diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gwin/gwin_widget.c | 51 | 
1 files changed, 37 insertions, 14 deletions
diff --git a/src/gwin/gwin_widget.c b/src/gwin/gwin_widget.c index 6002ffa9..09cc91d8 100644 --- a/src/gwin/gwin_widget.c +++ b/src/gwin/gwin_widget.c @@ -18,10 +18,13 @@  #include "gwin_class.h" -/* Our listener for events for widgets */ -static GListener			gl; +// Our listener for events for widgets +static GListener gl; -/* Our default style - a white background theme */ +// The widget that is currently in focus. May be NULL. +static GHandle widgetInFocus; + +// Our default style - a white background theme  const GWidgetStyle WhiteWidgetStyle = {  	HTML2COLOR(0xFFFFFF),			// window background @@ -81,11 +84,11 @@ const GWidgetStyle BlackWidgetStyle = {  static const GWidgetStyle *	defaultStyle = &BlackWidgetStyle; -/* We use these everywhere in this file */ +// We use these everywhere in this file  #define gw		((GWidgetObject *)gh)  #define wvmt	((gwidgetVMT *)gh->vmt) -/* Process an event */ +// Process an event  static void gwidgetEvent(void *param, GEvent *pe) {  	#define pme		((GEventMouse *)pe)  	#define pke		((GEventKeyboard *)pe) @@ -106,7 +109,7 @@ static void gwidgetEvent(void *param, GEvent *pe) {  	case GEVENT_MOUSE:  	case GEVENT_TOUCH:  		// Cycle through all windows -		for(gh = 0, h = gwinGetNextWindow(0); h; h = gwinGetNextWindow(h)) { +		for (gh = 0, h = gwinGetNextWindow(0); h; h = gwinGetNextWindow(h)) {  			// The window must be on this display and visible to be relevant  			if (h->display != pme->display || !(h->flags & GWIN_FLG_SYSVISIBLE)) @@ -145,18 +148,36 @@ static void gwidgetEvent(void *param, GEvent *pe) {  	#if GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD  	case GEVENT_KEYBOARD: -		// Cycle through all windows -		for (gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) { +		// If Tab key pressed then set focus to next widget +		if (pke->bytecount == 1 && pke->c[0] == GKEY_TAB) { +			widgetInFocus = gwinGetNextWindow(widgetInFocus); +			// If it was the last widget begin with the first one again +			if (widgetInFocus == 0) { +				widgetInFocus = gwinGetNextWindow(0); +			} +			break; +		} -			// Check whether the widget is enabled and visible -			if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE)) { -				continue; +		// Otherise, send keyboard events only to widget in focus +		if (widgetInFocus != 0) { +			// Make sure that it is a widget +			if (!(widgetInFocus->flags & GWIN_FLG_WIDGET)) { +				break; +			} + +			// Make sure that the widget is enabled and visible +			if (!(widgetInFocus->flags & GWIN_FLG_SYSVISIBLE) || !(widgetInFocus->flags & GWIN_FLG_ENABLED)) { +				break;  			} -			// Pass the information -			wvmt->KeyboardEvent(gw, pke); +			// Check whether this widget provides a method for handling keyboard events +			if (((gwidgetVMT*)widgetInFocus->vmt)->KeyboardEvent == 0) { +				break; +			} + +			// If we got this far we can finally pass the event +			((gwidgetVMT*)widgetInFocus->vmt)->KeyboardEvent((GWidgetObject*)widgetInFocus, pke);  		} -		break;  	#endif  	#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE @@ -249,6 +270,8 @@ static void gwidgetEvent(void *param, GEvent *pe) {  void _gwidgetInit(void)  { +	widgetInFocus = 0; +  	geventListenerInit(&gl);  	geventRegisterCallback(&gl, gwidgetEvent, 0);  	geventAttachSource(&gl, ginputGetMouse(GMOUSE_ALL_INSTANCES), GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES);  | 
