Make the launcher more controllable via keyboard buttons

Selected button via tab now actually displays in active state, can use up/down to cycle through selected widget now too
This commit is contained in:
UnknownShadow200 2023-06-30 11:58:35 +10:00
parent 5c973cda53
commit 9b41a3312c
4 changed files with 49 additions and 34 deletions

View File

@ -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'];
}

View File

@ -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 } };

View File

@ -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) {

View File

@ -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 {