From ea76b6988ccafaa6a4d4ed90f2489d0e49e1f180 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sat, 5 Sep 2015 09:32:30 -0400 Subject: Imported Upstream version 0.40.24 --- g_src/KeybindingScreen.cpp | 409 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100755 g_src/KeybindingScreen.cpp (limited to 'g_src/KeybindingScreen.cpp') diff --git a/g_src/KeybindingScreen.cpp b/g_src/KeybindingScreen.cpp new file mode 100755 index 0000000..02cbd81 --- /dev/null +++ b/g_src/KeybindingScreen.cpp @@ -0,0 +1,409 @@ +#ifdef __APPLE__ +# include "osx_messagebox.h" +#elif defined(unix) +# include +#endif + +#include "GL/glew.h" + +#ifdef WIN32 + +#ifndef INTEGER_TYPES + #define INTEGER_TYPES + typedef short int16_t; + typedef int int32_t; + typedef long long int64_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; +#endif + +typedef int32_t VIndex; +typedef int32_t Ordinal; + +#endif + +#include "graphics.h" +#include "init.h" +#include "keybindings.h" +#include "KeybindingScreen.h" + +#include +#include +#include +#include +#include + +using namespace std; + +struct BindingGroup { + string name; + InterfaceKey start, end; +}; + +const BindingGroup groups[] = { + {"General" , INTERFACEKEY_NONE, WORLDKEY_START-1}, + {"World" , WORLDKEY_START, ADVENTURERKEY_START-1}, + {"Adventurer" , ADVENTURERKEY_START, EMBARKKEY_START-1}, + {"Dwarf mode" , DWARFMAINKEY_START, MILITIAKEY_START-1}, + {"Embark" , EMBARKKEY_START, BUILDINGKEY_START-1}, + {"Building" , BUILDINGKEY_START, WORKSHOPKEY_START-1}, + {"Workshop" , WORKSHOPKEY_START, PILEZONEKEY_START-1}, + {"Pilezone" , PILEZONEKEY_START, STOCKORDERKEY_START-1}, + {"Stockorder" , STOCKORDERKEY_START, DWARFMAINKEY_START-1}, + {"Militia" , MILITIAKEY_START, INTERFACEKEY_STRING_A000-1}, + {"Text entry" , INTERFACEKEY_STRING_A000, INTERFACEKEY_STRING_A255} +}; + +KeybindingScreen::KeybindingScreen() { + gview.addscreen(this, INTERFACE_PUSH_AT_BACK, NULL); // HACK + mode = mode_main; + + main.add("Macros", sel_macros); + for (int i = 0; i < ARRSZ(groups); i++) + main.set(i+2, groups[i].name, sel_first_group + i); + main.set(ARRSZ(groups)+3, "Save and exit", sel_save_exit); + main.add("Exit, discard changes when DF quits", sel_just_exit); + enabler.flag |= ENABLERFLAG_RENDER; +} + +void KeybindingScreen::feed(set &input) { + enabler.flag|=ENABLERFLAG_RENDER; + if (input.count(INTERFACEKEY_KEYBINDING_COMPLETE)) { + list keys = enabler.getRegisteredKey(); + if (keys.size() == 0) { + puts("No keys registered ?!"); + mode = mode_keyR; + } else { + keyRegister.clear(); + list keys = enabler.getRegisteredKey(); + for (list::iterator it = keys.begin(); it != keys.end(); ++it) { + string display; + switch (it->type) { + case type_button: display = "Mouse button: "; break; + case type_key: display = "By position: "; break; + case type_unicode: display = "By letter: "; break; + } + keyRegister.add(display + it->display, it->type); + } + } + } else if (input.count(INTERFACEKEY_STANDARDSCROLL_PAGEUP) || + input.count(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN) || + input.count(INTERFACEKEY_STANDARDSCROLL_UP) || + input.count(INTERFACEKEY_STANDARDSCROLL_DOWN)) { + switch (mode) { + case mode_main: main.feed(input); break; + case mode_keyL: keyL.feed(input); reset_keyR(); break; + case mode_keyR: keyR.feed(input); break; + case mode_macro: macro.feed(input); break; + case mode_register: keyRegister.feed(input); break; + } + } else if (mode == mode_keyL && input.count(INTERFACEKEY_STANDARDSCROLL_RIGHT)) + mode = mode_keyR; + else if (mode == mode_main && input.count(INTERFACEKEY_STANDARDSCROLL_RIGHT)) { + if (main.get_selection() == sel_macros) enter_macros(); + if (main.get_selection() >= sel_first_group) + enter_key(main.get_selection() - sel_first_group); + } else if (mode == mode_keyR && input.count(INTERFACEKEY_STANDARDSCROLL_LEFT)) + mode = mode_keyL; + else if ((mode == mode_keyL || mode == mode_macro) && input.count(INTERFACEKEY_STANDARDSCROLL_LEFT)) + mode = mode_main; + else if (input.count(INTERFACEKEY_STRING_A000)) { // Backspace: Delete something. + switch (mode) { + case mode_macro: + if (macro.get_selection() != "") { + enabler.delete_macro(macro.get_selection()); + macro.del_selection(); + if (!macro.size()) + macro.add("No macros!", ""); + } + break; + case mode_keyR: + keyR_selector sel = keyR.get_selection(); + if (sel.sel == sel_event) { + enabler.remove_key(keyL.get_selection(), sel.event); + reset_keyR(); + } + break; + } + } else if (input.count(INTERFACEKEY_SELECT)) { + switch (mode) { + case mode_main: + if (main.get_selection() == sel_macros) { // Macros + enter_macros(); + } else if (main.get_selection() == sel_save_exit) { // Save and exit + enabler.save_keybindings(); + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else if (main.get_selection() == sel_just_exit) { // Just exit + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else { // Some key-binding group + enter_key(main.get_selection() - sel_first_group); + } + break; + case mode_keyR: { + InterfaceKey key = keyL.get_selection(); + switch (keyR.get_selection().sel) { + case sel_add: + enabler.register_key(); + mode = mode_register; + break; + case sel_rep_none: + enabler.key_repeat(key, REPEAT_NOT); + reset_keyR(); + break; + case sel_rep_slow: + enabler.key_repeat(key, REPEAT_SLOW); + reset_keyR(); + break; + case sel_rep_fast: + enabler.key_repeat(key, REPEAT_FAST); + reset_keyR(); + break; + }} + break; + case mode_register: + enabler.bindRegisteredKey(keyRegister.get_selection(), keyL.get_selection()); + mode = mode_keyR; + reset_keyR(); + break; + } + } else if (input.count(INTERFACEKEY_LEAVESCREEN) || input.count(INTERFACEKEY_OPTIONS)) { + if (mode == mode_register) + mode = mode_keyR; + else + mode = mode_main; + } +} + +void KeybindingScreen::logic() { + if (mode == mode_register) + enabler.flag|=ENABLERFLAG_RENDER; +} + +void KeybindingScreen::enter_macros() { + mode = mode_macro; + macro.clear(); + list macros = enabler.list_macros(); + for (list::iterator it = macros.begin(); it != macros.end(); ++it) + macro.add(*it, *it); + if (!macros.size()) + macro.add("No macros!", ""); +} + +void KeybindingScreen::enter_key(int group) { + mode = mode_keyL; + keyL.clear(); + for (InterfaceKey i = groups[group].start; i <= groups[group].end; i++) { + if (i != INTERFACEKEY_NONE) + keyL.add(enabler.GetBindingTextDisplay(i), i); + } + reset_keyR(); +} + +void KeybindingScreen::reset_keyR() { + int lastpos = keyR.get_pos(); + keyR.clear(); + struct keyR_selector sel; + sel.sel = sel_add; + keyR.add("Add binding", sel); + InterfaceKey key = keyL.get_selection(); + list matchers = enabler.list_keys(key); + Repeat rep = enabler.key_repeat(key); + sel.sel = sel_rep_none; + keyR.set(2, "Don't repeat", sel); + if (rep == REPEAT_NOT) keyR.set_color(2, 4, 0); + sel.sel = sel_rep_slow; + keyR.set(3, "Delayed repeat", sel); + if (rep == REPEAT_SLOW) keyR.set_color(3, 4, 0); + sel.sel = sel_rep_fast; + keyR.set(4, "Immediate repeat", sel); + if (rep == REPEAT_FAST) keyR.set_color(4, 4, 0); + int i = 6; + for (list::iterator it = matchers.begin(); it != matchers.end(); ++it, ++i) { + ostringstream desc; + switch (it->type) { + case type_unicode: + desc << "By letter: "; + if (it->unicode < 256 && isgraph(it->unicode)) // Is it printable? + desc << (char)it->unicode; + else + desc << "U+" << hex << uppercase << it->unicode; + break; + case type_key: + desc << "By position: " << translate_mod(it->mod) << sdlNames.left[it->key]; + break; + case type_button: + desc << "Mouse: " << (int)it->button; + break; + } + sel.sel = sel_event; + sel.event = *it; + keyR.set(i, desc.str(), sel); + } + keyR.set_pos(lastpos); +} + +void KeybindingScreen::render_macro() { + drawborder("Macros"); + gps.locate(3, 3); + gps.changecolor(4,0,1); + gps.addst("Select a macro, then press " + enabler.GetKeyDisplay(INTERFACEKEY_STRING_A000) + " to delete."); + macro.render(6, init.display.grid_x-2, 5, init.display.grid_y-2); +} + +void KeybindingScreen::render_key() { + if (enabler.is_registering()) { + gps.changecolor(4,0,1); + drawborder("Keybinding - currently registering new key"); + } else + drawborder("Keybinding"); + gps.locate(3, 6); + gps.changecolor(4,0,1); + gps.addst("Select a binding, then press " + enabler.GetKeyDisplay(INTERFACEKEY_STRING_A000) + " to delete."); + keyL.render(6, init.display.grid_x/2 - 1, 5, init.display.grid_y-2); + if (mode == mode_keyL || mode == mode_register) + keyR.bleach(true); + else + keyR.bleach(false); + keyR.render(init.display.grid_x/2 + 1, init.display.grid_x-2, 5, init.display.grid_y-2); +} + +void KeybindingScreen::render_register() { + int x1 = init.display.grid_x / 2 - 20, + x2 = init.display.grid_x / 2 + 20, + y1 = init.display.grid_y / 2 - 1, + y2 = init.display.grid_y / 2 + 1; + if (!enabler.is_registering()) { + y2 = y1 + keyRegister.size() + 1; + } + gps.erasescreen_rect(x1, x2, y1, y2); + gps.changecolor(1,1,1); + for (int x = x1; x <= x2; x++) { + gps.locate(y1, x); gps.addchar(' '); + gps.locate(y2, x); gps.addchar(' '); + } + for (int y = y1 + 1; y < y2; y++) { + gps.locate(y, x1); gps.addchar(' '); + gps.locate(y, x2); gps.addchar(' '); + } + if (enabler.is_registering()) { + gps.changecolor(7,0,1); + gps.locate(y1+1, x1+2); + gps.addst(translate_mod(getModState())); + } else { + keyRegister.render(x1+1, x2-1, y1+1, y2-1); + gps.locate(y2, x1+2); + gps.changecolor(7,1,1); + gps.addst("Select binding, or press " + enabler.GetKeyDisplay(INTERFACEKEY_LEAVESCREEN) + " to abort"); + } +} + +// Render the main menu +void KeybindingScreen::render_main() { + drawborder("Key binding & macro center"); + main.render(6, init.display.grid_x - 3, 3, init.display.grid_y - 4); +} + +void KeybindingScreen::render() { + switch(mode) { + case mode_main: render_main(); break; + case mode_keyL: case mode_keyR: render_key(); break; + case mode_macro: render_macro(); break; + case mode_register: + render_key(); + render_register(); + break; + } +} + +void KeybindingScreen::help() { +} + + +MacroScreenLoad::MacroScreenLoad() { + list macros = enabler.list_macros(); + width = 10; + if (!macros.size()) { + menu.add("No macros!", ""); + height = 1; + } else + height = macros.size(); + + for (list::iterator it = macros.begin(); it != macros.end(); ++it) { + if (it->length() > width) width = it->length(); + menu.add(*it, *it); + } + enabler.flag |= ENABLERFLAG_RENDER; + // render(); + // gps.renewscreen(); +} + +void MacroScreenLoad::feed(set &input) { + enabler.flag|=ENABLERFLAG_RENDER; + if (input.count(INTERFACEKEY_SELECT)) { + string id = menu.get_selection(); + if (id != "") enabler.load_macro(id); + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else if (input.count(INTERFACEKEY_LEAVESCREEN)) { + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else { + menu.feed(input); + } + if (input.count(INTERFACEKEY_OPTIONS)) { + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + } +} + +void MacroScreenLoad::logic() { +} + +void MacroScreenLoad::render() { + if (parent) parent->render(); + const int x1 = MAX(init.display.grid_x/2 - ((width + 2) / 2), 0); + const int x2 = MIN(x1+width+1, init.display.grid_x-1); + const int y1 = MAX(init.display.grid_y/2 - ((height + 2) / 2), 0); + const int y2 = MIN(y1 + height + 1, init.display.grid_y-1); + gps.changecolor(0,3,1); + gps.draw_border(x1, x2, y1, y2); + menu.render(x1+1, x2-1, y1+1, y2-1); + // gps.renewscreen(); +} + +MacroScreenSave::MacroScreenSave() { + enabler.flag |= ENABLERFLAG_RENDER; +} + +void MacroScreenSave::logic() { +} + +void MacroScreenSave::feed(set &input) { + enabler.flag|=ENABLERFLAG_RENDER; + id.feed(input); + if (input.count(INTERFACEKEY_SELECT)) { + string n = id.get_text(); + if (n.length()) + enabler.save_macro(n); + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } + if (input.count(INTERFACEKEY_OPTIONS)) { + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + } +} + +void MacroScreenSave::render() { + if (parent) parent->render(); + const int x1 = 3, + x2 = init.display.grid_x-4, + y1 = init.display.grid_y/2-1, + y2 = init.display.grid_y/2+1; + gps.changecolor(0,3,1); + gps.draw_border(x1, x2, y1, y2); + id.render(x1+1,x2-1,y1+1,y2-1); + // gps.renewscreen(); +} + -- cgit v1.2.3