mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r12425) -Feature [FS#1846]: On Screen Keyboard for input fields so someone without a keyboard can enter text too. Patch by Dominik.
This commit is contained in:
parent
06c0e5df5a
commit
327e870962
Binary file not shown.
Binary file not shown.
|
@ -1523,6 +1523,10 @@
|
|||
RelativePath=".\..\src\order_gui.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\osk_gui.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\player_gui.cpp"
|
||||
>
|
||||
|
|
|
@ -1520,6 +1520,10 @@
|
|||
RelativePath=".\..\src\order_gui.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\osk_gui.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\player_gui.cpp"
|
||||
>
|
||||
|
|
|
@ -290,6 +290,7 @@ network/network_gui.cpp
|
|||
newgrf_gui.cpp
|
||||
news_gui.cpp
|
||||
order_gui.cpp
|
||||
osk_gui.cpp
|
||||
player_gui.cpp
|
||||
rail_gui.cpp
|
||||
road_gui.cpp
|
||||
|
|
|
@ -127,7 +127,7 @@ static const Widget _generate_landscape_widgets[] = {
|
|||
{ WWT_DROPDOWN, RESIZE_NONE, 12, 114, 175, 130, 141, 0x0, STR_NULL}, // Number of industries
|
||||
|
||||
{ WWT_TEXT, RESIZE_NONE, 0, 12, 110, 153, 163, STR_RANDOM_SEED, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_NONE, 15, 114, 207, 152, 163, 0x0, STR_RANDOM_SEED_HELP}, // Edit box for seed
|
||||
{ WWT_EDITBOX, RESIZE_NONE, 15, 114, 207, 152, 163, STR_RANDOM_SEED_OSKTITLE, STR_RANDOM_SEED_HELP}, // Edit box for seed
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 12, 216, 326, 152, 163, STR_RANDOM, STR_RANDOM_HELP},
|
||||
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 6, 243, 326, 228, 257, STR_GENERATE, STR_NULL}, // Generate button
|
||||
|
@ -181,7 +181,7 @@ static const Widget _heightmap_load_widgets[] = {
|
|||
{ WWT_DROPDOWN, RESIZE_NONE, 12, 114, 175, 152, 163, 0x0, STR_NULL}, // Number of industries
|
||||
|
||||
{ WWT_TEXT, RESIZE_NONE, 0, 12, 110, 175, 185, STR_RANDOM_SEED, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_NONE, 15, 114, 207, 174, 185, 0x0, STR_RANDOM_SEED_HELP}, // Edit box for seed
|
||||
{ WWT_EDITBOX, RESIZE_NONE, 15, 114, 207, 174, 185, STR_RANDOM_SEED_OSKTITLE, STR_RANDOM_SEED_HELP}, // Edit box for seed
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 12, 216, 326, 174, 185, STR_RANDOM, STR_RANDOM_HELP},
|
||||
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 6, 243, 326, 196, 225, STR_GENERATE, STR_NULL}, // Generate button
|
||||
|
@ -374,8 +374,11 @@ static void GenerateLandscapeWndProc(Window *w, WindowEvent *e)
|
|||
SetWindowDirty(w);
|
||||
break;
|
||||
|
||||
case GLAND_GENERATE_BUTTON: // Generate
|
||||
case GLAND_RANDOM_EDITBOX: // edit box for random seed
|
||||
ShowOnScreenKeyboard(w, & _genseed_query, GLAND_RANDOM_EDITBOX, 0, 0);
|
||||
break;
|
||||
|
||||
case GLAND_GENERATE_BUTTON: // Generate
|
||||
UpdatePatches();
|
||||
|
||||
if (_patches.town_layout == TL_NO_ROADS) {
|
||||
|
|
14
src/gfx.cpp
14
src/gfx.cpp
|
@ -561,6 +561,20 @@ Dimension GetStringBoundingBox(const char *str)
|
|||
return br;
|
||||
}
|
||||
|
||||
void DrawCharCentered(WChar c, int x, int y, uint16 real_color)
|
||||
{
|
||||
FontSize size = FS_NORMAL;
|
||||
byte color = real_color & 0xFF;
|
||||
uint palette = _use_dos_palette ? 1 : 0;
|
||||
int w = GetCharacterWidth(size, c);
|
||||
|
||||
_string_colorremap[1] = _string_colormap[palette][color].text;
|
||||
_string_colorremap[2] = _string_colormap[palette][color].shadow;
|
||||
_color_remap_ptr = _string_colorremap;
|
||||
|
||||
GfxMainBlitter(GetGlyph(size, c), x - w / 2, y, BM_COLOUR_REMAP);
|
||||
}
|
||||
|
||||
/** Draw a string at the given coordinates with the given colour
|
||||
* @param string the string to draw
|
||||
* @param x offset from left side of the screen, if negative offset from the right side
|
||||
|
|
|
@ -99,6 +99,8 @@ int DrawStringRightAligned(int x, int y, StringID str, uint16 color);
|
|||
void DrawStringRightAlignedTruncated(int x, int y, StringID str, uint16 color, uint maxw);
|
||||
void DrawStringRightAlignedUnderline(int x, int y, StringID str, uint16 color);
|
||||
|
||||
void DrawCharCentered(uint32 c, int x, int y, uint16 color);
|
||||
|
||||
void GfxFillRect(int left, int top, int right, int bottom, int color);
|
||||
void GfxDrawLine(int left, int top, int right, int bottom, int color);
|
||||
void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
|
||||
|
|
|
@ -1352,6 +1352,7 @@ STR_NETWORK_MULTIPLAYER :{WHITE}Multipla
|
|||
|
||||
STR_NETWORK_PLAYER_NAME :{BLACK}Player name:
|
||||
STR_NETWORK_ENTER_NAME_TIP :{BLACK}This is the name other players will identify you by
|
||||
STR_NETWORK_PLAYER_NAME_OSKTITLE :{BLACK}Enter your name
|
||||
STR_NETWORK_CONNECTION :{BLACK}Connection:
|
||||
STR_NETWORK_CONNECTION_TIP :{BLACK}Choose between an internet game or a Local Area Network (LAN) game
|
||||
|
||||
|
@ -1395,6 +1396,7 @@ STR_NETWORK_START_GAME_WINDOW :{WHITE}Start ne
|
|||
|
||||
STR_NETWORK_NEW_GAME_NAME :{BLACK}Game name:
|
||||
STR_NETWORK_NEW_GAME_NAME_TIP :{BLACK}The game name will be displayed to other players in the multiplayer game selection menu
|
||||
STR_NETWORK_NEW_GAME_NAME_OSKTITLE :{BLACK}Enter a name for the network game
|
||||
STR_NETWORK_SET_PASSWORD :{BLACK}Set password
|
||||
STR_NETWORK_PASSWORD_TIP :{BLACK}Protect your game with a password if you don't want it to be publicly accessible
|
||||
STR_NETWORK_SELECT_MAP :{BLACK}Select a map:
|
||||
|
@ -1556,6 +1558,7 @@ STR_NETWORK_CHAT_CLIENT :[Private] {STRI
|
|||
STR_NETWORK_CHAT_TO_CLIENT :[Private] To {STRING}: {GRAY}{STRING}
|
||||
STR_NETWORK_CHAT_ALL_CAPTION :[All] :
|
||||
STR_NETWORK_CHAT_ALL :[All] {STRING}: {GRAY}{STRING}
|
||||
STR_NETWORK_CHAT_OSKTITLE :{BLACK}Enter text for network chat
|
||||
STR_NETWORK_NAME_CHANGE :has changed his/her name to
|
||||
STR_NETWORK_SERVER_SHUTDOWN :{WHITE} The server closed the session
|
||||
STR_NETWORK_SERVER_REBOOT :{WHITE} The server is restarting...{}Please wait...
|
||||
|
@ -1959,6 +1962,7 @@ STR_400E_SELECT_NEW_GAME_TYPE :{WHITE}Select N
|
|||
STR_400F_SELECT_SCENARIO_GREEN_PRE :{BLACK}Select scenario (green), pre-set game (blue), or random new game
|
||||
STR_4010_GENERATE_RANDOM_NEW_GAME :Generate random new game
|
||||
STR_LOAD_HEIGHTMAP :{WHITE}Load Heightmap
|
||||
STR_SAVE_OSKTITLE :{BLACK}Enter a name for the savegame
|
||||
|
||||
##id 0x4800
|
||||
STR_4800_IN_THE_WAY :{WHITE}{STRING} in the way
|
||||
|
@ -3273,6 +3277,7 @@ STR_RANDOM_HELP :{BLACK}Change t
|
|||
STR_WORLD_GENERATION_CAPTION :{WHITE}World generation
|
||||
STR_RANDOM_SEED :{BLACK}Random Seed:
|
||||
STR_RANDOM_SEED_HELP :{BLACK}Click to enter a random seed
|
||||
STR_RANDOM_SEED_OSKTITLE :{BLACK}Enter a random seed
|
||||
STR_LAND_GENERATOR :{BLACK}Land generator:
|
||||
STR_TREE_PLACER :{BLACK}Tree algorithm:
|
||||
STR_HEIGHTMAP_ROTATION :{BLACK}Heightmap rotation:
|
||||
|
@ -3420,6 +3425,7 @@ STR_NAME_MUST_BE_UNIQUE :{WHITE}Name mus
|
|||
#### Improved sign GUI
|
||||
STR_NEXT_SIGN_TOOLTIP :{BLACK}Go to next sign
|
||||
STR_PREVIOUS_SIGN_TOOLTIP :{BLACK}Go to previous sign
|
||||
STR_SIGN_OSKTITLE :{BLACK}Enter a name for the sign
|
||||
|
||||
########
|
||||
|
||||
|
@ -3492,3 +3498,8 @@ STR_DRAG_SIGNALS_DENSITY_TIP :{BLACK}Dragging
|
|||
STR_DRAG_SIGNALS_DENSITY_DECREASE_TIP :{BLACK}Decrease dragging signal density
|
||||
STR_DRAG_SIGNALS_DENSITY_INCREASE_TIP :{BLACK}Increase dragging signal density
|
||||
########
|
||||
|
||||
############ on screen keyboard
|
||||
STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ .
|
||||
STR_OSK_KEYBOARD_LAYOUT_CAPS :~!@#$%^&*()_+|QWERTYUIOP{{}}ASDFGHJKL:" ZXCVBNM<>? .
|
||||
########
|
||||
|
|
|
@ -3485,3 +3485,8 @@ STR_DRAG_SIGNALS_DENSITY_TIP :{BLACK}Abstand
|
|||
STR_DRAG_SIGNALS_DENSITY_DECREASE_TIP :{BLACK}Signalabstand verringern
|
||||
STR_DRAG_SIGNALS_DENSITY_INCREASE_TIP :{BLACK}Signalabstand erhöhen
|
||||
########
|
||||
|
||||
############ on screen keyboard
|
||||
STR_OSK_KEYBOARD_LAYOUT :^1234567890ß'€qwertzuiopü+asdfghjklöä#<yxcvbnm,.- .
|
||||
STR_OSK_KEYBOARD_LAYOUT_CAPS :°!"§$%&/()=?`@QWERTZUIOPÜ*ASDFGHJKLÖÄ'>YXCVBNM;:_ .
|
||||
########
|
||||
|
|
|
@ -1084,6 +1084,8 @@ void DrawEditBox(Window *w, querystr_d *string, int wid)
|
|||
const Widget *wi = &w->widget[wid];
|
||||
const Textbuf *tb = &string->text;
|
||||
|
||||
assert((wi->type & WWT_MASK) == WWT_EDITBOX);
|
||||
|
||||
GfxFillRect(wi->left + 1, wi->top + 1, wi->right - 1, wi->bottom - 1, 215);
|
||||
|
||||
/* Limit the drawing of the string inside the widget boundaries */
|
||||
|
@ -1135,6 +1137,10 @@ static void QueryStringWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
case WE_CLICK:
|
||||
switch (e->we.click.widget) {
|
||||
case QUERY_STR_WIDGET_TEXT:
|
||||
ShowOnScreenKeyboard(w, &WP(w, querystr_d), QUERY_STR_WIDGET_TEXT, QUERY_STR_WIDGET_CANCEL, QUERY_STR_WIDGET_OK);
|
||||
break;
|
||||
|
||||
case QUERY_STR_WIDGET_OK:
|
||||
press_ok:;
|
||||
if (qs->orig == NULL || strcmp(qs->text.buf, qs->orig) != 0) {
|
||||
|
@ -1188,7 +1194,7 @@ static const Widget _query_string_widgets[] = {
|
|||
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, RESIZE_NONE, 14, 11, 259, 0, 13, STR_012D, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 0, 259, 14, 29, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 2, 257, 16, 27, 0x0, STR_NULL},
|
||||
{ WWT_EDITBOX, RESIZE_NONE, 14, 2, 257, 16, 27, 0x0, STR_NULL},
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 0, 129, 30, 41, STR_012E_CANCEL, STR_NULL},
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 130, 259, 30, 41, STR_012F_OK, STR_NULL},
|
||||
{ WIDGETS_END},
|
||||
|
@ -1202,7 +1208,8 @@ static const WindowDesc _query_string_desc = {
|
|||
QueryStringWndProc
|
||||
};
|
||||
|
||||
static char _edit_str_buf[64];
|
||||
char _edit_str_buf[64];
|
||||
char _orig_str_buf[lengthof(_edit_str_buf)];
|
||||
|
||||
/** Show a query popup window with a textbox in it.
|
||||
* @param str StringID for the text shown in the textbox
|
||||
|
@ -1215,7 +1222,6 @@ static char _edit_str_buf[64];
|
|||
* @param afilter filters out unwanted character input */
|
||||
void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, Window *parent, CharSetFilter afilter)
|
||||
{
|
||||
static char orig_str_buf[lengthof(_edit_str_buf)];
|
||||
Window *w;
|
||||
uint realmaxlen = maxlen & ~0x1000;
|
||||
|
||||
|
@ -1233,8 +1239,8 @@ void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth,
|
|||
if (maxlen & 0x1000) {
|
||||
WP(w, querystr_d).orig = NULL;
|
||||
} else {
|
||||
strecpy(orig_str_buf, _edit_str_buf, lastof(orig_str_buf));
|
||||
WP(w, querystr_d).orig = orig_str_buf;
|
||||
strecpy(_orig_str_buf, _edit_str_buf, lastof(_orig_str_buf));
|
||||
WP(w, querystr_d).orig = _orig_str_buf;
|
||||
}
|
||||
|
||||
w->LowerWidget(QUERY_STR_WIDGET_TEXT);
|
||||
|
@ -1379,7 +1385,7 @@ static const Widget _save_dialog_widgets[] = {
|
|||
{ WWT_INSET, RESIZE_RB, 14, 2, 243, 50, 150, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES},
|
||||
{ WWT_SCROLLBAR, RESIZE_LRB, 14, 245, 256, 60, 151, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST},
|
||||
{ WWT_PANEL, RESIZE_RTB, 14, 0, 256, 152, 167, 0x0, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_RTB, 14, 2, 254, 154, 165, 0x0, STR_400B_CURRENTLY_SELECTED_NAME},
|
||||
{ WWT_EDITBOX, RESIZE_RTB, 14, 2, 254, 154, 165, STR_SAVE_OSKTITLE,STR_400B_CURRENTLY_SELECTED_NAME},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 127, 168, 179, STR_4003_DELETE, STR_400C_DELETE_THE_CURRENTLY_SELECTED},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_TB, 14, 128, 244, 168, 179, STR_4002_SAVE, STR_400D_SAVE_THE_CURRENT_GAME_USING},
|
||||
{ WWT_RESIZEBOX, RESIZE_LRTB, 14, 245, 256, 168, 179, 0x0, STR_RESIZE_BUTTON},
|
||||
|
@ -1587,6 +1593,10 @@ static void SaveLoadDlgWndProc(Window *w, WindowEvent *e)
|
|||
break;
|
||||
}
|
||||
|
||||
case 10: // edit box
|
||||
ShowOnScreenKeyboard(w, &WP(w, querystr_d), e->we.click.widget, 0, 0);
|
||||
break;
|
||||
|
||||
case 11: case 12: // Delete, Save game
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -426,6 +426,9 @@ static void NetworkGameWindowWndProc(Window *w, WindowEvent *e)
|
|||
case WE_CLICK:
|
||||
nd->field = e->we.click.widget;
|
||||
switch (e->we.click.widget) {
|
||||
case NGWW_PLAYER:
|
||||
ShowOnScreenKeyboard(w, &WP(w, network_ql_d).q, NGWW_PLAYER, 0, 0);
|
||||
break;
|
||||
case NGWW_CANCEL: // Cancel button
|
||||
DeleteWindowById(WC_NETWORK_WINDOW, 0);
|
||||
break;
|
||||
|
@ -574,7 +577,7 @@ static const Widget _network_game_window_widgets[] = {
|
|||
{ WWT_TEXT, RESIZE_NONE, BGC, 9, 85, 23, 35, STR_NETWORK_CONNECTION, STR_NULL},
|
||||
{ WWT_DROPDOWNIN, RESIZE_NONE, BGC, 90, 181, 22, 33, STR_NETWORK_LAN_INTERNET_COMBO, STR_NETWORK_CONNECTION_TIP}, // NGWW_CONN_BTN
|
||||
|
||||
{ WWT_PANEL, RESIZE_LR, BGC, 290, 440, 22, 33, 0x0, STR_NETWORK_ENTER_NAME_TIP}, // NGWW_PLAYER
|
||||
{ WWT_EDITBOX, RESIZE_LR, BGC, 290, 440, 22, 33, STR_NETWORK_PLAYER_NAME_OSKTITLE, STR_NETWORK_ENTER_NAME_TIP}, // NGWW_PLAYER
|
||||
|
||||
/* LEFT SIDE */
|
||||
{ WWT_PUSHTXTBTN, RESIZE_RIGHT, BTC, 10, 70, 42, 53, STR_NETWORK_GAME_NAME, STR_NETWORK_GAME_NAME_TIP}, // NGWW_NAME
|
||||
|
@ -736,7 +739,9 @@ static void NetworkStartServerWindowWndProc(Window *w, WindowEvent *e)
|
|||
case NSSW_CANCEL: // Cancel button
|
||||
ShowNetworkGameWindow();
|
||||
break;
|
||||
|
||||
case NSSW_GAMENAME:
|
||||
ShowOnScreenKeyboard(w, &WP(w, network_ql_d).q, NSSW_GAMENAME, 0, 0);
|
||||
break;
|
||||
case NSSW_SETPWD: // Set password button
|
||||
nd->widget_id = NSSW_SETPWD;
|
||||
ShowQueryString(BindCString(_network_server_password), STR_NETWORK_SET_PASSWORD, 20, 250, w, CS_ALPHANUMERAL);
|
||||
|
@ -887,7 +892,7 @@ static const Widget _network_start_server_window_widgets[] = {
|
|||
|
||||
/* Set game name and password widgets */
|
||||
{ WWT_TEXT, RESIZE_NONE, BGC, 10, 90, 22, 34, STR_NETWORK_NEW_GAME_NAME, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_NONE, BGC, 100, 272, 22, 33, 0x0, STR_NETWORK_NEW_GAME_NAME_TIP}, // NSSW_GAMENAME
|
||||
{ WWT_EDITBOX, RESIZE_NONE, BGC, 100, 272, 22, 33, STR_NETWORK_NEW_GAME_NAME_OSKTITLE, STR_NETWORK_NEW_GAME_NAME_TIP}, // NSSW_GAMENAME
|
||||
{ WWT_PUSHTXTBTN, RESIZE_NONE, BTC, 285, 405, 22, 33, STR_NETWORK_SET_PASSWORD, STR_NETWORK_PASSWORD_TIP}, // NSSW_SETPWD
|
||||
|
||||
/* List of playable scenarios */
|
||||
|
@ -1818,6 +1823,10 @@ static void ChatWindowWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
case WE_CLICK:
|
||||
switch (e->we.click.widget) {
|
||||
case 2:
|
||||
ShowOnScreenKeyboard(w, &WP(w, chatquerystr_d), 2, 0, 3);
|
||||
break;
|
||||
|
||||
case 3: /* Send */
|
||||
SendChat(WP(w, chatquerystr_d).text.buf, WP(w, chatquerystr_d).dtype, WP(w, chatquerystr_d).dest);
|
||||
/* FALLTHROUGH */
|
||||
|
@ -1851,10 +1860,10 @@ static void ChatWindowWndProc(Window *w, WindowEvent *e)
|
|||
}
|
||||
|
||||
static const Widget _chat_window_widgets[] = {
|
||||
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_PANEL, RESIZE_RIGHT, 14, 11, 319, 0, 13, 0x0, STR_NULL}, // background
|
||||
{ WWT_PANEL, RESIZE_RIGHT, 14, 75, 257, 1, 12, 0x0, STR_NULL}, // text box
|
||||
{ WWT_PUSHTXTBTN, RESIZE_LR, 14, 258, 319, 1, 12, STR_NETWORK_SEND, STR_NULL}, // send button
|
||||
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_PANEL, RESIZE_RIGHT, 14, 11, 319, 0, 13, 0x0, STR_NULL}, // background
|
||||
{ WWT_EDITBOX, RESIZE_RIGHT, 14, 75, 257, 1, 12, STR_NETWORK_CHAT_OSKTITLE, STR_NULL}, // text box
|
||||
{ WWT_PUSHTXTBTN, RESIZE_LR, 14, 258, 319, 1, 12, STR_NETWORK_SEND, STR_NULL}, // send button
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
|
@ -1926,6 +1935,9 @@ static void NetworkCompanyPasswordWindowWndProc(Window *w, WindowEvent *e)
|
|||
w->ToggleWidgetLoweredState(NCPWW_SAVE_AS_DEFAULT_PASSWORD);
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
case NCPWW_PASSWORD:
|
||||
ShowOnScreenKeyboard(w, &WP(w, chatquerystr_d), NCPWW_PASSWORD, 2, 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1954,7 +1966,7 @@ static const Widget _ncp_window_widgets[] = {
|
|||
{ WWT_CAPTION, RESIZE_NONE, 14, 11, 299, 0, 13, STR_COMPANY_PASSWORD_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 0, 299, 14, 50, 0x0, STR_NULL},
|
||||
{ WWT_TEXT, RESIZE_NONE, 14, 5, 100, 19, 30, STR_COMPANY_PASSWORD, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 101, 294, 19, 30, 0x0, STR_NULL},
|
||||
{ WWT_EDITBOX, RESIZE_NONE, 14, 101, 294, 19, 30, STR_SET_COMPANY_PASSWORD, STR_NULL},
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 101, 294, 35, 46, STR_MAKE_DEFAULT_COMPANY_PASSWORD, STR_MAKE_DEFAULT_COMPANY_PASSWORD_TIP},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 0, 149, 51, 62, STR_012E_CANCEL, STR_COMPANY_PASSWORD_CANCEL},
|
||||
{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 150, 299, 51, 62, STR_012F_OK, STR_COMPANY_PASSWORD_OK},
|
||||
|
|
|
@ -0,0 +1,362 @@
|
|||
/* $Id$ */
|
||||
|
||||
/** @file osk_gui.cpp The On Screen Keyboard GUI */
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "openttd.h"
|
||||
|
||||
#include "textbuf_gui.h"
|
||||
#include "window_gui.h"
|
||||
#include "string_func.h"
|
||||
#include "strings_func.h"
|
||||
#include "debug.h"
|
||||
#include "window_func.h"
|
||||
#include "gfx_func.h"
|
||||
|
||||
#include "table/sprites.h"
|
||||
#include "table/strings.h"
|
||||
|
||||
struct osk_d {
|
||||
querystr_d *qs; // text-input
|
||||
int text_btn; // widget number of parent's text field
|
||||
int ok_btn; // widget number of parent's ok button (=0 when ok shouldn't be passed on)
|
||||
int cancel_btn; // widget number of parent's cancel button (=0 when cancel shouldn't be passed on; text will be reverted to original)
|
||||
Textbuf *text; // pointer to parent's textbuffer (to update caret position)
|
||||
char *orig; // the original text, in case we cancel
|
||||
};
|
||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(osk_d));
|
||||
|
||||
enum OskWidgets {
|
||||
OSK_WIDGET_TEXT = 3,
|
||||
OSK_WIDGET_CANCEL = 5,
|
||||
OSK_WIDGET_OK,
|
||||
OSK_WIDGET_BACKSPACE,
|
||||
OSK_WIDGET_SPECIAL,
|
||||
OSK_WIDGET_CAPS,
|
||||
OSK_WIDGET_SHIFT,
|
||||
OSK_WIDGET_SPACE,
|
||||
OSK_WIDGET_LEFT,
|
||||
OSK_WIDGET_RIGHT,
|
||||
OSK_WIDGET_LETTERS
|
||||
};
|
||||
|
||||
char _keyboard_opt[2][OSK_KEYBOARD_ENTRIES * 4 + 1];
|
||||
static WChar _keyboard[2][OSK_KEYBOARD_ENTRIES];
|
||||
|
||||
enum {
|
||||
KEYS_NONE,
|
||||
KEYS_SHIFT,
|
||||
KEYS_CAPS
|
||||
};
|
||||
static byte _keystate = KEYS_NONE;
|
||||
|
||||
/*
|
||||
* Only show valid characters; do not show characters that would
|
||||
* only insert a space when we have a spacebar to do that or
|
||||
* characters that are not allowed to be entered.
|
||||
*/
|
||||
static void ChangeOskDiabledState(Window *w, const querystr_d *qs, bool shift)
|
||||
{
|
||||
for (uint i = 0; i < OSK_KEYBOARD_ENTRIES; i++) {
|
||||
w->SetWidgetDisabledState(OSK_WIDGET_LETTERS + i,
|
||||
!IsValidChar(_keyboard[shift][i], qs->afilter) || _keyboard[shift][i] == ' ');
|
||||
}
|
||||
w->SetWidgetDisabledState(OSK_WIDGET_SPACE, !IsValidChar(' ', qs->afilter));
|
||||
}
|
||||
|
||||
/* on screen keyboard */
|
||||
static void OskWndProc(Window *w, WindowEvent *e)
|
||||
{
|
||||
querystr_d *qs = WP(w, osk_d).qs;
|
||||
|
||||
switch (e->event) {
|
||||
case WE_CREATE:
|
||||
SetBit(_no_scroll, SCROLL_EDIT);
|
||||
/* Not needed by default. */
|
||||
w->DisableWidget(OSK_WIDGET_SPECIAL);
|
||||
break;
|
||||
|
||||
case WE_PAINT: {
|
||||
bool shift = HasBit(_keystate, KEYS_CAPS) ^ HasBit(_keystate, KEYS_SHIFT);
|
||||
|
||||
w->LowerWidget(OSK_WIDGET_TEXT);
|
||||
w->SetWidgetLoweredState(OSK_WIDGET_SHIFT, HasBit(_keystate, KEYS_SHIFT));
|
||||
w->SetWidgetLoweredState(OSK_WIDGET_CAPS, HasBit(_keystate, KEYS_CAPS));
|
||||
|
||||
ChangeOskDiabledState(w, qs, shift);
|
||||
|
||||
SetDParam(0, qs->caption);
|
||||
DrawWindowWidgets(w);
|
||||
|
||||
for (uint i = 0; i < OSK_KEYBOARD_ENTRIES; i++) {
|
||||
DrawCharCentered(_keyboard[shift][i],
|
||||
w->widget[OSK_WIDGET_LETTERS + i].left + 8,
|
||||
w->widget[OSK_WIDGET_LETTERS + i].top + 3,
|
||||
TC_BLACK);
|
||||
}
|
||||
|
||||
DrawEditBox(w, qs, OSK_WIDGET_TEXT);
|
||||
break;
|
||||
}
|
||||
|
||||
case WE_CLICK:
|
||||
/* clicked a letter */
|
||||
if (e->we.click.widget >= OSK_WIDGET_LETTERS) {
|
||||
bool shift = HasBit(_keystate, KEYS_CAPS) ^ HasBit(_keystate, KEYS_SHIFT);
|
||||
|
||||
WChar c = _keyboard[shift][e->we.click.widget - OSK_WIDGET_LETTERS];
|
||||
|
||||
if (!IsValidChar(c, qs->afilter)) break;
|
||||
|
||||
if (InsertTextBufferChar(&qs->text, c)) w->InvalidateWidget(OSK_WIDGET_TEXT);
|
||||
|
||||
if (HasBit(_keystate, KEYS_SHIFT)) {
|
||||
ToggleBit(_keystate, KEYS_SHIFT);
|
||||
w->widget[OSK_WIDGET_SHIFT].color = HasBit(_keystate, KEYS_SHIFT) ? 15 : 14;
|
||||
SetWindowDirty(w);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (e->we.click.widget) {
|
||||
case OSK_WIDGET_BACKSPACE:
|
||||
if (DeleteTextBufferChar(&qs->text, WKC_BACKSPACE)) w->InvalidateWidget(OSK_WIDGET_TEXT);
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_SPECIAL:
|
||||
/*
|
||||
* Anything device specific can go here.
|
||||
* The button itself is hidden by default, and when you need it you
|
||||
* can not hide it in the create event.
|
||||
*/
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_CAPS:
|
||||
ToggleBit(_keystate, KEYS_CAPS);
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_SHIFT:
|
||||
ToggleBit(_keystate, KEYS_SHIFT);
|
||||
SetWindowDirty(w);
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_SPACE:
|
||||
if (InsertTextBufferChar(&qs->text, ' ')) w->InvalidateWidget(OSK_WIDGET_TEXT);
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_LEFT:
|
||||
if (MoveTextBufferPos(&qs->text, WKC_LEFT)) w->InvalidateWidget(OSK_WIDGET_TEXT);
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_RIGHT:
|
||||
if (MoveTextBufferPos(&qs->text, WKC_RIGHT)) w->InvalidateWidget(OSK_WIDGET_TEXT);
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_OK:
|
||||
if (qs->orig == NULL || strcmp(qs->text.buf, qs->orig) != 0) {
|
||||
/* pass information by simulating a button press on parent window */
|
||||
if (WP(w, osk_d).ok_btn != 0) {
|
||||
Window *parent = w->parent;
|
||||
WindowEvent e;
|
||||
e.event = WE_CLICK;
|
||||
e.we.click.widget = WP(w, osk_d).ok_btn;
|
||||
parent->wndproc(parent, &e);
|
||||
}
|
||||
}
|
||||
DeleteWindow(w);
|
||||
break;
|
||||
|
||||
case OSK_WIDGET_CANCEL:
|
||||
if (WP(w, osk_d).cancel_btn != 0) { // pass a cancel event to the parent window
|
||||
Window *parent = w->parent;
|
||||
WindowEvent e;
|
||||
e.event = WE_CLICK;
|
||||
e.we.click.widget = WP(w, osk_d).cancel_btn;
|
||||
parent->wndproc(parent, &e);
|
||||
} else { // or reset to original string
|
||||
strcpy(qs->text.buf, WP(w, osk_d).orig);
|
||||
UpdateTextBufferSize(&qs->text);
|
||||
MoveTextBufferPos(&qs->text, WKC_END);
|
||||
}
|
||||
DeleteWindow(w);
|
||||
break;
|
||||
}
|
||||
/* make sure that the parent window's textbox also gets updated */
|
||||
if (w->parent != NULL) w->parent->InvalidateWidget(WP(w, osk_d).text_btn);
|
||||
break;
|
||||
|
||||
case WE_MOUSELOOP:
|
||||
HandleEditBox(w, qs, OSK_WIDGET_TEXT);
|
||||
/* make the caret of the parent window also blink */
|
||||
w->parent->InvalidateWidget(WP(w, osk_d).text_btn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const Widget _osk_widgets[] = {
|
||||
{ WWT_EMPTY, RESIZE_NONE, 0, 0, 0, 0, 0, 0x0, STR_NULL},
|
||||
{ WWT_CAPTION, RESIZE_NONE, 14, 0, 255, 0, 13, STR_012D, STR_NULL},
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 0, 255, 14, 29, 0x0, STR_NULL},
|
||||
{ WWT_EDITBOX, RESIZE_NONE, 14, 2, 253, 16, 27, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 0, 255, 30, 139, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 3, 108, 35, 46, STR_012E_CANCEL, STR_NULL},
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 111, 216, 35, 46, STR_012F_OK, STR_NULL},
|
||||
{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 219, 252, 35, 46, SPR_OSK_BACKSPACE, STR_NULL},
|
||||
|
||||
{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 3, 27, 67, 82, SPR_OSK_SPECIAL, STR_NULL},
|
||||
{ WWT_IMGBTN, RESIZE_NONE, 14, 3, 36, 85, 100, SPR_OSK_CAPS, STR_NULL},
|
||||
{ WWT_IMGBTN, RESIZE_NONE, 14, 3, 27, 103, 118, SPR_OSK_SHIFT, STR_NULL},
|
||||
|
||||
{ WWT_PUSHTXTBTN, RESIZE_NONE, 14, 75, 189, 121, 136, STR_EMPTY, STR_NULL},
|
||||
|
||||
{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 219, 234, 121, 136, SPR_OSK_LEFT, STR_NULL},
|
||||
{ WWT_PUSHIMGBTN, RESIZE_NONE, 14, 237, 252, 121, 136, SPR_OSK_RIGHT, STR_NULL},
|
||||
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 3, 18, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 21, 36, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 39, 54, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 57, 72, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 75, 90, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 93, 108, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 111, 126, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 129, 144, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 147, 162, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 165, 180, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 183, 198, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 201, 216, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 219, 234, 49, 64, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 237, 252, 49, 64, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 30, 45, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 48, 63, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 66, 81, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 84, 99, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 102, 117, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 120, 135, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 138, 153, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 156, 171, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 174, 189, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 192, 207, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 210, 225, 67, 82, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 228, 243, 67, 82, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 39, 54, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 57, 72, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 75, 90, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 93, 108, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 111, 126, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 129, 144, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 147, 162, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 165, 180, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 183, 198, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 201, 216, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 219, 234, 85, 100, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 237, 252, 85, 100, 0x0, STR_NULL},
|
||||
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 30, 45, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 48, 63, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 66, 81, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 84, 99, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 102, 117, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 120, 135, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 138, 153, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 156, 171, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 174, 189, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 192, 207, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 210, 225, 103, 118, 0x0, STR_NULL},
|
||||
{ WWT_PUSHBTN, RESIZE_NONE, 14, 228, 243, 103, 118, 0x0, STR_NULL},
|
||||
|
||||
{ WIDGETS_END},
|
||||
};
|
||||
|
||||
WindowDesc _osk_desc = {
|
||||
WDP_CENTER, WDP_CENTER, 256, 140, 256, 140,
|
||||
WC_OSK, WC_NONE,
|
||||
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
|
||||
_osk_widgets,
|
||||
OskWndProc
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve keyboard layout from language string or (if set) config file.
|
||||
* Also check for invalid characters.
|
||||
*/
|
||||
void GetKeyboardLayout()
|
||||
{
|
||||
char keyboard[2][OSK_KEYBOARD_ENTRIES * 4 + 1];
|
||||
char errormark[2][OSK_KEYBOARD_ENTRIES + 1]; // used for marking invalid chars
|
||||
bool has_error = false; // true when an invalid char is detected
|
||||
|
||||
if (StrEmpty(_keyboard_opt[0])) {
|
||||
GetString(keyboard[0], STR_OSK_KEYBOARD_LAYOUT, lastof(keyboard[0]));
|
||||
} else {
|
||||
strncpy(keyboard[0], _keyboard_opt[0], lengthof(keyboard[0]));
|
||||
}
|
||||
|
||||
if (StrEmpty(_keyboard_opt[1])) {
|
||||
GetString(keyboard[1], STR_OSK_KEYBOARD_LAYOUT_CAPS, lastof(keyboard[1]));
|
||||
} else {
|
||||
strncpy(keyboard[0], _keyboard_opt[0], lengthof(keyboard[1]));
|
||||
}
|
||||
|
||||
for (uint j = 0; j < 2; j++) {
|
||||
const char *kbd = keyboard[j];
|
||||
for (uint i = 0; i < OSK_KEYBOARD_ENTRIES; i++) {
|
||||
_keyboard[j][i] = Utf8Consume(&kbd);
|
||||
|
||||
if (IsPrintable(_keyboard[j][i])) {
|
||||
errormark[j][i] = ' ';
|
||||
} else {
|
||||
has_error = true;
|
||||
errormark[j][i] = '^';
|
||||
_keyboard[j][i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_error) {
|
||||
ShowInfoF("The keyboard layout you selected contains invalid chars. Please check those chars marked with ^.");
|
||||
ShowInfoF("Normal keyboard: %s", keyboard[0]);
|
||||
ShowInfoF(" %s", errormark[0]);
|
||||
ShowInfoF("Caps Lock: %s", keyboard[1]);
|
||||
ShowInfoF(" %s", errormark[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the osk associated with a given textbox
|
||||
* @param parent pointer to the Window where this keyboard originated from
|
||||
* @param q querystr_d pointer to the query string of the parent, which is
|
||||
* shared for both windows
|
||||
* @param button widget number of parent's textbox
|
||||
* @param cancel widget number of parent's cancel button (0 if cancel events
|
||||
* should not be passed)
|
||||
* @param ok widget number of parent's ok button (0 if ok events should not
|
||||
* be passed)
|
||||
*/
|
||||
void ShowOnScreenKeyboard(Window *parent, querystr_d *q, int button, int cancel, int ok)
|
||||
{
|
||||
DeleteWindowById(WC_OSK, 0);
|
||||
|
||||
Window *w = AllocateWindowDesc(&_osk_desc);
|
||||
|
||||
w->parent = parent;
|
||||
assert(parent != NULL);
|
||||
|
||||
if (parent->widget[button].data != 0) q->caption = parent->widget[button].data;
|
||||
|
||||
WP(w, osk_d).qs = q;
|
||||
WP(w, osk_d).text_btn = button;
|
||||
WP(w, osk_d).cancel_btn = cancel;
|
||||
WP(w, osk_d).ok_btn = ok;
|
||||
WP(w, osk_d).text = &q->text;
|
||||
|
||||
GetKeyboardLayout();
|
||||
|
||||
/* make a copy in case we need to reset later */
|
||||
strcpy(_orig_str_buf, WP(w, osk_d).qs->text.buf);
|
||||
WP(w, osk_d).orig = _orig_str_buf;
|
||||
}
|
|
@ -49,6 +49,7 @@
|
|||
#endif
|
||||
#include "spritecache.h"
|
||||
#include "transparency.h"
|
||||
#include "textbuf_gui.h"
|
||||
#include "string_func.h"
|
||||
#include "gui.h"
|
||||
#include "town.h"
|
||||
|
@ -1295,6 +1296,8 @@ static const SettingDescGlobVarList _misc_settings[] = {
|
|||
SDTG_VAR("player_face", SLE_UINT32, S, 0, _player_face, 0,0,0xFFFFFFFF,0, STR_NULL, NULL),
|
||||
SDTG_VAR("transparency_options", SLE_UINT, S, 0, _transparency_opt, 0,0,0x1FF,0, STR_NULL, NULL),
|
||||
SDTG_VAR("transparency_locks", SLE_UINT, S, 0, _transparency_lock, 0,0,0x1FF,0, STR_NULL, NULL),
|
||||
SDTG_STR("keyboard", SLE_STRB, S, 0, _keyboard_opt[0], NULL, STR_NULL, NULL),
|
||||
SDTG_STR("keyboard_caps", SLE_STRB, S, 0, _keyboard_opt[1], NULL, STR_NULL, NULL),
|
||||
SDTG_END()
|
||||
};
|
||||
|
||||
|
|
|
@ -164,8 +164,6 @@ struct editsign_d : querystr_d {
|
|||
SignID cur_sign;
|
||||
};
|
||||
|
||||
static char _edit_str_buf[64];
|
||||
|
||||
enum QueryEditSignWidgets {
|
||||
QUERY_EDIT_SIGN_WIDGET_TEXT = 3,
|
||||
QUERY_EDIT_SIGN_WIDGET_OK,
|
||||
|
@ -249,6 +247,10 @@ static void QuerySignEditWndProc(Window *w, WindowEvent *e)
|
|||
UpdateSignEditWindow(w, si);
|
||||
break;
|
||||
|
||||
case QUERY_EDIT_SIGN_WIDGET_TEXT:
|
||||
ShowOnScreenKeyboard(w, qs, e->we.click.widget, QUERY_EDIT_SIGN_WIDGET_CANCEL, QUERY_EDIT_SIGN_WIDGET_OK);
|
||||
break;
|
||||
|
||||
case QUERY_EDIT_SIGN_WIDGET_DELETE:
|
||||
/* Only need to set the buffer to null, the rest is handled as the OK button */
|
||||
DeleteTextBufferAll(&qs->text);
|
||||
|
@ -287,16 +289,16 @@ static void QuerySignEditWndProc(Window *w, WindowEvent *e)
|
|||
}
|
||||
|
||||
static const Widget _query_sign_edit_widgets[] = {
|
||||
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, RESIZE_NONE, 14, 11, 259, 0, 13, STR_012D, STR_NULL },
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 0, 259, 14, 29, STR_NULL, STR_NULL },
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 2, 257, 16, 27, STR_NULL, STR_NULL }, // Text field
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 0, 60, 30, 41, STR_012F_OK, STR_NULL },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 61, 120, 30, 41, STR_012E_CANCEL, STR_NULL },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 121, 180, 30, 41, STR_0290_DELETE, STR_NULL },
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 181, 237, 30, 41, STR_NULL, STR_NULL },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 238, 248, 30, 41, STR_6819, STR_PREVIOUS_SIGN_TOOLTIP },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 249, 259, 30, 41, STR_681A, STR_NEXT_SIGN_TOOLTIP },
|
||||
{ WWT_CLOSEBOX, RESIZE_NONE, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW},
|
||||
{ WWT_CAPTION, RESIZE_NONE, 14, 11, 259, 0, 13, STR_012D, STR_NULL },
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 0, 259, 14, 29, STR_NULL, STR_NULL },
|
||||
{ WWT_EDITBOX, RESIZE_NONE, 14, 2, 257, 16, 27, STR_SIGN_OSKTITLE, STR_NULL }, // Text field
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 0, 60, 30, 41, STR_012F_OK, STR_NULL },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 61, 120, 30, 41, STR_012E_CANCEL, STR_NULL },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 121, 180, 30, 41, STR_0290_DELETE, STR_NULL },
|
||||
{ WWT_PANEL, RESIZE_NONE, 14, 181, 237, 30, 41, STR_NULL, STR_NULL },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 238, 248, 30, 41, STR_6819, STR_PREVIOUS_SIGN_TOOLTIP },
|
||||
{ WWT_TEXTBTN, RESIZE_NONE, 14, 249, 259, 30, 41, STR_681A, STR_NEXT_SIGN_TOOLTIP },
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ static FileList files_dos = {
|
|||
{ "TRGT.GRF", {0xfc, 0xde, 0x1d, 0x7e, 0x8a, 0x74, 0x19, 0x7d, 0x72, 0xa6, 0x26, 0x95, 0x88, 0x4b, 0x90, 0x9e} }
|
||||
},
|
||||
{ "SAMPLE.CAT", {0x42, 0x2e, 0xa3, 0xdd, 0x07, 0x4d, 0x28, 0x59, 0xbb, 0x51, 0x63, 0x9a, 0x6e, 0x0e, 0x85, 0xda} },
|
||||
{ "OPENTTDD.GRF", {0x61, 0x47, 0x47, 0x15, 0xa9, 0x06, 0x10, 0xb6, 0xed, 0x1f, 0xe1, 0x4d, 0x03, 0x6c, 0xa8, 0x02} }
|
||||
{ "OPENTTDD.GRF", {0x32, 0xb4, 0xec, 0x0c, 0xc9, 0x5d, 0xa0, 0x14, 0x3a, 0x2f, 0xe1, 0xd4, 0x20, 0x63, 0x49, 0x74} }
|
||||
};
|
||||
|
||||
|
||||
|
@ -47,5 +47,5 @@ static FileList files_win = {
|
|||
{ "TRGTR.GRF", {0xde, 0x53, 0x65, 0x05, 0x17, 0xfe, 0x66, 0x1c, 0xea, 0xa3, 0x13, 0x8c, 0x6e, 0xdb, 0x0e, 0xb8} }
|
||||
},
|
||||
{ "SAMPLE.CAT", {0x92, 0x12, 0xe8, 0x1e, 0x72, 0xba, 0xdd, 0x4b, 0xbe, 0x1e, 0xae, 0xae, 0x66, 0x45, 0x8e, 0x10} },
|
||||
{ "OPENTTDW.GRF", {0xc8, 0xc0, 0x01, 0x73, 0x60, 0xa7, 0x5e, 0xb1, 0xef, 0x9b, 0xe6, 0xba, 0xad, 0x3a, 0x7b, 0xd4} }
|
||||
{ "OPENTTDW.GRF", {0xc6, 0x1f, 0xcc, 0x4e, 0x83, 0x98, 0x5b, 0x67, 0xb7, 0x03, 0xa0, 0x31, 0x39, 0x2e, 0x75, 0xfc} }
|
||||
};
|
||||
|
|
|
@ -49,7 +49,7 @@ enum Sprites {
|
|||
|
||||
/* Extra graphic spritenumbers */
|
||||
SPR_OPENTTD_BASE = 4896,
|
||||
OPENTTD_SPRITE_COUNT = 138,
|
||||
OPENTTD_SPRITE_COUNT = 144,
|
||||
|
||||
/* Halftile-selection sprites */
|
||||
SPR_HALFTILE_SELECTION_FLAT = SPR_OPENTTD_BASE,
|
||||
|
@ -73,6 +73,14 @@ enum Sprites {
|
|||
SPR_PIN_UP = SPR_OPENTTD_BASE + 51, // pin icon
|
||||
SPR_PIN_DOWN = SPR_OPENTTD_BASE + 52,
|
||||
|
||||
/* on screen keyboard icons */
|
||||
SPR_OSK_LEFT = SPR_OPENTTD_BASE + 138,
|
||||
SPR_OSK_RIGHT = SPR_OPENTTD_BASE + 139,
|
||||
SPR_OSK_CAPS = SPR_OPENTTD_BASE + 140,
|
||||
SPR_OSK_SHIFT = SPR_OPENTTD_BASE + 141,
|
||||
SPR_OSK_BACKSPACE = SPR_OPENTTD_BASE + 142,
|
||||
SPR_OSK_SPECIAL = SPR_OPENTTD_BASE + 143,
|
||||
|
||||
/* Clone vehicles stuff */
|
||||
SPR_CLONE_TRAIN = SPR_OPENTTD_BASE + 106,
|
||||
SPR_CLONE_ROADVEH = SPR_OPENTTD_BASE + 107,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "window_type.h"
|
||||
#include "string_type.h"
|
||||
#include "strings_type.h"
|
||||
|
||||
struct Textbuf {
|
||||
char *buf; ///< buffer in which text is saved
|
||||
|
@ -26,6 +27,8 @@ struct querystr_d {
|
|||
};
|
||||
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(querystr_d));
|
||||
|
||||
extern char _edit_str_buf[64];
|
||||
extern char _orig_str_buf[lengthof(_edit_str_buf)];
|
||||
|
||||
void DrawEditBox(Window *w, querystr_d *string, int wid);
|
||||
void HandleEditBox(Window *w, querystr_d *string, int wid);
|
||||
|
@ -43,4 +46,16 @@ void UpdateTextBufferSize(Textbuf *tb);
|
|||
void ShowQueryString(StringID str, StringID caption, uint maxlen, uint maxwidth, Window *parent, CharSetFilter afilter);
|
||||
void ShowQuery(StringID caption, StringID message, Window *w, void (*callback)(Window*, bool));
|
||||
|
||||
/** The number of 'characters' on the on-screen keyboard. */
|
||||
static const uint OSK_KEYBOARD_ENTRIES = 50;
|
||||
|
||||
/**
|
||||
* The number of characters has to be OSK_KEYBOARD_ENTRIES. However, these
|
||||
* have to be UTF-8 encoded, which means up to 4 bytes per character.
|
||||
* Furthermore the string needs to be '\0'-terminated.
|
||||
*/
|
||||
extern char _keyboard_opt[2][OSK_KEYBOARD_ENTRIES * 4 + 1];
|
||||
|
||||
void ShowOnScreenKeyboard(Window *parent, querystr_d *q, int button, int cancel, int ok);
|
||||
|
||||
#endif /* TEXTBUF_GUI_H */
|
||||
|
|
|
@ -221,6 +221,10 @@ void DrawWindowWidgets(const Window *w)
|
|||
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
|
||||
break;
|
||||
|
||||
case WWT_EDITBOX:
|
||||
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, FR_LOWERED | FR_DARKENED);
|
||||
break;
|
||||
|
||||
case WWT_TEXTBTN:
|
||||
case WWT_TEXTBTN_2:
|
||||
DrawFrameRect(r.left, r.top, r.right, r.bottom, wi->color, (clicked) ? FR_LOWERED : FR_NONE);
|
||||
|
|
|
@ -499,6 +499,7 @@ enum WindowWidgetTypes {
|
|||
WWT_CLOSEBOX,
|
||||
WWT_DROPDOWN, ///< Raised drop down list (regular)
|
||||
WWT_DROPDOWNIN, ///< Inset drop down list (used on game options only)
|
||||
WWT_EDITBOX, ///< a textbox for typing (don't forget to call ShowOnScreenKeyboard() when clicked)
|
||||
WWT_LAST, ///< Last Item. use WIDGETS_END to fill up padding!!
|
||||
|
||||
WWT_MASK = 0x1F,
|
||||
|
|
|
@ -90,6 +90,7 @@ enum WindowClass {
|
|||
WC_VEHICLE_TIMETABLE,
|
||||
WC_BUILD_SIGNAL,
|
||||
WC_COMPANY_PASSWORD_WINDOW,
|
||||
WC_OSK,
|
||||
};
|
||||
|
||||
struct Window;
|
||||
|
|
Loading…
Reference in New Issue