From 08d675bf0a1f3765077c410fee3efebf8b8637e7 Mon Sep 17 00:00:00 2001 From: a bellenir Date: Mon, 28 Jul 2014 07:09:43 +0000 Subject: [PATCH] yea, those files are important, and shouldve been added ages ago --- source/frame.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++ source/frame.h | 25 ++++++++++ 2 files changed, 152 insertions(+) create mode 100644 source/frame.c create mode 100644 source/frame.h diff --git a/source/frame.c b/source/frame.c new file mode 100644 index 0000000..17f6611 --- /dev/null +++ b/source/frame.c @@ -0,0 +1,127 @@ +/* external libraries */ +#include +#include +#include + +/* internal libraries */ +#include "mem.h" +#include "vec.h" + +/* internal headers */ +#include "frame.h" +#include "workdir.h" +#include "state.h" + +static int FrameTopBuffer = 2; +static int FrameBotBuffer = 2; + +static void frame_free(void* p_frame); + +//get the curent directory and copy it into a ref-counted memory block +//return a pointer to the new block +char* pwd(){ + char* dir = getcwd(NULL, 0); + char* rid = mem_allocate(sizeof(char)*(1+strlen(dir)), NULL); + strcpy(rid, dir); + free(dir); + return rid; +} + +Frame_T* frame_new(void) { + Frame_T* p_frame = (Frame_T*)mem_allocate(sizeof(Frame_T),&frame_free); + p_frame->p_win = newwin(1, 1, 0, 0); + p_frame->top_index = 0; + bool first_window = !state_get_focused_frame(); + char* path = first_window ? pwd() : state_get_focused_workdir()->path; + p_frame->workdir = workdir_new(path); + if(first_window) mem_release(path); + return p_frame; +} + +static void frame_free(void* p_frame_ptr) { + Frame_T* p_frame = (Frame_T*)p_frame_ptr; + wclear(p_frame->p_win); + wborder(p_frame->p_win, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); + wrefresh(p_frame->p_win); + delwin(p_frame->p_win); + if(p_frame->workdir) mem_release(p_frame->workdir); +} + +static int count_double_lines(Frame_T* p_frame){ + int count = 0; + for(int i = p_frame->top_index; i <= p_frame->workdir->idx; i++) + if (((File_T*)vec_at(p_frame->workdir->vfiles, i))->expanded) count++; + return count; +} + +static void frame_scroll(Frame_T* p_frame){ + int rows,cols; + getmaxyx(p_frame->p_win, rows, cols); + (void) cols; + if(p_frame->workdir->idx < p_frame->top_index){ + p_frame->top_index = p_frame->workdir->idx; + }else{ + int doublelines = count_double_lines(p_frame); + if (p_frame->top_index < doublelines+p_frame->workdir->idx-(rows-FrameTopBuffer-FrameBotBuffer)) + p_frame->top_index = doublelines+p_frame->workdir->idx-(rows-FrameTopBuffer-FrameBotBuffer); + } +} + +int realrows(Frame_T* p_frame){ + int rows, cols; + getmaxyx(p_frame->p_win, rows, cols); + (void) cols; + return rows - FrameTopBuffer - FrameBotBuffer; +} + +void frame_page_up(Frame_T* p_frame){ + workdir_set_idx(p_frame->workdir, p_frame->workdir->idx - realrows(p_frame)); +} + +void frame_page_down(Frame_T* p_frame){ + workdir_set_idx(p_frame->workdir, p_frame->workdir->idx+realrows(p_frame)); +} + +void frame_draw_files(Frame_T* frame){ + int file_i, frame_i = FrameTopBuffer; + int rows, cols; + getmaxyx(frame->p_win, rows, cols); + frame_scroll(frame); + file_i = frame->top_index; + //draw path + wattron(frame->p_win, A_UNDERLINE); + mvwaddnstr(frame->p_win, 1, 1, frame->workdir->path, cols-2); + wattroff(frame->p_win, A_UNDERLINE); + //list files + while (file_i < vec_size(frame->workdir->vfiles)){ + File_T* file = (File_T*)vec_at(frame->workdir->vfiles, file_i); + bool dir = is_dir(file->path); + if(frame == state_get_focused_frame() && file_i == frame->workdir->idx){ + wattron(frame->p_win, A_STANDOUT | A_BOLD); + } + if(dir) wattron(frame->p_win, COLOR_PAIR(DIRECTORY)); + mvwaddnstr(frame->p_win, frame_i, 1, file->name, cols-2); + frame_i++; + if(file->expanded){ + mvwprintw(frame->p_win, frame_i, 1, " owned by user id %d, group id %d", file->uid, file->gid); + frame_i++; + } + wstandend(frame->p_win); + file_i++; + if((frame_i+FrameBotBuffer) > rows) break; + } +} + + +void frame_set_highlighting(Frame_T* frame, bool highlight, bool refresh_win){ + if(frame){ + int line = FrameTopBuffer + frame->workdir->idx - frame->top_index; + attr_t newattr= highlight ? (A_STANDOUT|A_BOLD) : A_NORMAL; + File_T* file = (File_T*) vec_at(frame->workdir->vfiles, frame->workdir->idx); + short color = (is_dir(file->path) ? DIRECTORY : 0); + mvwchgat(frame->p_win, line, 0, -1, newattr, color, NULL); + if(file->expanded) mvwchgat(frame->p_win, line+1, color, -1, newattr, 0, NULL); + if(refresh_win) wrefresh(frame->p_win); + } +} + diff --git a/source/frame.h b/source/frame.h new file mode 100644 index 0000000..1ebbba6 --- /dev/null +++ b/source/frame.h @@ -0,0 +1,25 @@ +#ifndef FRAME_H +#define FRAME_H + +#include +#include "workdir.h" + +typedef struct { + WINDOW* p_win; + WorkDir_T* workdir; + int top_index; +} Frame_T; + + +enum ColorPairs { + DIRECTORY = 1 +}; + +Frame_T* frame_new(void); +void frame_page_up(Frame_T* p_frame); +void frame_page_down(Frame_T* p_frame); +void frame_draw_files(Frame_T* frame); //TODO: name pointers consistently +void frame_set_highlighting(Frame_T* frame, bool highlight, bool refresh_win); + +#endif /* FRAME_H */ + -- 2.52.0