From 7c383eaea2b0fc2ac0723f4885ddfae7081da774 Mon Sep 17 00:00:00 2001
From: Ludovic Pouzenc <ludovic@pouzenc.fr>
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