Add a new API for converting between interface_key and string characters.

It's necessary now that the simple linear arrangement is broken.
develop
Alexander Gavrilov 2014-08-11 14:23:19 +04:00
parent 002bd5240b
commit 2471c4a68e
8 changed files with 83 additions and 23 deletions

@ -1591,6 +1591,17 @@ Basic painting functions:
Returns the string that should be used to represent the given
logical keybinding on the screen in texts like "press Key to ...".
* ``dfhack.screen.keyToChar(key)``
Returns the integer character code of the string input
character represented by the given logical keybinding,
or *nil* if not a string input key.
* ``dfhack.screen.charToKey(charcode)``
Returns the keybinding representing the given string input
character, or *nil* if impossible.
The "pen" argument used by functions above may be represented by
a table with the following possible fields:

@ -1924,6 +1924,28 @@ static int screen_doSimulateInput(lua_State *L)
return 0;
}
static int screen_keyToChar(lua_State *L)
{
auto keycode = (df::interface_key)luaL_checkint(L, 1);
int charcode = Screen::keyToChar(keycode);
if (charcode >= 0)
lua_pushinteger(L, charcode);
else
lua_pushnil(L);
return 1;
}
static int screen_charToKey(lua_State *L)
{
auto charcode = (char)luaL_checkint(L, 1);
df::interface_key keycode = Screen::charToKey(charcode);
if (keycode)
lua_pushinteger(L, keycode);
else
lua_pushnil(L);
return 1;
}
}
static const luaL_Reg dfhack_screen_funcs[] = {
@ -1938,6 +1960,8 @@ static const luaL_Reg dfhack_screen_funcs[] = {
{ "dismiss", screen_dismiss },
{ "isDismissed", screen_isDismissed },
{ "_doSimulateInput", screen_doSimulateInput },
{ "keyToChar", screen_keyToChar },
{ "charToKey", screen_charToKey },
{ NULL, NULL }
};

@ -195,6 +195,11 @@ namespace DFHack
/// Retrieve the string representation of the bound key.
DFHACK_EXPORT std::string getKeyDisplay(df::interface_key key);
/// Return the character represented by this key, or -1
DFHACK_EXPORT int keyToChar(df::interface_key key);
/// Return the key code matching this character, or NONE
DFHACK_EXPORT df::interface_key charToKey(char code);
/// A painter class that implements a clipping area and cursor/pen state
struct DFHACK_EXPORT Painter : ViewRect {
df::coord2d gcursor;

@ -413,6 +413,29 @@ string Screen::getKeyDisplay(df::interface_key key)
return "?";
}
int Screen::keyToChar(df::interface_key key)
{
if (key < interface_key::STRING_A000 ||
key > interface_key::STRING_A255)
return -1;
if (key < interface_key::STRING_A128)
return key - interface_key::STRING_A000;
return key - interface_key::STRING_A128 + 128;
}
df::interface_key Screen::charToKey(char code)
{
int val = (unsigned char)code;
if (val < 127)
return df::interface_key(interface_key::STRING_A000 + val);
else if (val == 127)
return interface_key::NONE;
else
return df::interface_key(interface_key::STRING_A128 + (val-128));
}
/*
* Base DFHack viewscreen.
*/
@ -654,10 +677,10 @@ int dfhack_lua_viewscreen::do_input(lua_State *L)
lua_pushboolean(L, true);
lua_rawset(L, -3);
if (key >= interface_key::STRING_A000 &&
key <= interface_key::STRING_A255)
int charval = Screen::keyToChar(key);
if (charval >= 0)
{
lua_pushinteger(L, key - interface_key::STRING_A000);
lua_pushinteger(L, charval);
lua_setfield(L, -2, "_STRING");
}
}

