// A toggle on has occurred static void ToggleOn(GWidgetObject *gw, uint16_t role) { (void) role; gw->g.flags |= GBUTTON_FLG_PRESSED; _gwinUpdate((GHandle)gw); // Trigger the event on button down (different than for mouse/touch) _gwinSendEvent(&gw->g, GEVENT_GWIN_BUTTON); }
// A mouse up has occurred (it may or may not be over the button) static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) { (void) x; (void) y; gw->g.flags &= ~GBUTTON_FLG_PRESSED; _gwinUpdate((GHandle)gw); #if !GWIN_BUTTON_LAZY_RELEASE // If the mouse up was not over the button then cancel the event if (x < 0 || y < 0 || x >= gw->g.width || y >= gw->g.height) return; #endif _gwinSendEvent(&gw->g, GEVENT_GWIN_BUTTON); }
static void ButtonKeyboard(GWidgetObject* gw, GEventKeyboard* pke) { // ENTER and SPACE keys to press the button if (pke->c[0] == GKEY_ENTER || pke->c[0] == GKEY_SPACE) { // Some keyboards (eg the virtual keyboard) can't send keyup events. // Even for those that do we may not be listening for them. // We should really process on a keydown and then set a timer to display // the button release but that requires an extra timer and lots of // complication. Instead we cheat by not providing user feedback of the keypress. if (!(pke->keystate & GKEYSTATE_KEYUP)) _gwinSendEvent(&gw->g, GEVENT_GWIN_BUTTON); } }
static void FrameMouseUp(GWidgetObject *gw, coord_t x, coord_t y) { #if GWIN_BUTTON_LAZY_RELEASE if ((gw->g.flags & GWIN_FRAME_CLOSE_PRESSED)) { // Close is released - destroy the window gw->g.flags &= ~(GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED); forceFrameRedraw(gw); _gwinSendEvent(&gw->g, GEVENT_GWIN_CLOSE); _gwinDestroy(&gw->g, REDRAW_INSESSION); return; } if ((gw->g.flags & GWIN_FRAME_MAX_PRESSED)) { // Max is released - maximize the window gw->g.flags &= ~(GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED); forceFrameRedraw(gw); gwinSetMinMax(&gw->g, GWIN_MAXIMIZE); return; } if ((gw->g.flags & GWIN_FRAME_MIN_PRESSED)) { // Min is released - minimize the window gw->g.flags &= ~(GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED); forceFrameRedraw(gw); gwinSetMinMax(&gw->g, GWIN_MINIMIZE); return; } #else // If nothing is pressed we have nothing to do. if (!(gw->g.flags & (GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED))) return; // We must be releasing over the button if (y >= FRM_BUTTON_T && y < FRM_BUTTON_T+FRM_BUTTON_Y) { coord_t pos; pos = gw->g.width - (FRM_BORDER_R+FRM_BUTTON_X); if ((gw->g.flags & GWIN_FRAME_CLOSE_BTN)) { if ((gw->g.flags & GWIN_FRAME_CLOSE_PRESSED) && x >= pos && x <= pos+FRM_BUTTON_X) { // Close is released - destroy the window. This is tricky as we already have the drawing lock. gw->g.flags &= ~(GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED); forceFrameRedraw(gw); _gwinSendEvent(&gw->g, GEVENT_GWIN_CLOSE); _gwinDestroy(&gw->g, REDRAW_INSESSION); return; } pos -= FRM_BUTTON_X; } if ((gw->g.flags & GWIN_FRAME_MINMAX_BTN)) { if ((gw->g.flags & GWIN_FRAME_MAX_PRESSED) && x >= pos && x <= pos+FRM_BUTTON_X) { // Max is released - maximize the window gw->g.flags &= ~(GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED); forceFrameRedraw(gw); gwinSetMinMax(&gw->g, GWIN_MAXIMIZE); return; } pos -= FRM_BUTTON_X; if ((gw->g.flags & GWIN_FRAME_MIN_PRESSED) && x >= pos && x <= pos+FRM_BUTTON_X) { // Min is released - minimize the window gw->g.flags &= ~(GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED); forceFrameRedraw(gw); gwinSetMinMax(&gw->g, GWIN_MINIMIZE); return; } pos -= FRM_BUTTON_X; } } // Clear any flags and redraw the frame gw->g.flags &= ~(GWIN_FRAME_CLOSE_PRESSED|GWIN_FRAME_MAX_PRESSED|GWIN_FRAME_MIN_PRESSED); forceFrameRedraw(gw); #endif }