mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 17:12:25 -05:00
Virtual keyboard: Support numpad layout too
This commit is contained in:
parent
2f11809354
commit
a10df262b1
8 changed files with 121 additions and 78 deletions
14
src/Input.c
14
src/Input.c
|
@ -310,13 +310,13 @@ void Input_Clear(void) {
|
|||
ClearTouches();
|
||||
}
|
||||
|
||||
int Input_CalcDelta(int key, int horDelta, int verDelta) {
|
||||
if (Input_IsLeftButton(key) || key == CCKEY_KP4) return -horDelta;
|
||||
if (Input_IsRightButton(key) || key == CCKEY_KP6) return +horDelta;
|
||||
if (Input_IsUpButton(key) || key == CCKEY_KP8) return -verDelta;
|
||||
if (Input_IsDownButton(key) || key == CCKEY_KP2) return +verDelta;
|
||||
|
||||
return 0;
|
||||
void Input_CalcDelta(int key, int* horDelta, int* verDelta) {
|
||||
*horDelta = 0; *verDelta = 0;
|
||||
|
||||
if (Input_IsLeftButton(key) || key == CCKEY_KP4) *horDelta = -1;
|
||||
if (Input_IsRightButton(key) || key == CCKEY_KP6) *horDelta = +1;
|
||||
if (Input_IsUpButton(key) || key == CCKEY_KP8) *verDelta = -1;
|
||||
if (Input_IsDownButton(key) || key == CCKEY_KP2) *verDelta = +1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ void Input_Clear(void);
|
|||
#else
|
||||
#define Input_IsActionPressed() Input_IsCtrlPressed()
|
||||
#endif
|
||||
int Input_CalcDelta(int btn, int horDelta, int verDelta);
|
||||
void Input_CalcDelta(int btn, int* horDelta, int* verDelta);
|
||||
|
||||
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
|
|
|
@ -372,12 +372,13 @@ static void ColoursScreen_AdjustSelected(struct LScreen* s, int delta) {
|
|||
}
|
||||
|
||||
static void ColoursScreen_KeyDown(struct LScreen* s, int key, cc_bool was) {
|
||||
int delta = Input_CalcDelta(key, 1, 10);
|
||||
if (key == CCWHEEL_UP) delta = +1;
|
||||
if (key == CCWHEEL_DOWN) delta = -1;
|
||||
int deltaX, deltaY;
|
||||
Input_CalcDelta(key, &deltaX, &deltaY);
|
||||
if (key == CCWHEEL_UP) deltaX = +1;
|
||||
if (key == CCWHEEL_DOWN) deltaX = -1;
|
||||
|
||||
if (delta) {
|
||||
ColoursScreen_AdjustSelected(s, delta);
|
||||
if (deltaX || deltaY) {
|
||||
ColoursScreen_AdjustSelected(s, deltaY * 10 + deltaX);
|
||||
} else {
|
||||
LScreen_KeyDown(s, key, was);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ const cc_result ReturnCode_SocketInProgess = EINPROGRESS;
|
|||
const cc_result ReturnCode_SocketWouldBlock = EWOULDBLOCK;
|
||||
const cc_result ReturnCode_DirectoryExists = EEXIST;
|
||||
const char* Platform_AppNameSuffix = " NDS";
|
||||
extern cc_bool keyboardOpen;
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
|
|
|
@ -12,22 +12,13 @@
|
|||
|
||||
static cc_bool kb_inited, kb_shift, kb_needsHook;
|
||||
static struct FontDesc kb_font;
|
||||
static int kb_selected;
|
||||
static const char** kb_table;
|
||||
static int kb_curX, kb_curY;
|
||||
static float kb_padXAcc, kb_padYAcc;
|
||||
static char kb_buffer[512];
|
||||
static cc_string kb_str = String_FromArray(kb_buffer);
|
||||
static void (*KB_MarkDirty)(void);
|
||||
|
||||
#define KB_CELLS_PER_ROW 13
|
||||
#define KB_LAST_CELL (KB_CELLS_PER_ROW - 1)
|
||||
#define KB_TOTAL_ROWS 5
|
||||
#define KB_LAST_ROW (KB_TOTAL_ROWS - 1)
|
||||
|
||||
#define KB_TOTAL_CHARS (KB_CELLS_PER_ROW * 4) + 4
|
||||
#define KB_TOTAL_SIZE KB_CELLS_PER_ROW * KB_TOTAL_ROWS
|
||||
|
||||
#define KB_TILE_SIZE 32
|
||||
#define KB_TILE_SIZE 32
|
||||
|
||||
#define KB_B_CAPS 0x10
|
||||
#define KB_B_SHIFT 0x20
|
||||
|
@ -36,34 +27,74 @@ static void (*KB_MarkDirty)(void);
|
|||
#define KB_B_BACK 0x50
|
||||
#define KB_B_ENTER 0x60
|
||||
|
||||
#define KB_GetBehaviour(i) (kb_table_behaviour[i] & 0xF0)
|
||||
#define KB_GetCellWidth(i) (kb_table_behaviour[i] & 0x0F)
|
||||
#define KB_GetBehaviour(i) (kb->behaviour[i] & 0xF0)
|
||||
#define KB_GetCellWidth(i) (kb->behaviour[i] & 0x0F)
|
||||
#define KB_IsInvisible(i) (kb->behaviour[i] == 0)
|
||||
|
||||
static const char* kb_table_lower[] =
|
||||
struct KBLayout {
|
||||
int numRows, cellsPerRow, rowWidth;
|
||||
const char** lower;
|
||||
const char** upper;
|
||||
const char** table;
|
||||
const cc_uint8* behaviour;
|
||||
};
|
||||
static struct KBLayout* kb;
|
||||
|
||||
|
||||
static const char* kb_normal_lower[] =
|
||||
{
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "Backspace",
|
||||
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "(", ")", "& ",
|
||||
"a", "s", "d", "f", "g", "h", "j", "k", "l", "?", ";", "'", "Enter",
|
||||
"z", "x", "c", "v", "b", "n", "m", ".", ",","\\", "!", "@", "/ ",
|
||||
"Caps", "Shift", "Space", "Close"
|
||||
"Caps",0,0,0, "Shift",0,0,0, "Space",0,0,0, "Close"
|
||||
};
|
||||
static const char* kb_table_upper[] =
|
||||
static const char* kb_normal_upper[] =
|
||||
{
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "_", "+", "Backspace",
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "& ",
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", "?", ":", "\"", "Enter",
|
||||
"Z", "X", "C", "V", "B", "N", "M", "<", ">", "*", "%", "#", "/ ",
|
||||
"Caps", "Shift", "Space", "Close"
|
||||
"Caps",0,0,0, "Shift",0,0,0, "Space",0,0,0, "Close"
|
||||
};
|
||||
static const cc_uint8 kb_table_behaviour[] =
|
||||
static const cc_uint8 kb_normal_behaviour[] =
|
||||
{
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, KB_B_BACK | 4,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, KB_B_ENTER | 4,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
|
||||
KB_B_CAPS | 4, KB_B_SHIFT | 4, KB_B_SPACE | 4, KB_B_CLOSE | 4
|
||||
KB_B_CAPS | 4,0,0,0, KB_B_SHIFT | 4,0,0,0, KB_B_SPACE | 4,0,0,0, KB_B_CLOSE | 4
|
||||
};
|
||||
|
||||
static struct KBLayout normal_layout = {
|
||||
5, 13, 16, // 12 normal cells, 1 four wide cell
|
||||
kb_normal_lower, kb_normal_upper, kb_normal_lower,
|
||||
kb_normal_behaviour
|
||||
};
|
||||
|
||||
|
||||
static const char* kb_numpad[] =
|
||||
{
|
||||
"1", "2", "3", "Backspace",
|
||||
"4", "5", "6", "Enter",
|
||||
"7", "8", "9", "Space",
|
||||
"-", "0", ".", "Close",
|
||||
};
|
||||
static const cc_uint8 kb_numpad_behaviour[] =
|
||||
{
|
||||
1, 1, 1, KB_B_BACK | 4,
|
||||
1, 1, 1, KB_B_ENTER | 4,
|
||||
1, 1, 1, KB_B_SPACE | 4,
|
||||
1, 1, 1, KB_B_CLOSE | 4
|
||||
};
|
||||
|
||||
static struct KBLayout numpad_layout = {
|
||||
4, 4, 7, // 3 normal cells, 1 four wide cell
|
||||
kb_numpad, kb_numpad, kb_numpad,
|
||||
kb_numpad_behaviour
|
||||
};
|
||||
|
||||
|
||||
extern void LWidget_DrawBorder(struct Context2D* ctx, BitmapCol color, int borderX, int borderY,
|
||||
int x, int y, int width, int height);
|
||||
|
||||
|
@ -74,22 +105,23 @@ static void VirtualKeyboard_Init(void) {
|
|||
}
|
||||
|
||||
static int VirtualKeyboard_Width(void) {
|
||||
return (KB_CELLS_PER_ROW + 3) * KB_TILE_SIZE;
|
||||
return kb->rowWidth * KB_TILE_SIZE;
|
||||
}
|
||||
|
||||
static int VirtualKeyboard_Height(void) {
|
||||
return KB_TOTAL_ROWS * KB_TILE_SIZE;
|
||||
return kb->numRows * KB_TILE_SIZE;
|
||||
}
|
||||
|
||||
static int VirtualKeyboard_GetSelected(void) {
|
||||
// Last row needs special handling since it uses 4 cells per item
|
||||
int selected = kb_selected;
|
||||
if (selected < 0) return -1;
|
||||
if (kb_curX < 0) return -1;
|
||||
int maxCells = kb->cellsPerRow * kb->numRows;
|
||||
|
||||
int idx = kb_curX + kb->cellsPerRow * kb_curY;
|
||||
Math_Clamp(idx, 0, maxCells - 1);
|
||||
|
||||
int row = selected / KB_CELLS_PER_ROW;
|
||||
int cell = selected % KB_CELLS_PER_ROW;
|
||||
if (row != KB_LAST_ROW) return selected;
|
||||
cell /= 4;
|
||||
return row * KB_CELLS_PER_ROW + cell;
|
||||
// Skip over invisible cells
|
||||
while (KB_IsInvisible(idx)) idx--;
|
||||
return idx;
|
||||
}
|
||||
|
||||
static void VirtualKeyboard_Close(void);
|
||||
|
@ -104,20 +136,19 @@ static void VirtualKeyboard_Draw(struct Context2D* ctx) {
|
|||
struct DrawTextArgs args;
|
||||
cc_string str;
|
||||
int row, cell;
|
||||
int i, x, y, w, h, dx, dy;
|
||||
int i = 0, x, y, w, h, dx, dy;
|
||||
int selected = VirtualKeyboard_GetSelected();
|
||||
|
||||
Drawer2D.Colors['f'] = Drawer2D.Colors['0'];
|
||||
if (kb_needsHook) VirtualKeyboard_Hook();
|
||||
|
||||
for (row = 0, y = 0; row < KB_TOTAL_ROWS; row++)
|
||||
for (row = 0, y = 0; row < kb->numRows; row++)
|
||||
{
|
||||
for (cell = 0, x = 0; cell < KB_CELLS_PER_ROW; cell++)
|
||||
for (cell = 0, x = 0; cell < kb->cellsPerRow; cell++, i++)
|
||||
{
|
||||
i = row * KB_CELLS_PER_ROW + cell;
|
||||
if (i >= KB_TOTAL_CHARS) break;
|
||||
if (KB_IsInvisible(i)) continue;
|
||||
|
||||
str = String_FromReadonly(kb_table[i]);
|
||||
str = String_FromReadonly(kb->table[i]);
|
||||
DrawTextArgs_Make(&args, &str, &kb_font, false);
|
||||
w = KB_TILE_SIZE * KB_GetCellWidth(i);
|
||||
h = KB_TILE_SIZE;
|
||||
|
@ -136,6 +167,7 @@ static void VirtualKeyboard_Draw(struct Context2D* ctx) {
|
|||
|
||||
Drawer2D.Colors['f'] = Drawer2D.Colors['F'];
|
||||
}
|
||||
|
||||
static void VirtualKeyboard_CalcPosition(int* x, int* y, int width, int height) {
|
||||
/* Draw virtual keyboard at centre of window bottom */
|
||||
*y = height - 1 - VirtualKeyboard_Height();
|
||||
|
@ -148,19 +180,23 @@ static void VirtualKeyboard_CalcPosition(int* x, int* y, int width, int height)
|
|||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Input handling------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void VirtualKeyboard_Scroll(int delta) {
|
||||
if (kb_selected < 0) kb_selected = 0;
|
||||
static void VirtualKeyboard_Scroll(int xDelta, int yDelta) {
|
||||
int perRow = kb->cellsPerRow, numRows = kb->numRows;
|
||||
if (kb_curX < 0) kb_curX = 0;
|
||||
|
||||
kb_selected += delta;
|
||||
if (kb_selected < 0) kb_selected += KB_TOTAL_SIZE;
|
||||
if (kb_selected >= KB_TOTAL_SIZE) kb_selected -= KB_TOTAL_SIZE;
|
||||
kb_curX += xDelta;
|
||||
if (kb_curX < 0) kb_curX += perRow;
|
||||
if (kb_curX >= perRow) kb_curX -= perRow;
|
||||
|
||||
kb_curY += yDelta;
|
||||
if (kb_curY < 0) kb_curY += numRows;
|
||||
if (kb_curY >= numRows) kb_curY -= numRows;
|
||||
|
||||
Math_Clamp(kb_selected, 0, KB_TOTAL_SIZE - 1);
|
||||
KB_MarkDirty();
|
||||
}
|
||||
|
||||
static void VirtualKeyboard_ToggleTable(void) {
|
||||
kb_table = kb_table == kb_table_lower ? kb_table_upper : kb_table_lower;
|
||||
kb->table = kb->table == kb->lower ? kb->upper : kb->lower;
|
||||
KB_MarkDirty();
|
||||
}
|
||||
|
||||
|
@ -180,11 +216,8 @@ static void VirtualKeyboard_Backspace(void) {
|
|||
static void VirtualKeyboard_ClickSelected(void) {
|
||||
int selected = VirtualKeyboard_GetSelected();
|
||||
if (selected < 0) return;
|
||||
int behaviour = KB_GetBehaviour(selected);
|
||||
int B = kb_table_behaviour[selected];
|
||||
Platform_Log2("%i, %i", &B, &behaviour);
|
||||
|
||||
switch (behaviour) {
|
||||
switch (KB_GetBehaviour(selected)) {
|
||||
case KB_B_BACK:
|
||||
VirtualKeyboard_Backspace();
|
||||
break;
|
||||
|
@ -209,15 +242,17 @@ static void VirtualKeyboard_ClickSelected(void) {
|
|||
break;
|
||||
|
||||
default:
|
||||
VirtualKeyboard_AppendChar(kb_table[selected][0]);
|
||||
VirtualKeyboard_AppendChar(kb->table[selected][0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void VirtualKeyboard_ProcessDown(void* obj, int key, cc_bool was) {
|
||||
int delta = Input_CalcDelta(key, 1, KB_CELLS_PER_ROW);
|
||||
if (delta) {
|
||||
VirtualKeyboard_Scroll(delta);
|
||||
int deltaX, deltaY;
|
||||
Input_CalcDelta(key, &deltaX, &deltaY);
|
||||
|
||||
if (deltaX || deltaY) {
|
||||
VirtualKeyboard_Scroll(deltaX, deltaY);
|
||||
} else if (key == CCPAD_START || key == CCPAD_A) {
|
||||
VirtualKeyboard_ClickSelected();
|
||||
} else if (key == CCPAD_SELECT || key == CCPAD_B) {
|
||||
|
@ -237,10 +272,10 @@ static void VirtualKeyboard_PadAxis(void* obj, int port, int axis, float x, floa
|
|||
int xSteps, ySteps;
|
||||
|
||||
xSteps = Utils_AccumulateWheelDelta(&kb_padXAcc, x / 100.0f);
|
||||
if (xSteps) VirtualKeyboard_Scroll(xSteps > 0 ? 1 : -1);
|
||||
if (xSteps) VirtualKeyboard_Scroll(xSteps > 0 ? 1 : -1, 0);
|
||||
|
||||
ySteps = Utils_AccumulateWheelDelta(&kb_padYAcc, y / 100.0f);
|
||||
if (ySteps) VirtualKeyboard_Scroll(ySteps > 0 ? KB_CELLS_PER_ROW : -KB_CELLS_PER_ROW);
|
||||
if (ySteps) VirtualKeyboard_Scroll(0, ySteps > 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,12 +381,16 @@ static void VirtualKeyboard_Open(struct OpenKeyboardArgs* args, cc_bool launcher
|
|||
DisplayInfo.ShowingSoftKeyboard = true;
|
||||
|
||||
kb_needsHook = true;
|
||||
kb_table = kb_table_lower;
|
||||
kb_selected = -1;
|
||||
kb_curX = -1;
|
||||
kb_curY = 0;
|
||||
kb_padXAcc = 0;
|
||||
kb_padYAcc = 0;
|
||||
kb_shift = false;
|
||||
|
||||
int mode = args->type & 0xFF;
|
||||
int num = mode == KEYBOARD_TYPE_INTEGER || mode == KEYBOARD_TYPE_NUMBER;
|
||||
kb = num ? &numpad_layout : &normal_layout;
|
||||
|
||||
kb_str.length = 0;
|
||||
String_AppendString(&kb_str, args->text);
|
||||
|
||||
|
|
|
@ -964,12 +964,12 @@ static int TableWidget_PointerMove(void* widget, int id, int x, int y) {
|
|||
|
||||
static int TableWidget_KeyDown(void* widget, int key) {
|
||||
struct TableWidget* w = (struct TableWidget*)widget;
|
||||
int delta;
|
||||
int deltaX, deltaY;
|
||||
if (w->selectedIndex == -1) return false;
|
||||
|
||||
delta = Input_CalcDelta(key, 1, w->blocksPerRow);
|
||||
if (delta) {
|
||||
TableWidget_ScrollRelative(w, delta);
|
||||
Input_CalcDelta(key, &deltaX, &deltaY);
|
||||
if (deltaX || deltaY) {
|
||||
TableWidget_ScrollRelative(w, deltaX + deltaY * w->blocksPerRow);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -260,6 +260,7 @@ void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
|
|||
} else if (mode == KEYBOARD_TYPE_NUMBER) {
|
||||
swkbdSetNumpadKeys(&swkbd, '-', '.');
|
||||
}
|
||||
DisplayInfo.ShowingSoftKeyboard = true;
|
||||
|
||||
if (mode == KEYBOARD_TYPE_PASSWORD)
|
||||
swkbdSetPasswordMode(&swkbd, SWKBD_PASSWORD_HIDE_DELAY);
|
||||
|
@ -274,7 +275,11 @@ void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
|
|||
void OnscreenKeyboard_SetText(const cc_string* text) { }
|
||||
void OnscreenKeyboard_Draw2D(Rect2D* r, struct Bitmap* bmp) { }
|
||||
void OnscreenKeyboard_Draw3D(void) { }
|
||||
void OnscreenKeyboard_Close(void) { /* TODO implement */ }
|
||||
|
||||
void OnscreenKeyboard_Close(void) {
|
||||
DisplayInfo.ShowingSoftKeyboard = false;
|
||||
/* TODO implement */
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
|
|
|
@ -126,7 +126,6 @@ static void consoleInit(void) {
|
|||
*------------------------------------------------------General data-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static cc_bool launcherMode;
|
||||
cc_bool keyboardOpen;
|
||||
static int bg_id;
|
||||
static u16* bg_ptr;
|
||||
|
||||
|
@ -211,7 +210,7 @@ static void ProcessTouchInput(int mods) {
|
|||
void Window_ProcessEvents(float delta) {
|
||||
scanKeys();
|
||||
|
||||
if (keyboardOpen) {
|
||||
if (DisplayInfo.ShowingSoftKeyboard) {
|
||||
keyboardUpdate();
|
||||
} else {
|
||||
ProcessTouchInput(keysDown() | keysHeld());
|
||||
|
@ -317,7 +316,7 @@ void OnscreenKeyboard_Open(struct OpenKeyboardArgs* args) {
|
|||
kbd->OnKeyPressed = OnKeyPressed;
|
||||
String_InitArray(kbText, kbBuffer);
|
||||
String_AppendString(&kbText, args->text);
|
||||
keyboardOpen = true;
|
||||
DisplayInfo.ShowingSoftKeyboard = true;
|
||||
}
|
||||
|
||||
void OnscreenKeyboard_SetText(const cc_string* text) { }
|
||||
|
@ -327,8 +326,8 @@ void OnscreenKeyboard_Draw3D(void) { }
|
|||
|
||||
void OnscreenKeyboard_Close(void) {
|
||||
keyboardHide();
|
||||
if (!keyboardOpen) return;
|
||||
keyboardOpen = false;
|
||||
if (!DisplayInfo.ShowingSoftKeyboard) return;
|
||||
DisplayInfo.ShowingSoftKeyboard = false;
|
||||
|
||||
videoBgEnableSub(0); // show console
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue