Add GWIN virtual keyboard widget
This commit is contained in:
parent
b04148ca2b
commit
1ce3f20fa4
3
demos/modules/gwin/keyboard/demo.mk
Normal file
3
demos/modules/gwin/keyboard/demo.mk
Normal file
@ -0,0 +1,3 @@
|
||||
DEMODIR = $(GFXLIB)/demos/modules/gwin/keyboard
|
||||
GFXINC += $(DEMODIR)
|
||||
GFXSRC += $(DEMODIR)/main.c
|
55
demos/modules/gwin/keyboard/gfxconf.h
Normal file
55
demos/modules/gwin/keyboard/gfxconf.h
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* This file has a different license to the rest of the uGFX system.
|
||||
* You can copy, modify and distribute this file as you see fit.
|
||||
* You do not need to publish your source modifications to this file.
|
||||
* The only thing you are not permitted to do is to relicense it
|
||||
* under a different license.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copy this file into your project directory and rename it as gfxconf.h
|
||||
* Edit your copy to turn on the uGFX features you want to use.
|
||||
* The values below are the defaults. You should delete anything
|
||||
* you are leaving as default.
|
||||
*
|
||||
* Please use spaces instead of tabs in this file.
|
||||
*/
|
||||
|
||||
#ifndef _GFXCONF_H
|
||||
#define _GFXCONF_H
|
||||
|
||||
/* The operating system to use. One of these must be defined - preferably in your Makefile */
|
||||
//#define GFX_USE_OS_CHIBIOS TRUE
|
||||
//#define GFX_USE_OS_WIN32 TRUE
|
||||
//#define GFX_USE_OS_LINUX TRUE
|
||||
//#define GFX_USE_OS_OSX TRUE
|
||||
|
||||
#define GFX_USE_GDISP TRUE
|
||||
|
||||
#define GDISP_NEED_VALIDATION TRUE
|
||||
#define GDISP_NEED_CLIP TRUE
|
||||
//#define GDISP_NEED_SCROLL TRUE
|
||||
#define GDISP_NEED_TEXT TRUE
|
||||
#define GDISP_INCLUDE_FONT_UI2 TRUE
|
||||
|
||||
//#define GDISP_NEED_CONTROL TRUE
|
||||
//#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE
|
||||
#define GDISP_NEED_MULTITHREAD TRUE
|
||||
|
||||
#define GFX_USE_GWIN TRUE
|
||||
#define GWIN_NEED_WINDOWMANAGER TRUE
|
||||
#define GWIN_NEED_CONSOLE TRUE
|
||||
#define GWIN_NEED_WIDGET TRUE
|
||||
#define GWIN_NEED_KEYBOARD TRUE
|
||||
|
||||
#define GFX_USE_GEVENT TRUE
|
||||
#define GFX_USE_GTIMER TRUE
|
||||
|
||||
#define GFX_USE_GQUEUE TRUE
|
||||
#define GQUEUE_NEED_ASYNC TRUE
|
||||
|
||||
#define GFX_USE_GINPUT TRUE
|
||||
#define GINPUT_NEED_MOUSE TRUE
|
||||
//#define GINPUT_NEED_KEYBOARD TRUE
|
||||
|
||||
#endif /* _GFXCONF_H */
|
140
demos/modules/gwin/keyboard/main.c
Normal file
140
demos/modules/gwin/keyboard/main.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "gfx.h"
|
||||
|
||||
/* The variables we need */
|
||||
static font_t font;
|
||||
static GListener gl;
|
||||
static GHandle ghConsole;
|
||||
static GHandle ghKeyboard;
|
||||
|
||||
|
||||
/**
|
||||
* Create the widgets.
|
||||
*/
|
||||
static void createWidgets(void) {
|
||||
GWidgetInit wi;
|
||||
|
||||
gwinWidgetClearInit(&wi);
|
||||
|
||||
// Create the console - set colors before making it visible
|
||||
wi.g.show = FALSE;
|
||||
wi.g.x = 0; wi.g.y = 0;
|
||||
wi.g.width = gdispGetWidth(); wi.g.height = gdispGetHeight()/2;
|
||||
ghConsole = gwinConsoleCreate(0, &wi.g);
|
||||
gwinSetColor(ghConsole, Black);
|
||||
gwinSetBgColor(ghConsole, HTML2COLOR(0xF0F0F0));
|
||||
gwinShow(ghConsole);
|
||||
gwinClear(ghConsole);
|
||||
|
||||
// Create the keyboard
|
||||
wi.g.show = TRUE;
|
||||
wi.g.x = 0; wi.g.y = gdispGetHeight()/2;
|
||||
wi.g.width = gdispGetWidth(); wi.g.height = gdispGetHeight()/2;
|
||||
ghKeyboard = gwinKeyboardCreate(0, &wi);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
GEvent * pe;
|
||||
GEventKeyboard * pk;
|
||||
unsigned i;
|
||||
|
||||
// Initialize the display
|
||||
gfxInit();
|
||||
|
||||
// Set the widget defaults
|
||||
font = gdispOpenFont("*"); // Get the first defined font.
|
||||
gwinSetDefaultFont(font);
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(White);
|
||||
|
||||
// Create the gwin windows/widgets
|
||||
createWidgets();
|
||||
|
||||
// We want to listen for widget events
|
||||
geventListenerInit(&gl);
|
||||
gwinAttachListener(&gl);
|
||||
|
||||
// We also want to listen to keyboard events from the virtual keyboard
|
||||
geventAttachSource(&gl, gwinKeyboardGetEventSource(ghKeyboard), GLISTEN_KEYTRANSITIONS|GLISTEN_KEYUP);
|
||||
|
||||
while(1) {
|
||||
// Get an Event
|
||||
pe = geventEventWait(&gl, TIME_INFINITE);
|
||||
|
||||
switch(pe->type) {
|
||||
case GEVENT_GWIN_KEYBOARD:
|
||||
// This is a widget event generated on the standard gwin event source
|
||||
gwinPrintf(ghConsole, "Keyboard visibility has changed\n");
|
||||
break;
|
||||
|
||||
case GEVENT_KEYBOARD:
|
||||
// This is a keyboard event from a keyboard source which must be separately listened to.
|
||||
// It is not sent on the gwin event source even though in this case it was generated by a gwin widget.
|
||||
pk = (GEventKeyboard *)pe;
|
||||
|
||||
gwinPrintf(ghConsole, "KEYSTATE: 0x%04X [ %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s]",
|
||||
pk->keystate,
|
||||
(!pk->keystate ? "NONE " : ""),
|
||||
((pk->keystate & GKEYSTATE_KEYUP) ? "KEYUP " : ""),
|
||||
((pk->keystate & GKEYSTATE_REPEAT) ? "REPEAT " : ""),
|
||||
((pk->keystate & GKEYSTATE_SPECIAL) ? "SPECIAL " : ""),
|
||||
((pk->keystate & GKEYSTATE_RAW) ? "RAW " : ""),
|
||||
((pk->keystate & GKEYSTATE_SHIFT_L) ? "LSHIFT " : ""),
|
||||
((pk->keystate & GKEYSTATE_SHIFT_R) ? "RSHIFT " : ""),
|
||||
((pk->keystate & GKEYSTATE_CTRL_L) ? "LCTRL " : ""),
|
||||
((pk->keystate & GKEYSTATE_CTRL_R) ? "RCTRL " : ""),
|
||||
((pk->keystate & GKEYSTATE_ALT_L) ? "LALT " : ""),
|
||||
((pk->keystate & GKEYSTATE_ALT_R) ? "RALT " : ""),
|
||||
((pk->keystate & GKEYSTATE_FN) ? "FN " : ""),
|
||||
((pk->keystate & GKEYSTATE_COMPOSE) ? "COMPOSE " : ""),
|
||||
((pk->keystate & GKEYSTATE_WINKEY) ? "WINKEY " : ""),
|
||||
((pk->keystate & GKEYSTATE_CAPSLOCK) ? "CAPSLOCK " : ""),
|
||||
((pk->keystate & GKEYSTATE_NUMLOCK) ? "NUMLOCK " : ""),
|
||||
((pk->keystate & GKEYSTATE_SCROLLLOCK) ? "SCROLLLOCK " : "")
|
||||
);
|
||||
if (pk->bytecount) {
|
||||
gwinPrintf(ghConsole, " Keys:");
|
||||
for (i = 0; i < pk->bytecount; i++)
|
||||
gwinPrintf(ghConsole, " 0x%02X", (uint8_t)pk->c[i]);
|
||||
gwinPrintf(ghConsole, " [");
|
||||
for (i = 0; i < pk->bytecount; i++)
|
||||
gwinPrintf(ghConsole, "%c", pk->c[i] >= ' ' && pk->c[i] <= '~' ? pk->c[i] : ' ');
|
||||
gwinPrintf(ghConsole, "]");
|
||||
}
|
||||
gwinPrintf(ghConsole, "\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
gwinPrintf(ghConsole, "Unknown %d\n", pe->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
1
demos/modules/gwin/keyboard/readme.txt
Normal file
1
demos/modules/gwin/keyboard/readme.txt
Normal file
@ -0,0 +1 @@
|
||||
This demo demonstrates the virtual keyboard.
|
@ -36,6 +36,7 @@ FEATURE: Added SSD1331 gdisp driver
|
||||
FEATURE: Added arduino as a GOS supported operating system
|
||||
FEATURE: Added additional pixel format's
|
||||
FIX: Color components fixed for some strange compilers
|
||||
FEATURE: Add GWIN virtual keyboard widget
|
||||
|
||||
*** Release 2.2 ***
|
||||
FEATURE: Added nested containers demo
|
||||
|
@ -180,6 +180,9 @@
|
||||
// #define GWIN_NEED_LIST_IMAGES FALSE
|
||||
// #define GWIN_NEED_PROGRESSBAR FALSE
|
||||
// #define GWIN_PROGRESSBAR_AUTO FALSE
|
||||
// #define GWIN_NEED_KEYBOARD FALSE
|
||||
// #define GWIN_KEYBOARD_DEFAULT_LAYOUT VirtualKeyboard_English1
|
||||
// #define GWIN_NEED_KEYBOARD_ENGLISH1 TRUE
|
||||
// #define GWIN_FLAT_STYLING FALSE
|
||||
// #define GWIN_WIDGET_TAGS FALSE
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#ifndef _GINPUT_KEYBOARD_H
|
||||
#define _GINPUT_KEYBOARD_H
|
||||
|
||||
#if GINPUT_NEED_KEYBOARD || defined(__DOXYGEN__)
|
||||
#if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Type definitions */
|
||||
@ -164,6 +164,10 @@ typedef struct GEventKeyboard_t {
|
||||
#define GLISTEN_KEYTRANSITIONS 0x0008 // Return transitions to the key state
|
||||
#define GLISTEN_KEYRAW 0x0010 // Return raw scan-codes. This turns off normal character processing.
|
||||
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_KEYBOARD || defined(__DOXYGEN__)
|
||||
|
||||
// All keyboards
|
||||
#define GKEYBOARD_ALL_INSTANCES ((unsigned)-1)
|
||||
|
||||
|
@ -15,5 +15,7 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \
|
||||
$(GFXLIB)/src/gwin/gwin_frame.c \
|
||||
$(GFXLIB)/src/gwin/gwin_tabset.c \
|
||||
$(GFXLIB)/src/gwin/gwin_gl3d.c \
|
||||
$(GFXLIB)/src/gwin/gwin_keyboard.c \
|
||||
$(GFXLIB)/src/gwin/gwin_keyboard_layout.c
|
||||
|
||||
GFXINC += $(GFXLIB)/3rdparty/tinygl-0.4-ugfx/include
|
||||
|
471
src/gwin/gwin_keyboard.c
Normal file
471
src/gwin/gwin_keyboard.c
Normal file
@ -0,0 +1,471 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/gwin/gwin_keyboard.c
|
||||
* @brief GWIN sub-system virtual keyboard code
|
||||
*/
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
#if GFX_USE_GWIN && GWIN_NEED_KEYBOARD
|
||||
|
||||
#include "gwin_class.h"
|
||||
#include "gwin_keyboard_layout.h"
|
||||
|
||||
|
||||
#define GKEYBOARD_FLG_REVERTSET (GWIN_FIRST_CONTROL_FLAG<<0)
|
||||
#define GKEYBOARD_FLG_QUICKUPDATE (GWIN_FIRST_CONTROL_FLAG<<1)
|
||||
|
||||
#define BAD_ROWCOL 255
|
||||
|
||||
typedef uint8_t utf8;
|
||||
typedef uint16_t utf16;
|
||||
typedef uint32_t utf32;
|
||||
|
||||
// A character code - note this is not UTF-32 but a representation of the UTF-8 code stream for a single character.
|
||||
typedef uint32_t ucode;
|
||||
|
||||
// Get the length of a UTF-8 string
|
||||
static int UTF8StrLen(const utf8 *s) {
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
if (s) {
|
||||
while (*s) {
|
||||
len++;
|
||||
if (!(s[0] & 0x80))
|
||||
s++;
|
||||
else if ((s[0] & 0xE0) == 0xC0 && (s[1] & 0xC0) == 0x80)
|
||||
s+=2;
|
||||
else if ((s[0] & 0xF0) == 0xE0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80)
|
||||
s+=3;
|
||||
else if ((s[0] & 0xF8) == 0xF0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80 && (s[3] & 0xC0) == 0x80)
|
||||
s+=4;
|
||||
else
|
||||
// Invalid UTF-8 sequence - assume a single byte
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
// Return the nth character of a UTF8 string
|
||||
static ucode UTF8CharAt(const utf8 *s, int n) {
|
||||
ucode u;
|
||||
|
||||
u = 0;
|
||||
if (!s) return 0;
|
||||
|
||||
while(*s) {
|
||||
if (!(s[0] & 0x80)) {
|
||||
u = s[0];
|
||||
s++;
|
||||
} else if ((s[0] & 0xE0) == 0xC0 && (s[1] & 0xC0) == 0x80) {
|
||||
u = s[1] | ((ucode)s[0] << 8);
|
||||
s+=2;
|
||||
} else if ((s[0] & 0xF0) == 0xE0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80) {
|
||||
u = s[2] | ((ucode)s[1] << 8) | ((ucode)s[0] << 16);
|
||||
s+=3;
|
||||
} else if ((s[0] & 0xF8) == 0xF0 && (s[1] & 0xC0) == 0x80 && (s[2] & 0xC0) == 0x80 && (s[3] & 0xC0) == 0x80) {
|
||||
u = s[3] | ((ucode)s[2] << 8) | ((ucode)s[1] << 16) | ((ucode)s[0] << 24);
|
||||
s+=4;
|
||||
} else {
|
||||
// Invalid UTF-8 sequence - assume a single byte
|
||||
u = s[0];
|
||||
s++;
|
||||
}
|
||||
if (--n < 0)
|
||||
return u;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert a ucode to a UTF8 string (with no NULL on the end). Returns the number of bytes.
|
||||
static unsigned UCode2UTF8(utf8 *dst, ucode u) {
|
||||
if (!(u & 0xFFFFFF00)) {
|
||||
dst[0] = u;
|
||||
return 1;
|
||||
}
|
||||
if (!(u & 0xFFFF0000)) {
|
||||
dst[0] = u >> 8;
|
||||
dst[1] = u;
|
||||
return 2;
|
||||
}
|
||||
if (!(u & 0xFF000000)) {
|
||||
dst[0] = u >> 16;
|
||||
dst[1] = u >> 8;
|
||||
dst[2] = u;
|
||||
return 3;
|
||||
}
|
||||
dst[0] = u >> 24;
|
||||
dst[1] = u >> 16;
|
||||
dst[2] = u >> 8;
|
||||
dst[3] = u;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int NumKeyRows(const char **keyset) {
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
while(*keyset++)
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
static void SendKeyboardEventToListener(GSourceListener *psl, GKeyboardObject *gk) {
|
||||
GEventKeyboard *pe;
|
||||
const GVSpecialKey *skey;
|
||||
unsigned i;
|
||||
|
||||
// If there is no event buffer just mark a missed event
|
||||
if (!(pe = (GEventKeyboard *)geventGetEventBuffer(psl))) {
|
||||
// This listener is missing - save the meta events that have happened
|
||||
psl->srcflags |= GKEYSTATE_MISSED_EVENT;
|
||||
return;
|
||||
}
|
||||
|
||||
// The virtual keyboard can't generate repeats
|
||||
//if ((psl->listenflags & GLISTEN_KEYREPEATSOFF) && (k->keystate & GKEYSTATE_REPEAT))
|
||||
// return;
|
||||
|
||||
// The virtual keyboard can't generate special keys
|
||||
//if ((psl->listenflags & GLISTEN_KEYNOSPECIALS) && (k->keystate & GKEYSTATE_SPECIAL))
|
||||
// return;
|
||||
|
||||
// The virtual keyboard treats a key release as a keydown
|
||||
//if (!(psl->listenflags & GLISTEN_KEYUP) && (k->keystate & GKEYSTATE_KEYUP))
|
||||
// k->cntc = 0;
|
||||
|
||||
// The virtual keyboard has no transitions
|
||||
//if (!(psl->listenflags & GLISTEN_KEYTRANSITIONS) && !k->cntc)
|
||||
// return;
|
||||
|
||||
pe->type = GEVENT_KEYBOARD;
|
||||
if (gk->key < 0x20) {
|
||||
skey = &gk->keytable->skeys[gk->key-1];
|
||||
for(i=0; skey->sendkey[i]; i++)
|
||||
pe->c[i] = skey->sendkey[i];
|
||||
} else
|
||||
i = UCode2UTF8((utf8 *)pe->c, gk->key);
|
||||
pe->bytecount = i;
|
||||
for(; i < 8; i++)
|
||||
pe->c[i] = 0;
|
||||
pe->keystate = psl->srcflags;
|
||||
psl->srcflags = 0;
|
||||
geventSendEvent(psl);
|
||||
}
|
||||
|
||||
static void SendKeyboardEvent(GKeyboardObject *gk) {
|
||||
GSourceListener *psl;
|
||||
|
||||
// Send to the keyboard specific source listeners
|
||||
psl = 0;
|
||||
while ((psl = geventGetSourceListener((GSourceHandle)gk, psl)))
|
||||
SendKeyboardEventToListener(psl, gk);
|
||||
}
|
||||
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
// Find the key from the keyset and the x, y position
|
||||
static void FindKey(GKeyboardObject *gk, coord_t x, coord_t y) {
|
||||
const utf8 *krow;
|
||||
fixed f;
|
||||
int idx;
|
||||
|
||||
if (x < 0 || y < 0 || x >= gk->w.g.width || y >= gk->w.g.height) {
|
||||
gk->keyrow = gk->keycol = BAD_ROWCOL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the y parameters
|
||||
f = FIXED(gk->w.g.height) / NumKeyRows(gk->keyset);
|
||||
gk->keyrow = FIXED(y) / f;
|
||||
gk->keyy = NONFIXED(f * gk->keyrow + FIXED0_5);
|
||||
gk->keycy = NONFIXED(f * (gk->keyrow+1) + FIXED0_5) - gk->keyy;
|
||||
|
||||
// Get the current row
|
||||
krow = (const utf8 *)gk->keyset[gk->keyrow];
|
||||
|
||||
// Get the x parameters
|
||||
f = FIXED(gk->w.g.width) / UTF8StrLen(krow);
|
||||
gk->keycol = FIXED(x) / f;
|
||||
|
||||
// Get the key
|
||||
gk->key = UTF8CharAt(krow, gk->keycol);
|
||||
|
||||
// Amalgamate identical keys into one big key
|
||||
idx = gk->keycol;
|
||||
while(gk->keycol > 0 && UTF8CharAt(krow, gk->keycol-1) == gk->key)
|
||||
gk->keycol--;
|
||||
while(UTF8CharAt(krow, ++idx) == gk->key);
|
||||
gk->keyx = NONFIXED(f * gk->keycol + FIXED0_5);
|
||||
gk->keycx = NONFIXED(f * idx + FIXED0_5) - gk->keyx;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
#define gk ((GKeyboardObject *)gw)
|
||||
|
||||
FindKey(gk, x, y);
|
||||
|
||||
// Do we have a valid key?
|
||||
if (gk->keyrow == BAD_ROWCOL) {
|
||||
if (gk->lastkeyrow != BAD_ROWCOL) {
|
||||
gw->g.flags |= GKEYBOARD_FLG_QUICKUPDATE;
|
||||
_gwinUpdate((GHandle)gw);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// We are turning off the display of the key
|
||||
gk->keyrow = gk->keycol = BAD_ROWCOL;
|
||||
|
||||
// Is this one of the special keys
|
||||
if (gk->key < 0x20) {
|
||||
// This is a special key
|
||||
const GVSpecialKey *skey;
|
||||
|
||||
skey = &gk->keytable->skeys[gk->key - 1];
|
||||
|
||||
if ((skey->flags & GVKEY_SINGLESET)) {
|
||||
// Single character switch to a new layout
|
||||
gk->keyset = gk->keytable->ksets[skey->newset];
|
||||
gk->w.g.flags &= ~(GKEYBOARD_FLG_QUICKUPDATE|GKEYBOARD_FLG_REVERTSET);
|
||||
gk->w.g.flags |= GKEYBOARD_FLG_REVERTSET;
|
||||
|
||||
} else if ((skey->flags & GVKEY_LOCKSET)) {
|
||||
// Locked switch to a new layout
|
||||
gk->keyset = gk->keytable->ksets[skey->newset];
|
||||
gk->w.g.flags &= ~(GKEYBOARD_FLG_QUICKUPDATE|GKEYBOARD_FLG_REVERTSET);
|
||||
|
||||
} else if ((gk->w.g.flags & GKEYBOARD_FLG_REVERTSET)) {
|
||||
// Revert to default layout
|
||||
gk->keyset = gk->keytable->ksets[0];
|
||||
gk->w.g.flags &= ~(GKEYBOARD_FLG_QUICKUPDATE|GKEYBOARD_FLG_REVERTSET);
|
||||
|
||||
} else {
|
||||
// Just turning off a key
|
||||
gw->g.flags |= GKEYBOARD_FLG_QUICKUPDATE;
|
||||
}
|
||||
|
||||
// Send the key if required
|
||||
if (skey->sendkey && skey->sendkey[0])
|
||||
SendKeyboardEvent(gk);
|
||||
|
||||
// Update the display
|
||||
_gwinUpdate((GHandle)gw);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Do we need to revert to the standard layout?
|
||||
if ((gk->w.g.flags & GKEYBOARD_FLG_REVERTSET)) {
|
||||
gk->keyset = gk->keytable->ksets[0];
|
||||
gk->w.g.flags &= ~(GKEYBOARD_FLG_QUICKUPDATE|GKEYBOARD_FLG_REVERTSET);
|
||||
} else {
|
||||
gw->g.flags |= GKEYBOARD_FLG_QUICKUPDATE;
|
||||
}
|
||||
|
||||
// Send the key
|
||||
SendKeyboardEvent(gk);
|
||||
|
||||
// Update the display
|
||||
_gwinUpdate((GHandle)gw);
|
||||
}
|
||||
|
||||
// A mouse move has occurred (it may or may not be over the button)
|
||||
static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y) {
|
||||
#define gk ((GKeyboardObject *)gw)
|
||||
|
||||
FindKey(gk, x, y);
|
||||
|
||||
if (gk->keyrow != gk->lastkeyrow || gk->keycol != gk->lastkeycol) {
|
||||
gk->w.g.flags |= GKEYBOARD_FLG_QUICKUPDATE;
|
||||
_gwinUpdate((GHandle)gw);
|
||||
}
|
||||
#undef gk
|
||||
}
|
||||
#endif
|
||||
|
||||
extern GVKeyTable GWIN_KEYBOARD_DEFAULT_LAYOUT;
|
||||
void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param);
|
||||
|
||||
// The button VMT table
|
||||
static const gwidgetVMT keyboardVMT = {
|
||||
{
|
||||
"VKeyboard", // The classname
|
||||
sizeof(GKeyboardObject), // The object size
|
||||
_gwidgetDestroy, // The destroy routine
|
||||
_gwidgetRedraw, // The redraw routine
|
||||
0, // The after-clear routine
|
||||
},
|
||||
gwinKeyboardDraw_Normal, // The default drawing routine
|
||||
#if GINPUT_NEED_MOUSE
|
||||
{
|
||||
MouseMove, // Process mouse down events
|
||||
MouseUp, // Process mouse up events
|
||||
MouseMove, // Process mouse move events
|
||||
},
|
||||
#endif
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
{
|
||||
0, // No toggle roles
|
||||
0, // Assign Toggles
|
||||
0, // Get Toggles
|
||||
0, // Process toggle off events
|
||||
0, // Process toggle on events
|
||||
},
|
||||
#endif
|
||||
#if GINPUT_NEED_DIAL
|
||||
{
|
||||
0, // No dial roles
|
||||
0, // Assign Dials (NOT USED)
|
||||
0, // Get Dials (NOT USED)
|
||||
0, // Process dial move events (NOT USED)
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
GHandle gwinGKeyboardCreate(GDisplay *g, GKeyboardObject *gk, const GWidgetInit *pInit) {
|
||||
if (!(gk = (GKeyboardObject *)_gwidgetCreate(g, &gk->w, pInit, &keyboardVMT)))
|
||||
return 0;
|
||||
|
||||
gk->keytable = &GWIN_KEYBOARD_DEFAULT_LAYOUT;
|
||||
gk->keyset = gk->keytable->ksets[0];
|
||||
gk->lastkeyrow = gk->lastkeycol = gk->keyrow = gk->keycol = BAD_ROWCOL;
|
||||
gwinSetVisible((GHandle)gk, pInit->g.show);
|
||||
return (GHandle)gk;
|
||||
}
|
||||
|
||||
GSourceHandle gwinKeyboardGetEventSource(GHandle gh) {
|
||||
if (gh->vmt != (gwinVMT *)&keyboardVMT)
|
||||
return 0;
|
||||
return (GSourceHandle)gh;
|
||||
}
|
||||
|
||||
void gwinKeyboardSetLayout(GHandle gh, struct GVKeyTable *layout) {
|
||||
#define gk ((GKeyboardObject *)gh)
|
||||
|
||||
if (gh->vmt != (gwinVMT *)&keyboardVMT)
|
||||
return;
|
||||
|
||||
if (!layout)
|
||||
layout = &GWIN_KEYBOARD_DEFAULT_LAYOUT;
|
||||
gk->keytable = layout;
|
||||
gk->keyset = gk->keytable->ksets[0];
|
||||
gk->lastkeyrow = gk->lastkeycol = gk->keyrow = gk->keycol = BAD_ROWCOL;
|
||||
gk->w.g.flags &= ~(GKEYBOARD_FLG_QUICKUPDATE|GKEYBOARD_FLG_REVERTSET);
|
||||
gwinRedraw(gh);
|
||||
#undef gk
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* Custom Draw Routines
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
static const GColorSet *getDrawColors(GWidgetObject *gw) {
|
||||
if (!(gw->g.flags & GWIN_FLG_SYSENABLED)) return &gw->pstyle->disabled;
|
||||
if ((gw->g.flags & GBUTTON_FLG_PRESSED)) return &gw->pstyle->pressed;
|
||||
return &gw->pstyle->enabled;
|
||||
}
|
||||
*/
|
||||
|
||||
void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param) {
|
||||
#define gk ((GKeyboardObject *)gw)
|
||||
|
||||
char cap[5];
|
||||
const char *pcap;
|
||||
const utf8 *krow;
|
||||
coord_t x, y, cx, cy;
|
||||
uint8_t rows, cols, row, col, kcols;
|
||||
ucode key;
|
||||
fixed fx, fy;
|
||||
const GColorSet *pcol;
|
||||
(void) param;
|
||||
|
||||
if (gw->g.vmt != (gwinVMT *)&keyboardVMT) return;
|
||||
|
||||
// Get the y parameters
|
||||
rows = NumKeyRows(gk->keyset);
|
||||
fy = FIXED(gk->w.g.height) / rows;
|
||||
for(row = 0; row < rows; row++) {
|
||||
y = NONFIXED(fy * row + FIXED0_5);
|
||||
cy = NONFIXED(fy * (row+1) + FIXED0_5) - y;
|
||||
|
||||
// Get the current row
|
||||
krow = (const utf8 *)gk->keyset[row];
|
||||
|
||||
// Get the x parameters
|
||||
cols = UTF8StrLen(krow);
|
||||
fx = FIXED(gk->w.g.width) / cols;
|
||||
for(col = 0; col < cols; col=kcols) {
|
||||
|
||||
// Choose the color
|
||||
if (!(gk->w.g.flags & GWIN_FLG_SYSENABLED))
|
||||
pcol = &gk->w.pstyle->disabled;
|
||||
else if (gk->keyrow == row && gk->keycol == col)
|
||||
pcol = &gk->w.pstyle->pressed;
|
||||
else
|
||||
pcol = &gk->w.pstyle->enabled;
|
||||
|
||||
// Get the key
|
||||
key = UTF8CharAt(krow, col);
|
||||
|
||||
// Amalgamate identical keys into one big key
|
||||
kcols = col+1;
|
||||
while(UTF8CharAt(krow, kcols) == key)
|
||||
kcols++;
|
||||
x = NONFIXED(fx * col + FIXED0_5);
|
||||
cx = NONFIXED(fx * kcols + FIXED0_5) - x;
|
||||
|
||||
if (key < 0x20) {
|
||||
pcap = gk->keytable->skeys[key-1].keycap;
|
||||
} else {
|
||||
cap[UCode2UTF8((utf8 *)cap, key)] = 0;
|
||||
pcap = cap;
|
||||
}
|
||||
switch(*pcap) {
|
||||
case '\001': // Shift (up arrow)
|
||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2, gw->g.y+y+1, gw->g.x+x+1, gw->g.y+y+cy-1, pcol->text);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
|
||||
break;
|
||||
case '\002': // Shift locked (up arrow - bold)
|
||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2, gw->g.y+y, gw->g.x+x+1, gw->g.y+y+cy-1, pcol->text);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2, gw->g.y+y, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
|
||||
gdispGDrawBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->edge);
|
||||
break;
|
||||
case '\t':
|
||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy-1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx-1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
|
||||
break;
|
||||
case '\b':
|
||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy/2, gw->g.x+x+cx-1, gw->g.y+y+1, pcol->text);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy/2, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
|
||||
break;
|
||||
case '\r':
|
||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy/2, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
|
||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx-1, gw->g.y+y+cy/2, gw->g.x+x+cx-1, gw->g.y+y+1, pcol->text);
|
||||
break;
|
||||
default:
|
||||
gdispGFillStringBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcap, gw->g.font, pcol->text, pcol->fill, justifyCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef gk
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GWIN && GWIN_NEED_KEYBOARD */
|
111
src/gwin/gwin_keyboard.h
Normal file
111
src/gwin/gwin_keyboard.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/gwin/gwin_button.h
|
||||
* @brief GWIN Graphic window subsystem header file.
|
||||
*
|
||||
* @defgroup Button Button
|
||||
* @ingroup Widgets
|
||||
*
|
||||
* @details GWIN allows it to easily create buttons with different styles
|
||||
* and check for different meta states such as: PRESSED, CLICKED,
|
||||
* RELEASED etc.
|
||||
*
|
||||
* @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
|
||||
* @pre GWIN_NEED_BUTTON must be set to TRUE in your gfxconf.h
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GWIN_KEYBOARD_H
|
||||
#define _GWIN_KEYBOARD_H
|
||||
|
||||
/* This file is included within "src/gwin/gwin_widget.h" */
|
||||
|
||||
/**
|
||||
* @brief The Event Type for a Button Event
|
||||
*/
|
||||
#define GEVENT_GWIN_KEYBOARD (GEVENT_GWIN_CTRL_FIRST+6)
|
||||
|
||||
/**
|
||||
* @brief A Keyboard Event
|
||||
* @note There are currently no GEventGWinButton listening flags - use 0 as the flags to @p gwinAttachListener()
|
||||
*/
|
||||
typedef GEventGWin GEventGWinKeyboard;
|
||||
|
||||
struct keyinfo {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The keyboard widget structure
|
||||
* @note Do not use the members directly - treat it as a black-box.
|
||||
*/
|
||||
typedef struct GKeyboardObject {
|
||||
GWidgetObject w;
|
||||
const struct GVKeyTable *keytable;
|
||||
const char **keyset;
|
||||
coord_t keyx, keyy;
|
||||
coord_t keycx, keycy;
|
||||
uint8_t lastkeyrow, lastkeycol;
|
||||
uint8_t keyrow, keycol;
|
||||
uint32_t key;
|
||||
} GKeyboardObject;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Create a keyboard widget.
|
||||
* @return NULL if there is no resultant drawing area, otherwise a window handle.
|
||||
*
|
||||
* @param[in] g The GDisplay to display this window on
|
||||
* @param[in] gb The GKeyboardObject structure to initialise. If this is NULL the structure is dynamically allocated.
|
||||
* @param[in] pInit The initialisation parameters
|
||||
*
|
||||
* @note The drawing color and the background color get set to the current defaults. If you haven't called
|
||||
* @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
|
||||
* @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
|
||||
* is no default font and text drawing operations will no nothing.
|
||||
* @note A keyboard remembers its normal drawing state. If there is a window manager then it is automatically
|
||||
* redrawn if the window is moved or its visibility state is changed.
|
||||
* @note A keyboard supports mouse input.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
GHandle gwinGKeyboardCreate(GDisplay *g, GKeyboardObject *gb, const GWidgetInit *pInit);
|
||||
#define gwinKeyboardCreate(gb, pInit) gwinGKeyboardCreate(GDISP, gb, pInit)
|
||||
|
||||
/**
|
||||
* @brief Get the keyboard event source for a GWIN virtual keyboard
|
||||
* @return The event source handle or NULL if this is not a virtual keyboard
|
||||
*
|
||||
* @param[in] gh The GWIN virtual keyboard
|
||||
*
|
||||
* @note Normal GINPUT Keyboard events are returned by this event source.
|
||||
*/
|
||||
GSourceHandle gwinKeyboardGetEventSource(GHandle gh);
|
||||
|
||||
/**
|
||||
* @brief Set the layout for the virtual keyboard
|
||||
*
|
||||
* @param[in] gh The GWIN virtual keyboard
|
||||
* @param[in] layout The keyboard layout to use (described by gwin_keyboard_layout.h)
|
||||
*
|
||||
* @note Changing the layout resets the keyboard to key set 0 of the keyboard and cancels any
|
||||
* pending shifts.
|
||||
*/
|
||||
void gwinKeyboardSetLayout(GHandle gh, struct GVKeyTable *layout);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GWIN_KEYBOARD_H */
|
||||
/** @} */
|
45
src/gwin/gwin_keyboard_layout.c
Normal file
45
src/gwin/gwin_keyboard_layout.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
#if GFX_USE_GWIN && GWIN_NEED_KEYBOARD
|
||||
|
||||
#include "gwin_keyboard_layout.h"
|
||||
|
||||
#if GWIN_NEED_KEYBOARD_ENGLISH1
|
||||
/* For this keyboard mapping we use:
|
||||
* Set 0 = Lowercase letters
|
||||
* Set 1 = Uppercase letters (transient)
|
||||
* Set 2 = Uppercase letters (locked)
|
||||
* Set 3 = Numbers
|
||||
* Set 4 = Symbols
|
||||
*/
|
||||
static const GVSpecialKey Eng1SKeys[] = {
|
||||
{ "\001", 0, GVKEY_SINGLESET, 1 }, // \001 (1) = Shift Lower to Upper
|
||||
{ "\001", 0, GVKEY_INVERT|GVKEY_LOCKSET, 2 }, // \002 (2) = Shift Upper to Upper Lock
|
||||
{ "\002", 0, GVKEY_INVERT|GVKEY_LOCKSET, 0 }, // \003 (3) = Shift Upper Lock to Lower
|
||||
{ "123", 0, GVKEY_LOCKSET, 3 }, // \004 (4) = Change to Numbers
|
||||
{ "\010", "\b", 0, 0 }, // \005 (5) = Backspace
|
||||
{ "\015", "\r", 0, 0 }, // \006 (6) = Enter 1
|
||||
{ "\015", "\r", 0, 0 }, // \007 (7) = Enter 2 (Short keycap)
|
||||
{ "Sym", 0, GVKEY_LOCKSET, 4 }, // \010 (8) = Change to Symbols
|
||||
{ "aA", 0, GVKEY_LOCKSET, 0 }, // \011 (9) = Change to Lower Alpha
|
||||
};
|
||||
static const char Eng1Set0Row3[] = "\004 .\006\006";
|
||||
static const char Eng1Set1Row0[] = "QWERTYUIOP";
|
||||
static const char Eng1Set1Row1[] = "ASDFGHJKL";
|
||||
static const char *Eng1Set0[] = { "qwertyuiop", "asdfghjkl", "\001zxcvbnm\005", Eng1Set0Row3, 0 };
|
||||
static const char *Eng1Set1[] = { Eng1Set1Row0, Eng1Set1Row1, "\002ZXCVBNM\005", Eng1Set0Row3, 0 };
|
||||
static const char *Eng1Set2[] = { Eng1Set1Row0, Eng1Set1Row1, "\003ZXCVBNM\005", Eng1Set0Row3, 0 };
|
||||
static const char *Eng1Set3[] = { "+-*/", "@789", "\007456", "\010123", "\01100.", 0 };
|
||||
static const char *Eng1Set4[] = { "#$%^&*()", "~`:;\"'{}", "<>?/\\|[]", "\011\004,! .@", 0 };
|
||||
static const GVKeySet Eng1Sets[] = { Eng1Set0, Eng1Set1, Eng1Set2, Eng1Set3, Eng1Set4, 0 };
|
||||
const GVKeyTable VirtualKeyboard_English1 = { Eng1SKeys, Eng1Sets };
|
||||
#endif // GWIN_NEED_KEYBOARD_ENGLISH1
|
||||
|
||||
#endif // GFX_USE_GWIN && GWIN_NEED_KEYBOARD
|
69
src/gwin/gwin_keyboard_layout.h
Normal file
69
src/gwin/gwin_keyboard_layout.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is subject to the terms of the GFX License. If a copy of
|
||||
* the license was not distributed with this file, you can obtain one at:
|
||||
*
|
||||
* http://ugfx.org/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file src/gwin/gwin_keyboard_layout.h
|
||||
* @brief GWIN Virtual Keyboard Layout structures.
|
||||
*/
|
||||
|
||||
#ifndef _GWIN_KEYBOARD_LAYOUT_H
|
||||
#define _GWIN_KEYBOARD_LAYOUT_H
|
||||
|
||||
/**
|
||||
* A GVKeyTable is a set of definitions that define how the keyboard lays out
|
||||
* its keys. A GVKeyTable consists of a number of GVKeySets and a special key table.
|
||||
*
|
||||
* A GVKeySet is a set of keys that make up the currently visible keyboard.
|
||||
* Special keys in the GVKeySet can be used to switch between GVKeySets within
|
||||
* the GVKeyTable. An example is a shift key which switches between the GVKeySet of
|
||||
* lower case keys and the GVKeySet of upper case keys. GVKeySet number 0 is special
|
||||
* in that it is the default GVKeySet when the keyboard is first displayed.
|
||||
*
|
||||
* A GVKeySet is made up of GVKeyRow's. Each GVKeyRow describes the keys on one row
|
||||
* of the keyboard.
|
||||
*
|
||||
* Each GVKeyRow covers a number of key columns. Different rows can have different numbers of columns.
|
||||
* eg. 'Q' -> 'P' has 10 keys while 'A' to 'L' has 9. Additionally each key can cover more than one
|
||||
* column position eg a wide space bar.
|
||||
*
|
||||
* Each GVKeyRow is just a string. Each character is the caption for one key. Using the same
|
||||
* character for two or more adjacent keys merges the keys into one big key covering multiple key columns.
|
||||
* Characters \001 to \037 (1 to 31) are special keys. How to handle and draw those is described by the
|
||||
* special key structure array. Special keys do things like changing keysets, returning characters less than 32,
|
||||
* have multiple character keycaps.
|
||||
*
|
||||
* Note: keycaps from the special key table with a single character from 1 to 31 in them may invoke special drawn
|
||||
* symbols eg. character 13 may cause a special symbol to be drawn for the enter key. Other than those characters
|
||||
* which are drawn as symbols by the keyboard draw function, all other characters for keycaps are drawn using the
|
||||
* current widget font.
|
||||
*
|
||||
* Special keycaps handled by the standard draw:
|
||||
* \001 (1) - Shift (up arrow)
|
||||
* \002 (2) - Shift locked (up arrow - bold)
|
||||
* \010 (8) - Tab (right arrow)
|
||||
* \011 (9) - BackSpace (left arrow)
|
||||
* \015 (13) - Carriage Return (hooked left arrow)
|
||||
*/
|
||||
|
||||
typedef struct GVSpecialKey {
|
||||
const char const *keycap; // The caption on the key
|
||||
const char const *sendkey; // The key to send (NULL means none)
|
||||
uint8_t flags; // Flags
|
||||
#define GVKEY_INVERT 0x01 // Invert the color
|
||||
#define GVKEY_SINGLESET 0x02 // Change set when this key is pressed but only for a single keystroke
|
||||
#define GVKEY_LOCKSET 0x04 // Change set when this key is pressed but stay there until the set is changed by the user
|
||||
uint8_t newset; // The new set to change to
|
||||
} GVSpecialKey;
|
||||
|
||||
typedef const char **GVKeySet; // Array of Rows - Null indicates the end
|
||||
typedef struct GVKeyTable {
|
||||
const GVSpecialKey *skeys; // Array of Special Key structures
|
||||
const GVKeySet *ksets; // Array of KeySets - Null indicates the end
|
||||
} GVKeyTable;
|
||||
|
||||
#endif /* _GWIN_KEYBOARD_LAYOUT_H */
|
||||
/** @} */
|
@ -135,6 +135,13 @@
|
||||
#ifndef GWIN_NEED_TABSET
|
||||
#define GWIN_NEED_TABSET FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should the virtual keyboard be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GWIN_NEED_KEYBOARD
|
||||
#define GWIN_NEED_KEYBOARD FALSE
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
@ -343,6 +350,27 @@
|
||||
#ifndef GWIN_FLASHING_PERIOD
|
||||
#define GWIN_FLASHING_PERIOD 250
|
||||
#endif
|
||||
/**
|
||||
* @brief The default keyboard layout for the virtual gwin keyboard
|
||||
* @details Defaults to VirtualKeyboardLayout_English1
|
||||
*/
|
||||
#ifndef GWIN_KEYBOARD_DEFAULT_LAYOUT
|
||||
#define GWIN_KEYBOARD_DEFAULT_LAYOUT VirtualKeyboard_English1
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
* @name GWIN Virtual Keyboard Layouts
|
||||
* @brief One or more of these may be defined. They will only be created if GWIN_NEED_KEYBOARD is TRUE.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief The default keyboard layout for the virtual gwin keyboard
|
||||
* @details Defaults to VirtualKeyboardLayout_English1
|
||||
*/
|
||||
#ifndef GWIN_NEED_KEYBOARD_ENGLISH1
|
||||
#define GWIN_NEED_KEYBOARD_ENGLISH1 TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#endif /* _GWIN_OPTIONS_H */
|
||||
|
@ -38,7 +38,7 @@
|
||||
#endif
|
||||
#endif
|
||||
#if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX || GWIN_NEED_LABEL || GWIN_NEED_RADIO || GWIN_NEED_LIST || \
|
||||
GWIN_NEED_IMAGE || GWIN_NEED_CHECKBOX || GWIN_NEED_PROGRESSBAR
|
||||
GWIN_NEED_IMAGE || GWIN_NEED_CHECKBOX || GWIN_NEED_PROGRESSBAR || GWIN_NEED_KEYBOARD
|
||||
#if !GWIN_NEED_WIDGET
|
||||
#if GFX_DISPLAY_RULE_WARNINGS
|
||||
#warning "GWIN: GWIN_NEED_WIDGET is required when a widget is used. It has been turned on for you."
|
||||
|
@ -377,5 +377,9 @@ bool_t gwinAttachListener(GListener *pl);
|
||||
#include "gwin_progressbar.h"
|
||||
#endif
|
||||
|
||||
#if GWIN_NEED_KEYBOARD || defined(__DOXYGEN__)
|
||||
#include "gwin_keyboard.h"
|
||||
#endif
|
||||
|
||||
#endif /* _GWIDGET_H */
|
||||
/** @} */
|
||||
|
Loading…
Reference in New Issue
Block a user