style inheritance fixes; it is now possible to load style from the external file...
[chiroptera.git] / egui / dialogs.d
bloba51e37ceea2773322de876f496322b7a416c10e8
1 /* E-Mail Client
2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module egui.dialogs /*is aliced*/;
18 private:
20 import core.time;
22 import arsd.simpledisplay;
24 import iv.alice;
25 import iv.cmdcon;
26 import iv.strex;
27 import iv.utfutil;
28 import iv.vfs;
30 import egfx;
31 import egui.subwindows;
32 import egui.widgets;
35 // ////////////////////////////////////////////////////////////////////////// //
36 public string[] buildAutoCompletion (ConString prefix) {
37 import std.file : DirEntry, SpanMode, dirEntries;
39 if (prefix.length == 0) return null;
41 ConString path, namepfx;
43 if (prefix[$-1] == '/') {
44 path = prefix;
45 namepfx = null;
46 } else {
47 auto lspos = prefix.lastIndexOf('/');
48 if (lspos < 0) {
49 path = null;
50 namepfx = prefix;
51 } else {
52 path = prefix[0..lspos+1];
53 namepfx = prefix[lspos+1..$];
57 //conwriteln("path=[", path, "]; namepfx=[", namepfx, "]");
59 string[] res;
60 foreach (DirEntry de; dirEntries(path.idup, SpanMode.shallow)) {
61 if (namepfx.length != 0) {
62 import std.path : baseName;
63 //conwriteln(" [", de.baseName, "]");
64 if (!de.baseName.startsWith(namepfx)) continue;
66 try {
67 if (de.isDir) res ~= de.name~"/"; else res ~= de.name;
68 } catch (Exception e) {}
71 if (res.length > 1) {
72 import std.algorithm : sort;
73 sort(res);
76 return res;
80 // ////////////////////////////////////////////////////////////////////////// //
81 public class SelectCompletionWindow : SubWindow {
82 SimpleListBoxWidget lb;
83 string[] list;
85 void delegate (string str) onSelected;
87 this (const(char)[] prefix, string[] clist, bool aspath) {
88 createRoot();
89 int xhgt = 0;
90 int xwdt = 0;
91 bool idxset = false;
92 lb = new SimpleListBoxWidget(rootWidget);
93 foreach (string s; clist) {
94 if (aspath && s.length) {
95 usize lspos = s.length;
96 if (s[$-1] == '/') --lspos;
97 while (lspos > 0 && s.ptr[lspos-1] != '/') --lspos;
98 s = s[lspos..$];
100 lb.appendItem(s);
101 if (s == prefix) { idxset = true; lb.curidx = lb.length-1; }
102 if (!idxset && s.startsWith(prefix)) { idxset = true; lb.curidx = lb.length-1; }
103 int w = gxTextWidthUtf(s)+2;
104 if (xwdt < w) xwdt = w;
105 xhgt += gxTextHeightUtf;
108 if (xhgt == 0) { super(); return; }
109 if (xhgt > screenHeight) xhgt = screenHeight-decorationSizeY;
111 if (xwdt > screenWidth-decorationSizeX) xwdt = screenWidth-decorationSizeX;
113 super("Select Completion", GxSize(xwdt+decorationSizeX, xhgt+decorationSizeY));
114 lb.width = clientWidth;
115 lb.height = clientHeight;
116 list = clist;
118 lb.onAction = delegate (self) {
119 if (onSelected !is null && lb.curidx >= 0 && lb.curidx < list.length) {
120 close();
121 onSelected(list[lb.curidx]);
122 return;
124 vbwin.beep();
127 addModal();
130 override bool onKeyBubble (KeyEvent event) {
131 if (event.pressed) {
132 if (event == "Escape" || event == "C-Q") { close(); return true; }
133 if (event == "Enter") { lb.onAction(lb); return true; }
135 return super.onKeyBubble(event);
140 // ////////////////////////////////////////////////////////////////////////// //
141 public class YesNoWindow : SubWindow {
142 public:
143 ButtonWidget yes, no;
145 void delegate () onYes;
146 void delegate () onNo;
148 protected:
149 string msgMessage;
150 bool defaction = true;
152 public:
153 this (string atitle, string amessage, bool adefaction=true) {
154 msgMessage = amessage;
155 defaction = adefaction;
156 super(atitle);
159 override void createWidgets () {
160 new SpacerWidget(rootWidget, 8);
162 auto msgbox = new HBoxWidget(rootWidget);
163 new SpacerWidget(msgbox, 4);
164 with (new LabelWidget(msgbox, msgMessage, LabelWidget.HAlign.Center, LabelWidget.VAlign.Center)) {
165 flex = 1;
167 new SpacerWidget(msgbox, 4);
169 new SpacerWidget(rootWidget, 8);
171 auto btnbox = new HBoxWidget(rootWidget);
172 new SpacerWidget(btnbox, 2);
173 new SpringWidget(btnbox, 1);
174 yes = new ButtonExWidget(btnbox, "&Yes");
175 new SpacerWidget(btnbox, 4);
176 no = new ButtonExWidget(btnbox, "&No");
177 new SpringWidget(btnbox, 1);
178 new SpacerWidget(btnbox, 2);
180 new SpacerWidget(rootWidget, 2);
182 int bwdt = yes.width;
183 if (bwdt < no.width) bwdt = no.width;
184 if (bwdt < 96) bwdt = 96;
186 yes.width = bwdt;
187 no.width = bwdt;
189 relayoutResize();
190 centerWindow();
192 if (defaction) yes.focus(); else no.focus();
194 yes.onAction = delegate (self) {
195 close();
196 if (onYes !is null) onYes();
199 no.onAction = delegate (self) {
200 close();
201 if (onNo !is null) onNo();
205 override void finishCreating () {
206 addModal();
209 override bool onKeyBubble (KeyEvent event) {
210 if (event.pressed) {
211 if (event == "Escape" || event == "C-Q") { no.doAction(); return true; }
213 return super.onKeyBubble(event);