1 module unde.keybar.settings; 2 3 import derelict.sdl2.sdl; 4 import derelict.sdl2.ttf; 5 import derelict.sdl2.image; 6 7 import unde.global_state; 8 import unde.font; 9 import unde.keybar.lib; 10 import unde.guitk.lib; 11 import unde.guitk.background; 12 import unde.guitk.label; 13 import unde.guitk.list; 14 import unde.guitk.textarea; 15 import unde.translations.lib; 16 import unde.lib; 17 18 import std.stdio; 19 import std..string; 20 import std.math; 21 import std.range.primitives; 22 import std.file; 23 import std.algorithm.searching; 24 25 version(Windows) 26 { 27 import berkeleydb.all: ssize_t; 28 } 29 30 ssize_t 31 get_pos_of_layout(string[] names, string name, ssize_t p = 0) 32 { 33 if (names.length == 0) return -1; 34 35 if (names[$/2] == name) 36 { 37 return p + names.length/2; 38 } 39 if (name < names[$/2]) 40 { 41 return get_pos_of_layout(names[0..$/2], name, p); 42 } 43 else 44 return get_pos_of_layout(names[$/2+1..$], name, p + names.length/2 + 1); 45 } 46 47 UIPage create_keybar_settings_ui(GlobalState gs) 48 { 49 UIPage page = new UIPage(); 50 51 page.add_entry(gs, new Background(page, gs)); 52 page.add_entry(gs, new Label(page, gs, _("Choose one or more keyboard layouts:"), 53 15, 15)); 54 auto filter_label = new Label(page, gs, _("Filter:"), 15, 60); 55 page.add_entry(gs, filter_label); 56 SDL_Rect filter_rect; 57 filter_rect.x = filter_label.rect.x + filter_label.rect.w + 5; 58 filter_rect.y = 60; 59 filter_rect.w = gs.screen.w/2 - 15 - filter_rect.x; 60 filter_rect.h = 30; 61 auto filter_textarea = new TextArea(page, filter_rect); 62 63 SDL_Rect layouts_rect; 64 layouts_rect.x = 15; 65 layouts_rect.y = 105; 66 layouts_rect.w = gs.screen.w/2 - 15 - layouts_rect.x; 67 layouts_rect.h = cast(int)(gs.screen.h*0.83 - 15 - layouts_rect.y); 68 auto layouts_list = new List(page, layouts_rect, gs.keybar.layout_names); 69 70 string[] selected_layouts; 71 foreach (layout_mode; gs.keybar.layout_modes) 72 { 73 string layout_string = layout_mode.name ~ " - " ~ layout_mode.short_name; 74 selected_layouts ~= layout_string; 75 ssize_t pos = get_pos_of_layout(gs.keybar.layout_names, layout_string); 76 layouts_list.selected[pos] = true; 77 } 78 79 filter_textarea.on_change = (GlobalState gs) { 80 layouts_list.filter = filter_textarea.text; 81 }; 82 83 page.add_entry(gs, filter_textarea); 84 page.add_entry(gs, layouts_list); 85 86 page.add_entry(gs, new Label(page, gs, _("You have chosen:"), 87 gs.screen.w/2 + 15, 15)); 88 89 SDL_Rect chosen_rect; 90 chosen_rect.x = gs.screen.w/2 + 15; 91 chosen_rect.y = 60; 92 chosen_rect.w = gs.screen.w/2 - 30; 93 chosen_rect.h = cast(int)(gs.screen.h*0.83/2 - 15 - chosen_rect.y); 94 95 auto chosen_list = new List(page, chosen_rect, selected_layouts, 1); 96 97 chosen_list.selected[gs.keybar.mode] = 1; 98 99 layouts_list.on_select = (GlobalState gs, ssize_t pos) { 100 chosen_list.list ~= layouts_list.list[pos]; 101 ssize_t short_pos = layouts_list.list[pos].lastIndexOf(" - "); 102 string short_name = layouts_list.list[pos][short_pos+3..$]; 103 gs.keybar.layout_modes ~= &gs.keybar.layouts[short_name]; 104 105 save_keybar_settings(gs); 106 }; 107 108 layouts_list.on_deselect = (GlobalState gs, ssize_t pos) { 109 auto found = chosen_list.list.find(layouts_list.list[pos]); 110 if (found.length > 0) 111 { 112 ssize_t cpos = chosen_list.list.length - found.length; 113 chosen_list.list = chosen_list.list[0..cpos] ~ chosen_list.list[cpos+1..$]; 114 gs.keybar.layout_modes = gs.keybar.layout_modes[0..cpos] ~ gs.keybar.layout_modes[cpos+1..$]; 115 if (gs.keybar.mode >= cpos) 116 gs.keybar.mode--; 117 chosen_list.selected.clear(); 118 chosen_list.selected[gs.keybar.mode] = 1; 119 120 save_keybar_settings(gs); 121 } 122 }; 123 124 chosen_list.pre_draw = (GlobalState gs) 125 { 126 chosen_list.selected.clear(); 127 chosen_list.selected[gs.keybar.mode] = 1; 128 }; 129 130 page.add_entry(gs, chosen_list); 131 132 page.add_entry(gs, new Label(page, gs, _("Choose modifiers to change layouts:"), 133 gs.screen.w/2 + 15, cast(int)(gs.screen.h*0.83/2 + 15))); 134 135 SDL_Rect modifiers_rect; 136 modifiers_rect.x = gs.screen.w/2 + 15; 137 modifiers_rect.y = cast(int)(gs.screen.h*0.83/2 + 60); 138 modifiers_rect.w = gs.screen.w/2 - 30; 139 modifiers_rect.h = cast(int)(gs.screen.h*0.83 - 15 - modifiers_rect.y); 140 141 auto modifiers_list = new List(page, modifiers_rect, gs.keybar.layout_changer_names, 1); 142 143 auto found = gs.keybar.layout_changer_values.find(gs.keybar.changer); 144 if (found.length > 0) 145 { 146 ssize_t cpos = gs.keybar.layout_changer_values.length - found.length; 147 modifiers_list.selected[cpos] = true; 148 } 149 150 modifiers_list.on_select = (GlobalState gs, ssize_t pos) { 151 gs.keybar.changer = gs.keybar.layout_changer_values[pos]; 152 153 save_keybar_settings(gs); 154 }; 155 156 page.add_entry(gs, modifiers_list); 157 158 page.add_entry(gs, new Label(page, gs, _("Try text input here:"), 159 15, cast(int)(gs.screen.h*0.83 + 15))); 160 161 SDL_Rect test_rect; 162 test_rect.x = 15; 163 test_rect.y = cast(int)(gs.screen.h*0.83 + 60); 164 test_rect.w = gs.screen.w - 30; 165 test_rect.h = cast(int)(gs.screen.h*0.17 - 75); 166 auto test_textarea = new TextArea(page, test_rect); 167 page.add_entry(gs, test_textarea); 168 169 if (gs.keybar.keybar_settings_needed) 170 page.show = true; 171 172 return page; 173 } 174 175 void 176 turn_on_keybar_settings(GlobalState gs) 177 { 178 gs.uipages["keybar_settings"].show = true; 179 }