diff --git a/src/LBackend.c b/src/LBackend.c index c9887d025..8ed11c26b 100644 --- a/src/LBackend.c +++ b/src/LBackend.c @@ -401,17 +401,18 @@ void LBackend_ButtonUpdate(struct LButton* w) { void LBackend_ButtonDraw(struct LButton* w) { struct DrawTextArgs args; int xOffset, yOffset; + cc_bool active = w->hovered || w->selected; - LButton_DrawBackground(&framebuffer, w->x, w->y, w->width, w->height, w->hovered); + LButton_DrawBackground(&framebuffer, w->x, w->y, w->width, w->height, active); xOffset = w->width - w->_textWidth; yOffset = w->height - w->_textHeight; DrawTextArgs_Make(&args, &w->text, &titleFont, true); - if (!w->hovered) Drawer2D.Colors['f'] = Drawer2D.Colors['7']; + if (!active) Drawer2D.Colors['f'] = Drawer2D.Colors['7']; Context2D_DrawText(&framebuffer, &args, w->x + xOffset / 2, w->y + yOffset / 2); - if (!w->hovered) Drawer2D.Colors['f'] = Drawer2D.Colors['F']; + if (!active) Drawer2D.Colors['f'] = Drawer2D.Colors['F']; } diff --git a/src/LScreens.c b/src/LScreens.c index ac3cbe0b0..d69c9d093 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -59,9 +59,8 @@ void LScreen_UnselectWidget(struct LScreen* s, int idx, struct LWidget* w) { if (w->VTABLE->OnUnselect) w->VTABLE->OnUnselect(w, idx); } -static void LScreen_HandleTab(struct LScreen* s) { +static void LScreen_CycleSelected(struct LScreen* s, int dir) { struct LWidget* w; - int dir = Input_IsShiftPressed() ? -1 : 1; int index = 0, i, j; if (s->selectedWidget) { @@ -82,9 +81,7 @@ static void LScreen_HandleTab(struct LScreen* s) { } static void LScreen_KeyDown(struct LScreen* s, int key, cc_bool was) { - if (key == IPT_TAB) { - LScreen_HandleTab(s); - } else if (key == IPT_ENTER || key == IPT_KP_ENTER) { + if (key == IPT_ENTER || key == IPT_KP_ENTER) { /* Shouldn't multi click when holding down Enter */ if (was) return; @@ -95,9 +92,20 @@ static void LScreen_KeyDown(struct LScreen* s, int key, cc_bool was) { } else if (s->onEnterWidget) { s->onEnterWidget->OnClick(s->onEnterWidget); } - } else if (s->selectedWidget) { - if (!s->selectedWidget->VTABLE->KeyDown) return; - s->selectedWidget->VTABLE->KeyDown(s->selectedWidget, key, was); + return; + } + + /* Active widget takes input priority over default behaviour */ + if (s->selectedWidget && s->selectedWidget->VTABLE->KeyDown) { + if (s->selectedWidget->VTABLE->KeyDown(s->selectedWidget, key, was)) return; + } + + if (key == IPT_TAB) { + LScreen_CycleSelected(s, Input_IsShiftPressed() ? -1 : 1); + } else if (key == IPT_UP) { + LScreen_CycleSelected(s, -1); + } else if (key == IPT_DOWN) { + LScreen_CycleSelected(s, 1); } } @@ -1358,13 +1366,13 @@ static struct LWidget* settings_widgets[] = { (struct LWidget*)&SettingsScreen.btnMode, (struct LWidget*)&SettingsScreen.lblMode, (struct LWidget*)&SettingsScreen.btnColours, (struct LWidget*)&SettingsScreen.lblColours, (struct LWidget*)&SettingsScreen.cbExtra, (struct LWidget*)&SettingsScreen.cbEmpty, - (struct LWidget*)&SettingsScreen.btnBack, (struct LWidget*)&SettingsScreen.cbScale + (struct LWidget*)&SettingsScreen.cbScale, (struct LWidget*)&SettingsScreen.btnBack }; static struct LWidget* settings_classic[] = { (struct LWidget*)&SettingsScreen.sep, (struct LWidget*)&SettingsScreen.btnMode, (struct LWidget*)&SettingsScreen.lblMode, (struct LWidget*)&SettingsScreen.cbExtra, (struct LWidget*)&SettingsScreen.cbEmpty, - (struct LWidget*)&SettingsScreen.btnBack, (struct LWidget*)&SettingsScreen.cbScale + (struct LWidget*)&SettingsScreen.cbScale, (struct LWidget*)&SettingsScreen.btnBack }; LAYOUTS set_btnMode[] = { { ANCHOR_CENTRE, -135 }, { ANCHOR_CENTRE, -70 } }; diff --git a/src/LWidgets.c b/src/LWidgets.c index d4a8802ee..0c9a8176d 100644 --- a/src/LWidgets.c +++ b/src/LWidgets.c @@ -30,9 +30,9 @@ void LWidget_CalcOffsets(void) { /*########################################################################################################################* *------------------------------------------------------ButtonWidget-------------------------------------------------------* *#########################################################################################################################*/ -static void LButton_DrawBase(struct Context2D* ctx, int x, int y, int width, int height, cc_bool hovered) { - BitmapCol color = hovered ? Launcher_Theme.ButtonForeActiveColor - : Launcher_Theme.ButtonForeColor; +static void LButton_DrawBase(struct Context2D* ctx, int x, int y, int width, int height, cc_bool active) { + BitmapCol color = active ? Launcher_Theme.ButtonForeActiveColor + : Launcher_Theme.ButtonForeColor; if (Launcher_Theme.ClassicBackground) { Gradient_Noise(ctx, color, 8, @@ -67,12 +67,12 @@ static void LButton_DrawBorder(struct Context2D* ctx, int x, int y, int width, i oneX, height - twoY); } -static void LButton_DrawHighlight(struct Context2D* ctx, int x, int y, int width, int height, cc_bool hovered) { +static void LButton_DrawHighlight(struct Context2D* ctx, int x, int y, int width, int height, cc_bool active) { BitmapCol activeColor = BitmapColor_RGB(189, 198, 255); BitmapCol color = Launcher_Theme.ButtonHighlightColor; if (Launcher_Theme.ClassicBackground) { - if (hovered) color = activeColor; + if (active) color = activeColor; Context2D_Clear(ctx, color, x + twoX, y + oneY, @@ -80,17 +80,17 @@ static void LButton_DrawHighlight(struct Context2D* ctx, int x, int y, int width Context2D_Clear(ctx, color, x + oneX, y + twoY, oneX, height - fourY); - } else if (!hovered) { + } else if (!active) { Context2D_Clear(ctx, color, x + twoX, y + oneY, width - fourX, oneY); } } -void LButton_DrawBackground(struct Context2D* ctx, int x, int y, int width, int height, cc_bool hovered) { - LButton_DrawBase( ctx, x, y, width, height, hovered); +void LButton_DrawBackground(struct Context2D* ctx, int x, int y, int width, int height, cc_bool active) { + LButton_DrawBase( ctx, x, y, width, height, active); LButton_DrawBorder( ctx, x, y, width, height); - LButton_DrawHighlight(ctx, x, y, width, height, hovered); + LButton_DrawHighlight(ctx, x, y, width, height, active); } static void LButton_Draw(void* widget) { @@ -99,19 +99,19 @@ static void LButton_Draw(void* widget) { } static void LButton_Hover(void* w, int idx, cc_bool wasOver) { - /* only need to redraw when changing from unhovered to hovered */ + /* only need to redraw when changing from unhovered to active */ if (!wasOver) LBackend_MarkDirty(w); } -static void LButton_Unhover(void* w) { - LBackend_MarkDirty(w); -} +static void LButton_Unhover(void* w) { LBackend_MarkDirty(w); } +static void LButton_OnSelect(void* w, int idx, cc_bool wasSelected) { LBackend_MarkDirty(w); } +static void LButton_OnUnselect(void* w, int idx) { LBackend_MarkDirty(w); } static const struct LWidgetVTABLE lbutton_VTABLE = { LButton_Draw, NULL, - NULL, NULL, /* Key */ - LButton_Hover, LButton_Unhover, /* Hover */ - NULL, NULL /* Select */ + NULL, NULL, /* Key */ + LButton_Hover, LButton_Unhover, /* Hover */ + LButton_OnSelect, LButton_OnUnselect /* Select */ }; void LButton_Init(struct LButton* w, int width, int height, const char* text, const struct LLayout* layouts) { w->VTABLE = &lbutton_VTABLE; @@ -247,7 +247,7 @@ static void LInput_Delete(struct LInput* w) { LBackend_InputUpdate(w); } -static void LInput_KeyDown(void* widget, int key, cc_bool was) { +static cc_bool LInput_KeyDown(void* widget, int key, cc_bool was) { struct LInput* w = (struct LInput*)widget; if (key == IPT_BACKSPACE) { LInput_Backspace(w); @@ -263,7 +263,11 @@ static void LInput_KeyDown(void* widget, int key, cc_bool was) { LInput_AdvanceCaretPos(w, false); } else if (key == IPT_RIGHT) { LInput_AdvanceCaretPos(w, true); + } else { + return false; } + + return true; } static cc_bool LInput_CanAppend(struct LInput* w, char c) { @@ -564,7 +568,7 @@ cc_bool LTable_HandlesKey(int key) { return key == IPT_UP || key == IPT_DOWN || key == IPT_PAGEUP || key == IPT_PAGEDOWN; } -static void LTable_KeyDown(void* widget, int key, cc_bool was) { +static cc_bool LTable_KeyDown(void* widget, int key, cc_bool was) { struct LTable* w = (struct LTable*)widget; int index = LTable_GetSelectedIndex(w); @@ -576,10 +580,11 @@ static void LTable_KeyDown(void* widget, int key, cc_bool was) { index -= w->visibleRows; } else if (key == IPT_PAGEDOWN) { index += w->visibleRows; - } else { return; } + } else { return false; } w->_lastRow = -1; LTable_SetSelectedTo(w, index); + return true; } static void LTable_MouseDown(void* widget, int idx, cc_bool wasOver) { diff --git a/src/LWidgets.h b/src/LWidgets.h index 6830551ad..0a2ee7994 100644 --- a/src/LWidgets.h +++ b/src/LWidgets.h @@ -23,7 +23,8 @@ struct LWidgetVTABLE { /* Called repeatedly to update this widget when selected. */ void (*Tick)(void* widget); /* Called when key is pressed and this widget is selected. */ - void (*KeyDown)(void* widget, int key, cc_bool wasDown); + /* Returns whether the key press was intercepted */ + cc_bool (*KeyDown)(void* widget, int key, cc_bool wasDown); /* Called when key is pressed and this widget is selected. */ void (*KeyPress)(void* widget, char c); /* Called when mouse hovers/moves over this widget. */ @@ -70,7 +71,7 @@ struct LButton { }; CC_NOINLINE void LButton_Init(struct LButton* w, int width, int height, const char* text, const struct LLayout* layouts); CC_NOINLINE void LButton_SetConst(struct LButton* w, const char* text); -CC_NOINLINE void LButton_DrawBackground(struct Context2D* ctx, int x, int y, int width, int height, cc_bool hovered); +CC_NOINLINE void LButton_DrawBackground(struct Context2D* ctx, int x, int y, int width, int height, cc_bool active); struct LCheckbox; struct LCheckbox {