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 }