From 7c383eaea2b0fc2ac0723f4885ddfae7081da774 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Thu, 18 Aug 2011 21:46:44 +0000 Subject: Implementation zoom souris. Tentative 1 pas finie. git-svn-id: file:///var/svn/2011-ddhardrescue/trunk@23 d3078510-dda0-49f1-841c-895ef4b7ec81 --- src/cursesview.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/src/cursesview.c b/src/cursesview.c index ddd5a2f..0d46daf 100644 --- a/src/cursesview.c +++ b/src/cursesview.c @@ -13,7 +13,7 @@ extern int end; // window updated by cursesUpdateSliceDump callback from "worker" thread, with a mutex for prevent fuzzy concurrent updates WINDOW *winUpdateSliceDump=NULL; static pthread_mutex_t ncursesWriteMutex = PTHREAD_MUTEX_INITIALIZER; -address_t sliceDumpBegin, sliceDumpEnd; +address_t sliceDumpBegin, sliceDumpEnd, sliceDumpMin, sliceDumpMax; // Helpers declaration (below the interesting code of this file) int cursesInit(WINDOW *wins[], PANEL *panels[], int count); @@ -23,15 +23,23 @@ void print_in_middle(WINDOW *win, int starty, int startx, int width, char *strin void makeWin(WINDOW **win, PANEL **panel, int h, int w, int y, int x, char title[]); void cursesMainLoop(slices_evt_t *slicesEvt) { - WINDOW *wins[CURSESWIN_COUNT]; - PANEL *panels[CURSESWIN_COUNT]; char msgViewedArea[255]; int ch, i; + WINDOW *wins[CURSESWIN_COUNT]; + PANEL *panels[CURSESWIN_COUNT]; + +#ifdef NCURSES_MOUSE_VERSION + int dispatched, res; + int (*dispatchTo)(MEVENT mevent, WINDOW *winDebug); + MEVENT mevent; + PANEL *p; +#endif + cursesInit(wins, panels, CURSESWIN_COUNT); - sliceDumpBegin=slicesEvt->data->min; - sliceDumpEnd=slicesEvt->data->max; + sliceDumpBegin=sliceDumpMin=slicesEvt->data->min; + sliceDumpEnd=sliceDumpMax=slicesEvt->data->max; wattron(wins[CURSESWIN_COUNT-1], COLOR_PAIR(4)); mvwprintw(wins[CURSESWIN_COUNT-1], 1, 0, "F2:Exit F5:Zoom left F6:Unzoom left F7:Unzoom right F8:Zoom right"); @@ -55,10 +63,10 @@ void cursesMainLoop(slices_evt_t *slicesEvt) { sliceDumpEnd=(sliceDumpBegin+sliceDumpEnd)/2; break; case KEY_F(6): - sliceDumpBegin=slicesEvt->data->min; + sliceDumpBegin=sliceDumpMin; break; case KEY_F(7): - sliceDumpEnd=slicesEvt->data->max; + sliceDumpEnd=sliceDumpMax; break; case KEY_F(8): sliceDumpBegin=(sliceDumpBegin+sliceDumpEnd)/2; @@ -74,6 +82,35 @@ void cursesMainLoop(slices_evt_t *slicesEvt) { update_panels(); } break; +#ifdef NCURSES_MOUSE_VERSION + case KEY_MOUSE: + // Seems to have a mouse event + res = getmouse(&mevent); + if ( res == OK ) { + // Try to find in which panel (search first in top-level panel and go down) + p=NULL; + while ( ( p=panel_below(p) ) != NULL) { + if ( wenclose(panel_window(p), mevent.y, mevent.x) ) { + break; + } + } + + // If we found a panel, dispatch the event if a listener is set + if (p != NULL) { + dispatched=0; + dispatchTo=(int (*)(MEVENT mevent, WINDOW *winDebug)) panel_userptr(p); + + if (dispatchTo != NULL) dispatched=dispatchTo(mevent, wins[0]); + if ( ! dispatched ) { + // If no listener or event not consumed, use the default behavior : set the panel on top + if ( (mevent.bstate & BUTTON1_CLICKED) == BUTTON1_CLICKED) { + top_panel(p); + } + } + } + } + break; +#endif } doupdate(); @@ -93,8 +130,37 @@ void cursesMainLoop(slices_evt_t *slicesEvt) { cursesUnInit(wins, panels, CURSESWIN_COUNT); } +// TODO : faire une structure avec tous les éléments graphiques utiles au listener et tout passer par référence de la mainloop à ce listener +int winUpdateSliceDumpMouseEventListener(MEVENT mevent, WINDOW *winDebug) { + bool resb; + int pX, pY, maxX, maxY; + address_t delta; + float pos; + char buf[255]; + + pY=mevent.y; + pX=mevent.x; + resb=wmouse_trafo(winUpdateSliceDump, &pY, &pX, false); + if ( resb == TRUE ) { + getmaxyx(winUpdateSliceDump, maxY, maxX); + pos=(pY*maxX+pX)/(maxY*maxX); + delta=sliceDumpEnd-sliceDumpBegin; + sliceDumpBegin+=delta*pos/2; + sliceDumpEnd-=delta*(1-pos)/2; + } + + sprintf(buf, "Debug : pos==%f, sliceDumpEnd==%lli, sliceDumpBegin=%lli, delta==%lli", pos, sliceDumpEnd, sliceDumpBegin, delta); + wattron(winDebug, COLOR_PAIR(4)); + mvwprintw(winDebug, 2, 0, buf); + return 1; +} + int cursesInit(WINDOW *wins[], PANEL *panels[], int count) { int screenH, screenW; +#ifdef NCURSES_MOUSE_VERSION + char buf[255]; + mmask_t mmask; +#endif /* Initialize curses */ initscr(); @@ -102,6 +168,9 @@ int cursesInit(WINDOW *wins[], PANEL *panels[], int count) { raw(); keypad(stdscr, TRUE); noecho(); +#ifdef NCURSES_MOUSE_VERSION + mmask = mousemask(REPORT_MOUSE_POSITION|BUTTON1_CLICKED, NULL); +#endif /* Initialize all the colors */ init_pair(1, COLOR_WHITE, COLOR_BLACK); @@ -123,6 +192,13 @@ int cursesInit(WINDOW *wins[], PANEL *panels[], int count) { set_panel_userptr(panels[2], panels[0]); */ + set_panel_userptr(panels[1], winUpdateSliceDumpMouseEventListener); + +#ifdef NCURSES_MOUSE_VERSION + sprintf(buf, "Debug infos : mmask=%lx", mmask); + mvprintw(LINES - 3, 0, buf); +#endif + /* Update the stacking order. 2nd panel will be on top */ update_panels(); -- cgit v1.2.3