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 }