예제 #1
0
// Process an event
static void gwidgetEvent(void *param, GEvent *pe) {
	#define pme		((GEventMouse *)pe)
	#define pke		((GEventKeyboard *)pe)
	#define pte		((GEventToggle *)pe)
	#define pde		((GEventDial *)pe)

	GHandle				h;
	GHandle				gh;
	#if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL)
		uint16_t		role;
	#endif
	(void)				param;

	// Process various events
	switch (pe->type) {

	#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
	case GEVENT_MOUSE:
	case GEVENT_TOUCH:
		// Cycle through all windows
		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))
				continue;

			// Is the mouse currently captured by this widget?
			if ((h->flags & (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) == (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) {
				gh = h;
				if ((pme->buttons & GMETA_MOUSE_UP)) {
					gh->flags &= ~GWIN_FLG_MOUSECAPTURE;
					if (wvmt->MouseUp)
						wvmt->MouseUp(gw, pme->x - gh->x, pme->y - gh->y);
				} else if (wvmt->MouseMove)
					wvmt->MouseMove(gw, pme->x - gh->x, pme->y - gh->y);

				// There is only ever one captured mouse. Prevent normal mouse processing if there is a captured mouse
				gh = 0;
			
				break;
			}

			// Save the highest z-order window that the mouse is over
			if (pme->x >= h->x && pme->x < h->x + h->width && pme->y >= h->y && pme->y < h->y + h->height)
				gh = h;
		}

		// Process any mouse down over the highest order window if it is an enabled widget
		if (gh && (gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) == (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) {
			if ((pme->buttons & GMETA_MOUSE_DOWN)) {
				gh->flags |= GWIN_FLG_MOUSECAPTURE;

				#if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD
					// We should try and capture the focus on this window.
					// If we can't then we don't change the focus
					gwinSetFocus(gh);
				#endif

				if (wvmt->MouseDown)
					wvmt->MouseDown(gw, pme->x - gh->x, pme->y - gh->y);
			}
		}
		break;
	#endif

	#if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD
	case GEVENT_KEYBOARD:
		// If Tab key pressed then set focus to next widget
		if (pke->bytecount == 1 && pke->c[0] == GKEY_TAB) {
			if (!(pke->keystate & GKEYSTATE_KEYUP))
				_gwinMoveFocus();
			break;
		}

		// Otherwise, send keyboard events only to widget in focus
		if (_widgetInFocus)
			((gwidgetVMT*)_widgetInFocus->vmt)->KeyboardEvent((GWidgetObject*)_widgetInFocus, pke);
		break;
	#endif

	#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
	case GEVENT_TOGGLE:
		// Cycle through all windows
		for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {

			// check if it a widget that 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;

			for(role = 0; role < wvmt->toggleroles; role++) {
				if (wvmt->ToggleGet(gw, role) == pte->instance) {
					if (pte->on) {
						if (wvmt->ToggleOn)
							wvmt->ToggleOn(gw, role);
					} else {
						if (wvmt->ToggleOff)
							wvmt->ToggleOff(gw, role);
					}
				}
			}
		}
		break;
	#endif

	#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
	case GEVENT_DIAL:
		// Cycle through all windows
		for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {

			// check if it a widget that 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;

			for(role = 0; role < wvmt->dialroles; role++) {
				if (wvmt->DialGet(gw, role) == pte->instance) {
					if (wvmt->DialMove)
						wvmt->DialMove(gw, role, pde->value, pde->maxvalue);
				}
			}
		}
		break;
	#endif

	default:
		break;
	}

	#undef pme
	#undef pte
	#undef pke
	#undef pde
}
예제 #2
0
	static void TextEditKeyboard(GWidgetObject* gw, GEventKeyboard* pke) {
		// Only react on KEYDOWN events. Ignore KEYUP events.
		if ((pke->keystate & GKEYSTATE_KEYUP) || !pke->bytecount)
			return;

		// Is it a special key?
		if (pke->keystate & GKEYSTATE_SPECIAL) {

			// Arrow keys to move the cursor
			switch ((uint8_t)pke->c[0]) {
			case GKEY_LEFT:
				if (!gw2obj->cursorPos)
					return;
				gw2obj->cursorPos--;
				break;
			case GKEY_RIGHT:
				if (!gw->text[gw2obj->cursorPos])
					return;
				gw2obj->cursorPos++;
				break;
			case GKEY_HOME:
				if (!gw2obj->cursorPos)
					return;
				gw2obj->cursorPos = 0;
				break;
			case GKEY_END:
				if (!gw->text[gw2obj->cursorPos])
					return;
				gw2obj->cursorPos = strlen(gw->text);
				break;
			default:
				return;
			}

		} else {

			// Normal key press
			switch((uint8_t)pke->c[0]) {
			case GKEY_BACKSPACE:
				// Backspace
				if (!gw2obj->cursorPos)
					return;
				gw2obj->cursorPos--;
				resizeText(gw, gw2obj->cursorPos, -1);
				break;
			case GKEY_TAB:
			case GKEY_LF:
			case GKEY_CR:
				// Move to the next field
				_gwinMoveFocus();
				return;
			case GKEY_DEL:
				// Delete
				if (!gw->text[gw2obj->cursorPos])
					return;
				resizeText(gw, gw2obj->cursorPos, -1);
				break;
			default:
				// Ignore any other control characters
				if ((uint8_t)pke->c[0] < GKEY_SPACE)
					return;

				// Keep the edit length to less than the maximum
				if (gw2obj->maxSize && gw2obj->cursorPos+pke->bytecount > gw2obj->maxSize)
					return;

				// Make space
				resizeText(gw, gw2obj->cursorPos, pke->bytecount);

				// Insert the character
				memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount);
				gw2obj->cursorPos += pke->bytecount;
				break;
			}
		}

		_gwinUpdate((GHandle)gw);
	}