// 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 }
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); }