1 #include "dialogs.h"
2
3
4 Font* dialogs::FontResource;
5 SDL_Color dialogs::BackgroundColor;
6 SDL_Color dialogs::TextBoxColor;
7 stack<yesnoData> dialogs::yesnoCurrent;
8 stack<inputDialog> dialogs::inputCurrent;
onDialogClickDoNothing(bool yesclicked)9 void onDialogClickDoNothing(bool yesclicked) {};
10
11 class yesnoButtonData: public buttondata
12 {
13 public:
14 onDialogEnd func;
15 window* target;
16
yesnoButtonData(onDialogEnd afunc,window * atarget)17 yesnoButtonData(onDialogEnd afunc,window* atarget)
18 {
19 func=afunc;
20 target=atarget;
21 }
22 };
23
yesButtonClick(const buttondata * data)24 void dialogs::yesButtonClick(const buttondata* data)
25 {
26 const yesnoButtonData* dt=static_cast<const yesnoButtonData*>(data);
27 onDialogEnd func=dt->func;
28 dt->target->endSub();
29 dialogs::yesnoCurrent.pop();
30 func(true);
31 }
32
33
noButtonClick(const buttondata * data)34 void dialogs::noButtonClick(const buttondata* data)
35 {
36 const yesnoButtonData* dt=static_cast<const yesnoButtonData*>(data);
37 onDialogEnd func=dt->func;
38 dt->target->endSub();
39 dialogs::yesnoCurrent.pop();
40 func(false);
41 }
42
yesnoOnKeyDown(SDLKey keysym,Uint16 unicode)43 void dialogs::yesnoOnKeyDown(SDLKey keysym, Uint16 unicode)
44 {
45 yesnoData dt= dialogs::yesnoCurrent.top();
46
47 switch(keysym)
48 {
49 case SDLK_RETURN :
50 dialogs::yesnoCurrent.pop();
51 dt.enterdown=true;
52 dialogs::yesnoCurrent.push(dt);
53 break;
54 case (SDLK_ESCAPE):
55 dialogs::yesnoCurrent.pop();
56 dt.escdown=true;
57 dialogs::yesnoCurrent.push(dt);
58 break;
59 }
60 }
61
yesnoOnKeyUp(SDLKey keysym,Uint16 unicode)62 void dialogs::yesnoOnKeyUp(SDLKey keysym, Uint16 unicode)
63 {
64 yesnoData dt= dialogs::yesnoCurrent.top();
65
66 switch(keysym)
67 {
68 case SDLK_RETURN :
69 if(!dt.enterdown) return;
70 dialogs::yesnoCurrent.pop();
71 dt.target->endSub();
72 dt.func(true);
73 break;
74 case (SDLK_ESCAPE):
75
76 if(!dt.escdown) return;
77 dialogs::yesnoCurrent.pop();
78 dt.target->endSub();
79 dt.func(false);
80
81 break;
82 }
83 }
84 //================================================================================
85 class inputtextblock: public control
86 {
87 public:
88 int lines;
89 int tic;
90 string oldtext;
91 inputDialog* diag;
92 inputtextblock(int sx, int sy, int sw, int slines);
93
94 vector<string> textsplit;
95
96 void draw(SDL_Surface* target);
loop()97 void loop() {}
onMouseMove(int px,int py)98 inline void onMouseMove(int px,int py){}
onMouseOut()99 inline void onMouseOut() {}
onMouseDown(int px,int py)100 inline void onMouseDown(int px,int py) {}
onMouseUp(int px,int py)101 inline void onMouseUp(int px,int py) {}
onMouseRightUp(int px,int py)102 inline void onMouseRightUp(int px,int py) {}
103 };
104
inputtextblock(int sx,int sy,int sw,int slines)105 inputtextblock::inputtextblock(int sx, int sy, int sw, int slines)
106 {
107 lines=slines;
108 oldtext="";
109 textsplit=vector<string>(1,"");
110 x=sx;y=sy;w=sw;h=lines*dialogs::FontResource->Height();
111 depth=0;
112 tic=0;
113 }
114
draw(SDL_Surface * target)115 void inputtextblock::draw(SDL_Surface* target)
116 {
117 tic++;
118 string text=dialogs::getCurrentInputText();
119
120 if(text!=oldtext)
121 {
122 textsplit=dialogs::FontResource->splitByLines(text,w);
123 if(textsplit.size()==0) textsplit.push_back("");
124 oldtext=text;
125 }
126
127
128
129
130 int begi=0,endi=lines;
131 if(lines<textsplit.size())
132 {
133 begi=textsplit.size()-lines;
134 endi=textsplit.size();
135 }
136
137 if (lines>textsplit.size())
138 {
139 endi=textsplit.size();
140 }
141
142 int fh=dialogs::FontResource->Height();
143 int th=0;
144 for (int i=begi;i<endi;i++)
145 {
146
147 if((i==endi-1) && (tic%8<4) )
148 dialogs::FontResource->Write(target, x, y+th, textsplit[i]+"|");
149 else
150 dialogs::FontResource->Write(target, x, y+th, textsplit[i]);
151 th+=fh;
152 }
153 }
154
155
156
157 //================================================================================
158
getCurrentInputText()159 string dialogs::getCurrentInputText()
160 {
161 if(inputCurrent.empty()) return "NULL";
162 else return inputCurrent.top().text;
163 }
makeButtonDialog(window * target,string prompt,string yescaption,bool showno,string nocaption,onDialogEnd func)164 void dialogs::makeButtonDialog(window* target, string prompt, string yescaption, bool showno, string nocaption, onDialogEnd func)
165 {
166
167
168 Sint16 pw = target->Width/2;
169 Sint16 ph = max(target->Height/3, min<int>(target->Height, FontResource->WrappedTextHeight(prompt, pw-2*button::Size) + button::Size*4) );
170 Sint16 px = target->Width/4;
171 Sint16 py = (target->Height - ph)/2;
172
173
174
175 yesnoData dt;
176 dt.target=target;
177 dt.func=func;
178 dt.enterdown=false;
179 dt.escdown=false;
180 dialogs::yesnoCurrent.push(dt);
181 target->beginSub();
182
183 control* tmcntrl;
184
185 tmcntrl = new rectangle(px-1,py-1,pw+2,ph+2, 0,0,0 );
186 tmcntrl->depth=1;
187 target->addControl(tmcntrl);
188
189 tmcntrl = new rectangle(px+3,py+3,pw,ph, 0,0,0 );
190 tmcntrl->depth=1;
191 target->addControl(tmcntrl);
192
193
194 tmcntrl=new rectangle(px,py,pw,ph, BackgroundColor );
195 tmcntrl->depth=2;
196 target->addControl(tmcntrl);
197
198 target->onKeyUp=yesnoOnKeyUp;
199 target->onKeyDown=yesnoOnKeyDown;
200
201
202 textblock* tx = new textblock(px+button::Size, py+button::Size, pw-2*button::Size, ph - 4*button::Size, dialogs::FontResource);
203 tx->text= prompt;
204 tx->depth=19;
205 target->addControl(tx);
206
207 int ybuttonw = FontResource->TextWidth(yescaption)+button::Size;
208 if (ybuttonw<button::Size*4) ybuttonw=button::Size*4;
209
210 int buttonw = FontResource->TextWidth(nocaption)+button::Size;
211 if (buttonw<ybuttonw) buttonw=ybuttonw;
212 int buttonx;
213
214 if(showno) buttonx=px+pw/2-buttonw-button::Size/2;
215 else buttonx=px+(pw-buttonw)/2;
216
217
218 int buttony=py+ph-2*button::Size+button::Size/2;
219 button* tmbut= new button(buttonx,buttony,buttonw,button::Size);
220 tmbut->text=yescaption;
221 tmbut->depth=20;
222 tmbut->onClick=yesButtonClick;
223 tmbut->data=new yesnoButtonData(func,target);
224
225 target->addControl(tmbut);
226
227
228
229 if(showno)
230 {
231 buttonx=px+pw/2+button::Size/2;
232 tmbut= new button(buttonx,buttony,buttonw,button::Size);
233 tmbut->text=nocaption;
234 tmbut->depth=20;
235 tmbut->onClick=noButtonClick;
236 tmbut->data=new yesnoButtonData(func,target);
237 target->addControl(tmbut);
238 }
239 }
240
makeYesNoDialog(window * target,string prompt,string yescaption,string nocaption,onDialogEnd func)241 void dialogs::makeYesNoDialog(window* target, string prompt, string yescaption, string nocaption, onDialogEnd func)
242 {
243 makeButtonDialog(target,prompt, yescaption, true, nocaption, func);
244 }
makeMessageDialog(window * target,string prompt,string buttoncaption,onDialogEnd func)245 void dialogs::makeMessageDialog(window* target, string prompt, string buttoncaption, onDialogEnd func)
246 {
247 makeButtonDialog(target,prompt, buttoncaption, false, "", func);
248 }
249
250
251 //==================================
textDialogClickClear(const buttondata * data)252 void dialogs::textDialogClickClear(const buttondata* data)
253 {
254 inputDialog& d= inputCurrent.top();
255 d.text = "";
256 }
257
textDialogClick(bool ok)258 void dialogs::textDialogClick(bool ok)
259 {
260 inputDialog d= inputCurrent.top();
261 inputCurrent.pop();
262
263 d.target->endSub();
264 d.func(ok,d.text,d.data);
265 }
266
inputOnKeyDown(SDLKey keysym,Uint16 unicode)267 void dialogs::inputOnKeyDown(SDLKey keysym,Uint16 unicode)
268 {
269 inputDialog d= inputCurrent.top();
270 if( unicode < 0x80)
271 {
272 char c = (char)(unicode);
273 if(c>=' ')
274 {
275 d.text+=c;
276 inputCurrent.pop();
277 inputCurrent.push(d);
278 }
279 }
280
281 switch(keysym)
282 {
283 case SDLK_RETURN: textDialogClick(true); break;
284 case SDLK_ESCAPE: textDialogClick(false); break;
285
286 case SDLK_BACKSPACE:
287 d.text=d.text.substr(0,d.text.length()-1);
288 inputCurrent.pop();
289 inputCurrent.push(d);
290 break;
291 }
292 }
293
inputOnKeyUp(SDLKey keysym,Uint16 unicode)294 void dialogs::inputOnKeyUp(SDLKey keysym,Uint16 unicode)
295 {
296
297 }
298
299
makeTextInputDialog(window * target,string prompt,string defaulttext,int lines,string okcaption,string cancelcaption,onTextDialogEnd func,inputDialogData * data)300 void dialogs::makeTextInputDialog(window* target, string prompt, string defaulttext, int lines, string okcaption, string cancelcaption, onTextDialogEnd func, inputDialogData* data)
301 {
302
303 SDL_EnableUNICODE(1);
304 Sint16 pw = target->Width/2;
305 Sint16 ph = max(target->Height/3, min<int>(target->Height, FontResource->WrappedTextHeight(prompt, pw-2*button::Size) + button::Size*5) );
306 Sint16 px = target->Width/4;
307 Sint16 py = (target->Height - ph)/2;
308
309
310 Sint16 ith = lines*FontResource->Height();
311 Sint16 textblockheight=ph - 4*button::Size - 2 - ith;
312 Sint16 itw = pw-2*button::Size;
313 Sint16 itx = px+button::Size, ity=py+button::Size+textblockheight+1;
314
315
316 inputDialog cur;
317 cur.data=data;
318 cur.text=defaulttext;
319 cur.lines=lines;
320 cur.target=target;
321 cur.func=func;
322
323 inputCurrent.push(cur);
324
325
326 target->beginSub();
327 target->onKeyUp=inputOnKeyUp;
328 target->onKeyDown=inputOnKeyDown;
329
330 control * tmcntrl;
331 tmcntrl = new rectangle(px-1,py-1,pw+2,ph+2, 0,0,0 );
332 tmcntrl->depth=1;
333 target->addControl(tmcntrl);
334
335 tmcntrl = new rectangle(px+3,py+3,pw,ph, 0,0,0 );
336 tmcntrl->depth=1;
337 target->addControl(tmcntrl);
338
339
340
341 tmcntrl=new rectangle(px,py,pw,ph, BackgroundColor );
342 tmcntrl->depth=2;
343 target->addControl(tmcntrl);
344
345 tmcntrl=new rectangle(itx-1,ity-1,itw+2,ith+2, 0,0,0);
346 tmcntrl->depth=3;
347 target->addControl(tmcntrl);
348
349 tmcntrl=new rectangle(itx,ity,itw,ith, dialogs::TextBoxColor);
350 tmcntrl->depth=4;
351 target->addControl(tmcntrl);
352
353
354
355 textblock* tx = new textblock(px+button::Size, py+button::Size, pw-2*button::Size, textblockheight, dialogs::FontResource);
356 tx->text= prompt;
357 tx->depth=19;
358 target->addControl(tx);
359
360 inputtextblock* input = new inputtextblock(itx+2, ity, itw-4,lines);
361 input->depth=19;
362 target->addControl(input);
363
364
365 int ybuttonw = FontResource->TextWidth(okcaption)+button::Size;
366 if (ybuttonw<button::Size*4) ybuttonw=button::Size*4;
367
368 int buttonw = FontResource->TextWidth(cancelcaption)+button::Size;
369 if (buttonw<ybuttonw) buttonw=ybuttonw;
370
371
372 int buttonx=px + button::Size /*+pw/2-buttonw-button::Size/2*/;
373
374 int buttony=py+ph-2*button::Size+button::Size/2;
375 button* tmbut= new button(buttonx,buttony,buttonw,button::Size);
376 tmbut->text=okcaption;
377 tmbut->depth=20;
378 tmbut->onClick=textDialogClickOk;
379 tmbut->data=NULL;
380 target->addControl(tmbut);
381
382 buttonx=/*px+pw/2+button::Size/2*/ px + pw/2 - buttonw/2;
383 tmbut= new button(buttonx,buttony,buttonw,button::Size);
384 tmbut->text="Clear";
385 tmbut->depth=20;
386 tmbut->onClick=textDialogClickClear;
387 tmbut->data=NULL;
388 target->addControl(tmbut);
389
390
391
392 buttonx=/*px+pw/2+button::Size/2*/ px + pw - buttonw - button::Size;
393 tmbut= new button(buttonx,buttony,buttonw,button::Size);
394 tmbut->text=cancelcaption;
395 tmbut->depth=20;
396 tmbut->onClick=textDialogClickCancel;
397 tmbut->data=NULL;
398 target->addControl(tmbut);
399
400
401
402
403 }
404