From 6545abaf757adea641cb5d7a2bb0992dc965a342 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 29 Jul 2014 16:47:56 -0400 Subject: [PATCH] switched to tri-state flag for indicating the type of screen refresh required --- source/frame.c | 40 ++++++++++++++++++++++--------- source/frame.h | 4 ++++ source/input.c | 4 ++-- source/main.c | 38 +++++++----------------------- source/screen.c | 61 +++++++++++++++++++++++++++--------------------- source/state.c | 48 ++++++++++++++++--------------------- source/state.h | 28 +++++++++++++++------- source/workdir.c | 10 ++++---- 8 files changed, 123 insertions(+), 110 deletions(-) diff --git a/source/frame.c b/source/frame.c index 9b621f5..e60d0f8 100644 --- a/source/frame.c +++ b/source/frame.c @@ -47,6 +47,24 @@ static void frame_free(void* p_frame_ptr) { if(p_frame->workdir) mem_release(p_frame->workdir); } +void frame_resize(Frame_T* p_frame, int lines, int cols) +{ + wresize(p_frame->p_win, lines, cols); +} + +void frame_move(Frame_T* p_frame, int line, int col) +{ + mvwin(p_frame->p_win, line, col); +} + +void frame_draw(Frame_T* p_frame) +{ + wclear(p_frame->p_win); + frame_draw_files(p_frame); + box(p_frame->p_win, 0 , 0); + wrefresh(p_frame->p_win); +} + static int count_double_lines_to_idx(Frame_T* p_frame, bool inclusive){ int count = 0; int target = p_frame->workdir->idx + (inclusive ? 1 : 0); @@ -67,7 +85,7 @@ static bool frame_scroll(Frame_T* p_frame){ int doublelines = count_double_lines_to_idx(p_frame, true); 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); - changed = true; + changed = true; } } return changed; @@ -118,15 +136,15 @@ void frame_draw_files(Frame_T* frame){ void frame_set_highlighting(Frame_T* frame, bool highlight, bool refresh_win){ - if(frame){ - int line = FrameTopBuffer + count_double_lines_to_idx(frame, false) + 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 = (file && is_dir(file->path) ? DIRECTORY : 0); - mvwchgat(frame->p_win, line, 0, -1, newattr, color, NULL); - if(file && file->expanded) mvwchgat(frame->p_win, line+1, color, -1, newattr, 0, NULL); - if(frame_scroll(frame)) state_set_screen_dirty(true); - if(refresh_win) wrefresh(frame->p_win); - } + if(frame){ + int line = FrameTopBuffer + count_double_lines_to_idx(frame, false) + 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 = (file && is_dir(file->path) ? DIRECTORY : 0); + mvwchgat(frame->p_win, line, 0, -1, newattr, color, NULL); + if(file && file->expanded) mvwchgat(frame->p_win, line+1, color, -1, newattr, 0, NULL); + if(frame_scroll(frame)) state_set_refresh_state(REFRESH_CURR_WIN); + if(refresh_win) wrefresh(frame->p_win); + } } diff --git a/source/frame.h b/source/frame.h index 1ebbba6..a22ec95 100644 --- a/source/frame.h +++ b/source/frame.h @@ -16,6 +16,10 @@ enum ColorPairs { }; Frame_T* frame_new(void); +void frame_resize(Frame_T* p_frame, int lines, int cols); +void frame_move(Frame_T* p_frame, int line, int col); +void frame_draw(Frame_T* p_frame); + 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 diff --git a/source/input.c b/source/input.c index 89a129c..a57109d 100644 --- a/source/input.c +++ b/source/input.c @@ -18,7 +18,7 @@ typedef struct { static void handle_aardvark(void) { state_set_aardvark_mode(!state_get_aardvark_mode()); - state_set_screen_dirty(true); + state_set_refresh_state(REFRESH_ALL_WINS); } static void handle_quit(void) { @@ -85,7 +85,7 @@ static void search_mode(void){ searchstr[searchlen] = 0; workdir_seek(state_get_focused_workdir(), searchstr); } - if(state_get_screen_dirty()) screen_update(); + if(state_get_refresh_state() != REFRESH_COMPLETE) screen_update(); } free(searchstr); state_set_mode(MODE_NORMAL); diff --git a/source/main.c b/source/main.c index 18da209..e3429a1 100644 --- a/source/main.c +++ b/source/main.c @@ -1,25 +1,18 @@ -#include -#include -#include #include -#include -#include #include - #include "state.h" #include "input.h" #include "screen.h" void handle_signal(int sig) { - (void) sig; - state_set_screen_dirty(true); - state_set_screen_resized(true); + (void) sig; + state_set_refresh_state(REFRESH_ALL_WINS); } void handle_alarm(int sig) { - (void) sig; - state_set_screen_dirty(true); - alarm(1); + (void) sig; + state_set_refresh_state(REFRESH_CURR_WIN); + alarm(1); } int main() { @@ -27,29 +20,16 @@ int main() { signal(SIGWINCH, handle_signal); signal(SIGALRM, handle_alarm); /* Initialize ncurses and user input settings */ - initscr(); - start_color(); - init_pair(DIRECTORY, COLOR_BLUE, COLOR_BLACK); - init_pair(2, COLOR_MAGENTA, COLOR_BLACK); - init_pair(3, COLOR_RED, COLOR_BLACK); - init_pair(4, COLOR_YELLOW, COLOR_BLACK); - init_pair(5, COLOR_GREEN, COLOR_BLACK); - init_pair(6, COLOR_CYAN, COLOR_BLACK); - raw(); - keypad(stdscr, TRUE); - noecho(); - timeout(25); - refresh(); screen_init(); state_set_mode(MODE_NORMAL); + /* main loop */ while(state_get_running()) { - if(state_get_screen_dirty()) screen_update(); + if(state_get_refresh_state() != REFRESH_COMPLETE) + screen_update(); input_handle_key(getch()); } + /* tear down ncurses */ screen_deinit(); - clear(); - refresh(); - endwin(); return 0; } diff --git a/source/screen.c b/source/screen.c index c4e3c6e..6f8d69b 100644 --- a/source/screen.c +++ b/source/screen.c @@ -21,33 +21,51 @@ static void screen_refresh_curr_frame(void); static list_t* Frame_List; void screen_init(void) { + /* Initialize ncurses */ + initscr(); + start_color(); + init_pair(DIRECTORY, COLOR_BLUE, COLOR_BLACK); + init_pair(2, COLOR_MAGENTA, COLOR_BLACK); + init_pair(3, COLOR_RED, COLOR_BLACK); + init_pair(4, COLOR_YELLOW, COLOR_BLACK); + init_pair(5, COLOR_GREEN, COLOR_BLACK); + init_pair(6, COLOR_CYAN, COLOR_BLACK); + raw(); + keypad(stdscr, TRUE); + noecho(); + timeout(25); + refresh(); + /* Initialize the frame list */ Frame_List = list_new(); list_push_back(Frame_List, frame_new()); state_set_focused_node(Frame_List->head); } void screen_deinit(void) { + /* dump the frame list */ mem_release(Frame_List); + /* tear down ncurses */ + clear(); + refresh(); + endwin(); } void screen_update(void) { /* Clear screen and update LINES and COLS */ - if(state_get_screen_resized()){ + if(state_get_refresh_state() == REFRESH_ALL_WINS){ endwin(); screen_place_windows(); - state_set_screen_resized(false); } else { screen_refresh_curr_frame(); } if(state_get_aardvark_mode()) aardvark_draw(); /* Refresh and mark complete */ - state_set_screen_dirty(false); + state_set_refresh_state(REFRESH_COMPLETE); } void screen_open(void) { list_push_back(Frame_List, frame_new()); - state_set_screen_dirty(true); - state_set_screen_resized(true); + state_set_refresh_state(REFRESH_ALL_WINS); } /* TODO: add equiv. function to list */ @@ -71,8 +89,7 @@ void screen_close(void) { // new_focus will be null if rm-d tail: set it to new tail if(new_focus == NULL) new_focus = Frame_List->tail; state_set_focused_node(new_focus); - state_set_screen_dirty(true); - state_set_screen_resized(true); + state_set_refresh_state(REFRESH_ALL_WINS); mem_release(doomed_node); } } @@ -87,12 +104,9 @@ static void screen_place_windows(void) { /* Print the master frame */ p_frame = list_at(Frame_List,0)->contents; - mvwin(p_frame->p_win, 0, 0); - wresize(p_frame->p_win, lines, (num_frames > 1) ? cols/2 : cols); - wclear(p_frame->p_win); - frame_draw_files(p_frame); - box(p_frame->p_win, 0 , 0); - wrefresh(p_frame->p_win); + frame_move(p_frame, 0, 0); + frame_resize(p_frame, lines, (num_frames > 1) ? cols/2 : cols); + frame_draw(p_frame); /* Print any other frames we might have */ p_node = list_at(Frame_List,1); @@ -104,13 +118,9 @@ static void screen_place_windows(void) { int height = (lines / (num_frames-1)) + (id <= remain ? 1 : 0); p_frame = p_node->contents; /* Place the frame */ - mvwin(p_frame->p_win, pos, cols/2); - wresize(p_frame->p_win, height, cols/2); - wclear(p_frame->p_win); - frame_draw_files(p_frame); - wmove(p_frame->p_win, 1, 1); - box(p_frame->p_win, 0 , 0); - wrefresh(p_frame->p_win); + frame_move(p_frame, pos, cols/2); + frame_resize(p_frame, height, cols/2); + frame_draw(p_frame); /* Get the next one */ id++; pos += height; @@ -120,16 +130,13 @@ static void screen_place_windows(void) { static void screen_refresh_curr_frame(void) { Frame_T* p_frame = state_get_focused_frame(); - wclear(p_frame->p_win); - frame_draw_files(p_frame); - box(p_frame->p_win, 0 , 0); - wrefresh(p_frame->p_win); + frame_draw(p_frame); } void screen_focus_next(void){ list_node_t* focused = state_get_focused_node(); state_set_focused_node(focused->next ? focused->next : Frame_List->head); - state_set_screen_dirty(true); + state_set_refresh_state(REFRESH_CURR_WIN); } void screen_focus_prev(void){ @@ -137,12 +144,12 @@ void screen_focus_prev(void){ if(i >= 0){ list_node_t* prev = (i == 0) ? Frame_List->tail : list_at(Frame_List, i-1); if(prev) state_set_focused_node(prev); - state_set_screen_dirty(true); + state_set_refresh_state(REFRESH_CURR_WIN); } } void screen_focus_master(void){ state_set_focused_node(Frame_List->head); - state_set_screen_dirty(true); + state_set_refresh_state(REFRESH_CURR_WIN); } diff --git a/source/state.c b/source/state.c index 8fc9376..002a998 100644 --- a/source/state.c +++ b/source/state.c @@ -10,19 +10,17 @@ /** Whether the system is currently running or not. */ static bool Running = true; -/** Whether the screen should be refreshed or not. */ -static bool Screen_Dirty = true; - -/** Whether the terminal has been resized or not. */ -static bool Resized = true; - /** Whether the aardvark should be displayed */ static bool AardvarkOn = false; /** A pointer to the currently focused node */ static list_node_t* Focused_Node = NULL; -static Mode_T CurrentMode = 0; +/** Current refresh state */ +static RefreshState_T RefreshState = REFRESH_ALL_WINS; + +/** Current operational mode */ +static Mode_T CurrentMode = MODE_NORMAL; bool state_get_running(void) { return Running; @@ -32,28 +30,12 @@ void state_set_running(bool val) { Running = val; } -bool state_get_screen_dirty(void) { - return Screen_Dirty; -} - -void state_set_screen_dirty(bool val) { - Screen_Dirty = val; -} - -bool state_get_screen_resized(void) { - return Resized; -} - -void state_set_screen_resized(bool val) { - Resized = val; -} - bool state_get_aardvark_mode(void) { return AardvarkOn; } void state_set_aardvark_mode(bool val) { - alarm(val ? 1 : 0); + alarm(val ? 1 : 0); AardvarkOn = val; } @@ -71,15 +53,25 @@ WorkDir_T* state_get_focused_workdir(void) { } void state_set_focused_node(list_node_t *p_node) { - frame_set_highlighting(state_get_focused_frame(), false, true); + frame_set_highlighting(state_get_focused_frame(), false, true); Focused_Node = p_node; } -Mode_T state_get_mode() { +RefreshState_T state_get_refresh_state(void) +{ + return RefreshState; +} + +void state_set_refresh_state(RefreshState_T state) +{ + RefreshState = state; +} + +Mode_T state_get_mode(void) { return CurrentMode; } -void state_set_mode(Mode_T m) { - CurrentMode = m; +void state_set_mode(Mode_T mode) { + CurrentMode = mode; } diff --git a/source/state.h b/source/state.h index d97f4a5..97781ab 100644 --- a/source/state.h +++ b/source/state.h @@ -13,22 +13,34 @@ #include "frame.h" #include "workdir.h" - -typedef enum{ MODE_NORMAL, MODE_SEARCH } Mode_T; - bool state_get_running(void); void state_set_running(bool val); -bool state_get_screen_dirty(void); -void state_set_screen_dirty(bool val); -bool state_get_screen_resized(void); -void state_set_screen_resized(bool val); +//bool state_get_screen_dirty(void); +//void state_set_screen_dirty(bool val); +//bool state_get_screen_resized(void); +//void state_set_screen_resized(bool val); bool state_get_aardvark_mode(void); void state_set_aardvark_mode(bool val); void state_set_focused_node(list_node_t* p_node); list_node_t* state_get_focused_node(void); Frame_T* state_get_focused_frame(void); WorkDir_T* state_get_focused_workdir(void); + +typedef enum { + REFRESH_COMPLETE, + REFRESH_CURR_WIN, + REFRESH_ALL_WINS, +} RefreshState_T; + +RefreshState_T state_get_refresh_state(void); +void state_set_refresh_state(RefreshState_T state); + +typedef enum { + MODE_NORMAL, + MODE_SEARCH +} Mode_T; + Mode_T state_get_mode(void); -void state_set_mode(Mode_T); +void state_set_mode(Mode_T mode); #endif /* STATE_H */ diff --git a/source/workdir.c b/source/workdir.c index 1c918bb..c47b8a7 100644 --- a/source/workdir.c +++ b/source/workdir.c @@ -53,12 +53,12 @@ void file_free(void* p_vfile){ } void workdir_set_idx(WorkDir_T* wd, int idx){ - frame_set_highlighting(state_get_focused_frame(), false, false); + frame_set_highlighting(state_get_focused_frame(), false, false); wd->idx = idx; if(idx < 0) wd->idx = 0; else if((unsigned int)idx >= vec_size(wd->vfiles)) wd->idx = vec_size(wd->vfiles)-1; - frame_set_highlighting(state_get_focused_frame(), true, true); + frame_set_highlighting(state_get_focused_frame(), true, true); } void workdir_next(WorkDir_T* wd) { @@ -86,7 +86,7 @@ void workdir_cd(WorkDir_T* wd) { wd->idx = 0; } workdir_ls(wd); - state_set_screen_dirty(true); + state_set_refresh_state(REFRESH_CURR_WIN); } File_T* make_dotdot(char* path){ @@ -165,10 +165,10 @@ void workdir_seek(WorkDir_T* wd, char* search){ void workdir_expand_selected(WorkDir_T* wd){ ((File_T*)vec_at(wd->vfiles, wd->idx))->expanded = true; - state_set_screen_dirty(true); + state_set_refresh_state(REFRESH_CURR_WIN); } void workdir_collapse_selected(WorkDir_T* wd){ ((File_T*)vec_at(wd->vfiles, wd->idx))->expanded = false; - state_set_screen_dirty(true); + state_set_refresh_state(REFRESH_CURR_WIN); } -- 2.52.0