@ -238,10 +238,10 @@ void viewscreen_commandpromptst::feed(std::set<df::interface_key> *events)
cursor_pos = entry.size();
continue;
}
if (key >= interface_key::STRING_A000 &&
key <= interface_key::STRING_A255)
int charcode = Screen::keyToChar(key);
if (charcode > 0)
{
entry.insert(cursor_pos, 1, char(key - interface_key::STRING_A000));
entry.insert(cursor_pos, 1, char(charcode));
cursor_pos++;
set_entry(entry);
return;

@ -130,7 +130,8 @@ public:
this->cursor_pos = get_viewscreen_cursor();
this->primary_list = get_primary_list();
this->select_key = get_search_select_key();
select_token = (df::interface_key) (ascii_to_enum_offset + select_key);
select_token = Screen::charToKey(select_key);
shift_select_token = Screen::charToKey(select_key + 'A' - 'a');
valid = true;
do_post_init();
}
@ -185,10 +186,11 @@ public:
return false;
}
df::interface_key last_token = *input->rbegin();
if (last_token >= interface_key::STRING_A032 && last_token <= interface_key::STRING_A126)
int charcode = Screen::keyToChar(last_token);
if (charcode >= 32 && charcode <= 126)
{
// Standard character
search_string += last_token - ascii_to_enum_offset;
search_string += char(charcode);
do_search();
}
else if (last_token == interface_key::STRING_A000)
@ -219,7 +221,7 @@ public:
// Hotkey pressed, enter typing mode
start_entry_mode();
}
else if (input->count((df::interface_key) (select_token + shift_offset)))
else if (input->count(shift_select_token))
{
// Shift + Hotkey pressed, clear query
clear_search();
@ -246,7 +248,7 @@ protected:
virtual int32_t *get_viewscreen_cursor() = 0;
virtual vector<T> *get_primary_list() = 0;
search_generic() : ascii_to_enum_offset(interface_key::STRING_A048 - '0'), shift_offset('A' - 'a')
search_generic()
{
reset_all();
}
@ -412,9 +414,7 @@ private:
bool entry_mode;
df::interface_key select_token;
const int ascii_to_enum_offset;
const int shift_offset;
df::interface_key shift_select_token;
};
template <class S, class T> search_generic<S, T> *search_generic<S, T> ::lock = NULL;

@ -143,8 +143,6 @@ void OutputToggleString(int &x, int &y, const char *text, const char *hotkey, bo
OutputString(COLOR_GREY, x, y, "Off", newline, left_margin);
}
const int ascii_to_enum_offset = interface_key::STRING_A048 - '0';
inline string int_to_string(const int n)
{
return static_cast<ostringstream*>( &(ostringstream() << n) )->str();
@ -792,11 +790,11 @@ public:
{
// Search query typing mode always on
df::interface_key last_token = *input->rbegin();
if ((last_token >= interface_key::STRING_A096 && last_token <= interface_key::STRING_A123) ||
last_token == interface_key::STRING_A032)
int charcode = Screen::keyToChar(last_token);
if ((charcode >= 96 && charcode <= 123) || charcode == 32)
{
// Standard character
search_string += last_token - ascii_to_enum_offset;
search_string += char(charcode);
filterDisplay();
centerSelection();
}

@ -4087,8 +4087,6 @@ using df::global::ui_building_assign_items;
using df::global::ui_building_in_assign;
static const int ascii_to_enum_offset = interface_key::STRING_A048 - '0';
void OutputString(int8_t color, int &x, int y, const std::string &text)
{
Screen::paintString(Screen::Pen(' ', color, 0), x, y, text);
@ -4241,10 +4239,11 @@ public:
}
df::interface_key last_token = *input->rbegin();
if (last_token >= interface_key::STRING_A032 && last_token <= interface_key::STRING_A126)
int charcode = Screen::keyToChar(last_token);
if (charcode >= 32 && charcode <= 126)
{
// Standard character
search_string += last_token - ascii_to_enum_offset;
search_string += char(charcode);
apply_filters();
}
else if (last_token == interface_key::STRING_A000)