1 
2 #include "WINGsP.h"
3 
4 #include <X11/keysym.h>
5 #include <stdint.h>
6 
alertPanelOnClick(WMWidget * self,void * clientData)7 static void alertPanelOnClick(WMWidget * self, void *clientData)
8 {
9 	WMAlertPanel *panel = clientData;
10 
11 	WMBreakModalLoop(WMWidgetScreen(self));
12 	if (self == panel->defBtn) {
13 		panel->result = WAPRDefault;
14 	} else if (self == panel->othBtn) {
15 		panel->result = WAPROther;
16 	} else if (self == panel->altBtn) {
17 		panel->result = WAPRAlternate;
18 	}
19 }
20 
handleKeyPress(XEvent * event,void * clientData)21 static void handleKeyPress(XEvent * event, void *clientData)
22 {
23 	WMAlertPanel *panel = (WMAlertPanel *) clientData;
24 	KeySym ksym;
25 
26 	XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
27 
28 	if (ksym == XK_Return && panel->defBtn) {
29 		WMPerformButtonClick(panel->defBtn);
30 	} else if (ksym == XK_Escape) {
31 		if (panel->altBtn || panel->othBtn) {
32 			WMPerformButtonClick(panel->othBtn ? panel->othBtn : panel->altBtn);
33 		} else {
34 			panel->result = WAPRDefault;
35 			WMBreakModalLoop(WMWidgetScreen(panel->win));
36 		}
37 	}
38 }
39 
40 int
WMRunAlertPanel(WMScreen * scrPtr,WMWindow * owner,const char * title,const char * msg,const char * defaultButton,const char * alternateButton,const char * otherButton)41 WMRunAlertPanel(WMScreen * scrPtr, WMWindow * owner,
42 		const char *title, const char *msg, const char *defaultButton, const char *alternateButton, const char *otherButton)
43 {
44 	WMAlertPanel *panel;
45 	int tmp;
46 
47 	panel = WMCreateAlertPanel(scrPtr, owner, title, msg, defaultButton, alternateButton, otherButton);
48 
49 	{
50 		int px, py;
51 		WMView *view = WMWidgetView(panel->win);
52 
53 		if (owner) {
54 			WMView *oview = WMWidgetView(owner);
55 			WMPoint pt = WMGetViewScreenPosition(oview);
56 
57 			px = (W_VIEW_WIDTH(oview) - W_VIEW_WIDTH(view)) / 2;
58 			py = (W_VIEW_HEIGHT(oview) - W_VIEW_HEIGHT(view)) / 2;
59 
60 			px += pt.x;
61 			py += pt.y;
62 		} else {
63 			px = (W_VIEW_WIDTH(scrPtr->rootView) - W_VIEW_WIDTH(view)) / 2;
64 			py = (W_VIEW_HEIGHT(scrPtr->rootView) - W_VIEW_HEIGHT(view)) / 2;
65 		}
66 		WMSetWindowInitialPosition(panel->win, px, py);
67 	}
68 
69 	WMMapWidget(panel->win);
70 
71 	WMRunModalLoop(scrPtr, W_VIEW(panel->win));
72 
73 	tmp = panel->result;
74 
75 	WMDestroyAlertPanel(panel);
76 
77 	return tmp;
78 }
79 
WMDestroyAlertPanel(WMAlertPanel * panel)80 void WMDestroyAlertPanel(WMAlertPanel * panel)
81 {
82 	WMUnmapWidget(panel->win);
83 	WMDestroyWidget(panel->win);
84 	wfree(panel);
85 }
86 
WMCreateAlertPanel(WMScreen * scrPtr,WMWindow * owner,const char * title,const char * msg,const char * defaultButton,const char * alternateButton,const char * otherButton)87 WMAlertPanel *WMCreateAlertPanel(WMScreen * scrPtr, WMWindow * owner,
88 				 const char *title, const char *msg, const char *defaultButton,
89 				 const char *alternateButton, const char *otherButton)
90 {
91 	WMAlertPanel *panel;
92 	WMFont *defaultFont;
93 	int dw = 0, aw = 0, ow = 0, w;
94 	WMBox *hbox;
95 	WMPixmap *icon;
96 
97 	defaultFont = WMSystemFontOfSize(scrPtr, 12);
98 	panel = wmalloc(sizeof(WMAlertPanel));
99 
100 	if (owner) {
101 		panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel", WMTitledWindowMask);
102 	} else {
103 		panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel", WMTitledWindowMask);
104 	}
105 
106 	WMSetWindowInitialPosition(panel->win,
107 				   (scrPtr->rootView->size.width - WMWidgetWidth(panel->win)) / 2,
108 				   (scrPtr->rootView->size.height - WMWidgetHeight(panel->win)) / 2);
109 
110 	WMSetWindowTitle(panel->win, "");
111 
112 	panel->vbox = WMCreateBox(panel->win);
113 	WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
114 	WMSetBoxHorizontal(panel->vbox, False);
115 	WMMapWidget(panel->vbox);
116 
117 	hbox = WMCreateBox(panel->vbox);
118 	WMSetBoxBorderWidth(hbox, 5);
119 	WMSetBoxHorizontal(hbox, True);
120 	WMMapWidget(hbox);
121 	WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
122 
123 	panel->iLbl = WMCreateLabel(hbox);
124 	WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
125 	WMMapWidget(panel->iLbl);
126 	WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
127 	icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL);
128 	if (icon) {
129 		WMSetLabelImage(panel->iLbl, icon);
130 		WMReleasePixmap(icon);
131 	} else {
132 		WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
133 	}
134 
135 	if (title) {
136 		WMFont *largeFont;
137 
138 		largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
139 
140 		panel->tLbl = WMCreateLabel(hbox);
141 		WMMapWidget(panel->tLbl);
142 		WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True, 64, 0, 0);
143 		WMSetLabelText(panel->tLbl, title);
144 		WMSetLabelTextAlignment(panel->tLbl, WALeft);
145 		WMSetLabelFont(panel->tLbl, largeFont);
146 
147 		WMReleaseFont(largeFont);
148 	}
149 
150 	/* create divider line */
151 
152 	panel->line = WMCreateFrame(panel->win);
153 	WMMapWidget(panel->line);
154 	WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True, 2, 2, 5);
155 	WMSetFrameRelief(panel->line, WRGroove);
156 
157 	if (msg) {
158 		panel->mLbl = WMCreateLabel(panel->vbox);
159 		WMSetLabelWraps(panel->mLbl, True);
160 		WMMapWidget(panel->mLbl);
161 		WMAddBoxSubview(panel->vbox, WMWidgetView(panel->mLbl), True, True,
162 				WMFontHeight(scrPtr->normalFont) * 4, 0, 5);
163 		WMSetLabelText(panel->mLbl, msg);
164 		WMSetLabelTextAlignment(panel->mLbl, WACenter);
165 		WMSetLabelFont(panel->mLbl, defaultFont);
166 	}
167 
168 	panel->hbox = WMCreateBox(panel->vbox);
169 	WMSetBoxBorderWidth(panel->hbox, 10);
170 	WMSetBoxHorizontal(panel->hbox, True);
171 	WMMapWidget(panel->hbox);
172 	WMAddBoxSubview(panel->vbox, WMWidgetView(panel->hbox), False, True, 44, 0, 0);
173 
174 	/* create buttons */
175 	if (otherButton)
176 		ow = WMWidthOfString(defaultFont, otherButton, strlen(otherButton));
177 
178 	if (alternateButton)
179 		aw = WMWidthOfString(defaultFont, alternateButton, strlen(alternateButton));
180 
181 	if (defaultButton)
182 		dw = WMWidthOfString(defaultFont, defaultButton, strlen(defaultButton));
183 
184 	dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
185 
186 	aw += 30;
187 	ow += 30;
188 	dw += 30;
189 
190 	w = WMAX(dw, WMAX(aw, ow));
191 	if ((w + 10) * 3 < 400) {
192 		aw = w;
193 		ow = w;
194 		dw = w;
195 	} else {
196 		int t;
197 
198 		t = 400 - 40 - aw - ow - dw;
199 		aw += t / 3;
200 		ow += t / 3;
201 		dw += t / 3;
202 	}
203 
204 	if (defaultButton) {
205 		panel->defBtn = WMCreateCommandButton(panel->hbox);
206 		WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
207 		WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->defBtn), False, True, dw, 0, 0);
208 		WMSetButtonText(panel->defBtn, defaultButton);
209 		WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
210 		WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
211 		WMSetButtonImagePosition(panel->defBtn, WIPRight);
212 		WMSetButtonFont(panel->defBtn, defaultFont);
213 	}
214 	if (alternateButton) {
215 		panel->altBtn = WMCreateCommandButton(panel->hbox);
216 		WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->altBtn), False, True, aw, 0, 5);
217 		WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
218 		WMSetButtonText(panel->altBtn, alternateButton);
219 		WMSetButtonFont(panel->altBtn, defaultFont);
220 	}
221 	if (otherButton) {
222 		panel->othBtn = WMCreateCommandButton(panel->hbox);
223 		WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
224 		WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->othBtn), False, True, ow, 0, 5);
225 		WMSetButtonText(panel->othBtn, otherButton);
226 		WMSetButtonFont(panel->othBtn, defaultFont);
227 	}
228 
229 	WMMapSubwidgets(panel->hbox);
230 
231 	WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress, panel);
232 
233 	WMRealizeWidget(panel->win);
234 	WMMapSubwidgets(panel->win);
235 
236 	WMReleaseFont(defaultFont);
237 
238 	return panel;
239 }
240 
WMCreateScaledAlertPanel(WMScreen * scrPtr,WMWindow * owner,const char * title,const char * msg,const char * defaultButton,const char * alternateButton,const char * otherButton)241 WMAlertPanel *WMCreateScaledAlertPanel(WMScreen * scrPtr, WMWindow * owner,
242 				       const char *title, const char *msg, const char *defaultButton,
243 				       const char *alternateButton, const char *otherButton)
244 {
245 	WMAlertPanel *panel;
246 	int dw = 0, aw = 0, ow = 0, w;
247 	WMBox *hbox;
248 	WMPixmap *icon;
249 	int wmScaleWidth, wmScaleHeight;
250 	int pwidth, pheight;
251 
252 	panel = wmalloc(sizeof(WMAlertPanel));
253 
254 	if (owner) {
255 		panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel", WMTitledWindowMask);
256 	} else {
257 		panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel", WMTitledWindowMask);
258 	}
259 
260 	/* calculate and set the panel's size */
261 	WMGetScaleBaseFromSystemFont(scrPtr, &wmScaleWidth, &wmScaleHeight);
262 	pwidth = WMScaleX(400);
263 	pheight = WMScaleY(5)    /* upper margin */
264 		+ 64             /* icon size */
265 		+ WMScaleY(5)    /* space between icon and divider line */
266 		+ 2              /* divider line */
267 		+ WMScaleY(5);   /* space between divider line and message */
268 	if (msg)
269 		pheight += WMFontHeight(scrPtr->normalFont) * 4 + WMScaleY(5);
270 	pheight += WMScaleY(44);
271 	WMResizeWidget(panel->win, pwidth, pheight);
272 
273 	WMSetWindowInitialPosition(panel->win,
274 				   (scrPtr->rootView->size.width - pwidth) / 2,
275 				   (scrPtr->rootView->size.height - pheight) / 2);
276 
277 	WMSetWindowTitle(panel->win, "");
278 
279 	panel->vbox = WMCreateBox(panel->win);
280 	WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
281 	WMSetBoxHorizontal(panel->vbox, False);
282 	WMMapWidget(panel->vbox);
283 
284 	hbox = WMCreateBox(panel->vbox);
285 	WMSetBoxBorderWidth(hbox, WMScaleX(5));
286 	WMSetBoxHorizontal(hbox, True);
287 	WMMapWidget(hbox);
288 	WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 64 + 2 * WMScaleY(5), 0, WMScaleY(5));
289 
290 	panel->iLbl = WMCreateLabel(hbox);
291 	WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
292 	WMMapWidget(panel->iLbl);
293 	WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
294 	icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL);
295 	if (icon) {
296 		WMSetLabelImage(panel->iLbl, icon);
297 		WMReleasePixmap(icon);
298 	} else {
299 		WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
300 	}
301 
302 	if (title) {
303 		WMFont *largeFont;
304 
305 		largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
306 
307 		panel->tLbl = WMCreateLabel(hbox);
308 		WMMapWidget(panel->tLbl);
309 		WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True, 64, 0, 0);
310 		WMSetLabelText(panel->tLbl, title);
311 		WMSetLabelTextAlignment(panel->tLbl, WALeft);
312 		WMSetLabelFont(panel->tLbl, largeFont);
313 
314 		WMReleaseFont(largeFont);
315 	}
316 
317 	/* create divider line */
318 
319 	panel->line = WMCreateFrame(panel->win);
320 	WMMapWidget(panel->line);
321 	WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True, 2, 2, WMScaleY(5));
322 	WMSetFrameRelief(panel->line, WRGroove);
323 
324 	if (msg) {
325 		panel->mLbl = WMCreateLabel(panel->vbox);
326 		WMSetLabelWraps(panel->mLbl, True);
327 		WMMapWidget(panel->mLbl);
328 		WMAddBoxSubview(panel->vbox, WMWidgetView(panel->mLbl), True, True,
329 				WMFontHeight(scrPtr->normalFont) * 4, 0, WMScaleY(5));
330 		WMSetLabelText(panel->mLbl, msg);
331 		WMSetLabelTextAlignment(panel->mLbl, WACenter);
332 	}
333 
334 	panel->hbox = WMCreateBox(panel->vbox);
335 	WMSetBoxBorderWidth(panel->hbox, WMScaleX(10));
336 	WMSetBoxHorizontal(panel->hbox, True);
337 	WMMapWidget(panel->hbox);
338 	WMAddBoxSubview(panel->vbox, WMWidgetView(panel->hbox), False, True, WMScaleY(44), 0, 0);
339 
340 	/* create buttons */
341 	if (otherButton)
342 		ow = WMWidthOfString(scrPtr->normalFont, otherButton, strlen(otherButton));
343 
344 	if (alternateButton)
345 		aw = WMWidthOfString(scrPtr->normalFont, alternateButton, strlen(alternateButton));
346 
347 	if (defaultButton)
348 		dw = WMWidthOfString(scrPtr->normalFont, defaultButton, strlen(defaultButton));
349 
350 	dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
351 
352 	aw += WMScaleX(30);
353 	ow += WMScaleX(30);
354 	dw += WMScaleX(30);
355 
356 	w = WMAX(dw, WMAX(aw, ow));
357 	if ((w + WMScaleX(10)) * 3 < pwidth) {
358 		aw = w;
359 		ow = w;
360 		dw = w;
361 	} else {
362 		int t;
363 
364 		t = pwidth - 4 * WMScaleX(10) - aw - ow - dw;
365 		aw += t / 3;
366 		ow += t / 3;
367 		dw += t / 3;
368 	}
369 
370 	if (defaultButton) {
371 		panel->defBtn = WMCreateCommandButton(panel->hbox);
372 		WMResizeWidget(panel->defBtn, dw, WMScaleY(24));
373 		WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
374 		WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->defBtn), False, True, dw, 0, 0);
375 		WMSetButtonText(panel->defBtn, defaultButton);
376 		WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
377 		WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
378 		WMSetButtonImagePosition(panel->defBtn, WIPRight);
379 	}
380 	if (alternateButton) {
381 		panel->altBtn = WMCreateCommandButton(panel->hbox);
382 		WMResizeWidget(panel->altBtn, aw, WMScaleY(24));
383 		WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->altBtn), False, True, aw, 0, WMScaleX(5));
384 		WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
385 		WMSetButtonText(panel->altBtn, alternateButton);
386 	}
387 	if (otherButton) {
388 		panel->othBtn = WMCreateCommandButton(panel->hbox);
389 		WMResizeWidget(panel->othBtn, ow, WMScaleY(24));
390 		WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
391 		WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->othBtn), False, True, ow, 0, WMScaleX(5));
392 		WMSetButtonText(panel->othBtn, otherButton);
393 	}
394 
395 	WMMapSubwidgets(panel->hbox);
396 
397 	WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress, panel);
398 
399 	WMRealizeWidget(panel->win);
400 	WMMapSubwidgets(panel->win);
401 
402 	return panel;
403 }
404 
inputBoxOnClick(WMWidget * self,void * clientData)405 static void inputBoxOnClick(WMWidget * self, void *clientData)
406 {
407 	WMInputPanel *panel = clientData;
408 
409 	WMBreakModalLoop(WMWidgetScreen(self));
410 	if (self == panel->defBtn) {
411 		panel->result = WAPRDefault;
412 	} else if (self == panel->altBtn) {
413 		panel->result = WAPRAlternate;
414 	}
415 }
416 
handleKeyPress2(XEvent * event,void * clientData)417 static void handleKeyPress2(XEvent * event, void *clientData)
418 {
419 	WMInputPanel *panel = (WMInputPanel *) clientData;
420 	KeySym ksym;
421 
422 	XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
423 
424 	if (ksym == XK_Return && panel->defBtn) {
425 		WMPerformButtonClick(panel->defBtn);
426 	} else if (ksym == XK_Escape) {
427 		if (panel->altBtn) {
428 			WMPerformButtonClick(panel->altBtn);
429 		} else {
430 			/*           printf("got esc\n"); */
431 			WMBreakModalLoop(WMWidgetScreen(panel->win));
432 			panel->result = WAPRDefault;
433 		}
434 	}
435 }
436 
WMRunInputPanel(WMScreen * scrPtr,WMWindow * owner,const char * title,const char * msg,const char * defaultText,const char * okButton,const char * cancelButton)437 char *WMRunInputPanel(WMScreen * scrPtr, WMWindow * owner, const char *title,
438 		      const char *msg, const char *defaultText, const char *okButton, const char *cancelButton)
439 {
440 	WMInputPanel *panel;
441 	char *tmp;
442 
443 	panel = WMCreateInputPanel(scrPtr, owner, title, msg, defaultText, okButton, cancelButton);
444 
445 	{
446 		int px, py;
447 		WMView *view = WMWidgetView(panel->win);
448 
449 		if (owner) {
450 			WMView *oview = WMWidgetView(owner);
451 			WMPoint pt = WMGetViewScreenPosition(oview);
452 
453 			px = (W_VIEW_WIDTH(oview) - W_VIEW_WIDTH(view)) / 2;
454 			py = (W_VIEW_HEIGHT(oview) - W_VIEW_HEIGHT(view)) / 2;
455 
456 			px += pt.x;
457 			py += pt.y;
458 		} else {
459 			px = (W_VIEW_WIDTH(scrPtr->rootView) - W_VIEW_WIDTH(view)) / 2;
460 			py = (W_VIEW_HEIGHT(scrPtr->rootView) - W_VIEW_HEIGHT(view)) / 2;
461 		}
462 		WMSetWindowInitialPosition(panel->win, px, py);
463 	}
464 
465 	WMMapWidget(panel->win);
466 
467 	WMRunModalLoop(scrPtr, W_VIEW(panel->win));
468 
469 	if (panel->result == WAPRDefault)
470 		tmp = WMGetTextFieldText(panel->text);
471 	else
472 		tmp = NULL;
473 
474 	WMDestroyInputPanel(panel);
475 
476 	return tmp;
477 }
478 
WMDestroyInputPanel(WMInputPanel * panel)479 void WMDestroyInputPanel(WMInputPanel * panel)
480 {
481 	WMRemoveNotificationObserver(panel);
482 	WMUnmapWidget(panel->win);
483 	WMDestroyWidget(panel->win);
484 	wfree(panel);
485 }
486 
endedEditingObserver(void * observerData,WMNotification * notification)487 static void endedEditingObserver(void *observerData, WMNotification * notification)
488 {
489 	WMInputPanel *panel = (WMInputPanel *) observerData;
490 
491 	switch ((uintptr_t)WMGetNotificationClientData(notification)) {
492 	case WMReturnTextMovement:
493 		if (panel->defBtn)
494 			WMPerformButtonClick(panel->defBtn);
495 		break;
496 	case WMEscapeTextMovement:
497 		if (panel->altBtn)
498 			WMPerformButtonClick(panel->altBtn);
499 		else {
500 			WMBreakModalLoop(WMWidgetScreen(panel->win));
501 			panel->result = WAPRDefault;
502 		}
503 		break;
504 	default:
505 		break;
506 	}
507 }
508 
WMCreateInputPanel(WMScreen * scrPtr,WMWindow * owner,const char * title,const char * msg,const char * defaultText,const char * okButton,const char * cancelButton)509 WMInputPanel *WMCreateInputPanel(WMScreen * scrPtr, WMWindow * owner, const char *title, const char *msg,
510 				 const char *defaultText, const char *okButton, const char *cancelButton)
511 {
512 	WMInputPanel *panel;
513 	WMFont *defaultFont;
514 	int x, dw = 0, aw = 0, w;
515 
516 	defaultFont = WMSystemFontOfSize(scrPtr, 12);
517 	panel = wmalloc(sizeof(WMInputPanel));
518 
519 	if (owner)
520 		panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel", WMTitledWindowMask);
521 	else
522 		panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel", WMTitledWindowMask);
523 	WMSetWindowTitle(panel->win, "");
524 
525 	WMResizeWidget(panel->win, 320, 160);
526 
527 	if (title) {
528 		WMFont *largeFont;
529 
530 		largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
531 
532 		panel->tLbl = WMCreateLabel(panel->win);
533 		WMMoveWidget(panel->tLbl, 20, 16);
534 		WMResizeWidget(panel->tLbl, 320 - 40, WMFontHeight(largeFont) + 4);
535 		WMSetLabelText(panel->tLbl, title);
536 		WMSetLabelTextAlignment(panel->tLbl, WALeft);
537 		WMSetLabelFont(panel->tLbl, largeFont);
538 
539 		WMReleaseFont(largeFont);
540 	}
541 
542 	if (msg) {
543 		panel->mLbl = WMCreateLabel(panel->win);
544 		WMMoveWidget(panel->mLbl, 20, 50);
545 		WMResizeWidget(panel->mLbl, 320 - 40, WMFontHeight(scrPtr->normalFont) * 2);
546 		WMSetLabelText(panel->mLbl, msg);
547 		WMSetLabelTextAlignment(panel->mLbl, WALeft);
548 		WMSetLabelFont(panel->mLbl, defaultFont);
549 	}
550 
551 	panel->text = WMCreateTextField(panel->win);
552 	WMMoveWidget(panel->text, 20, 85);
553 	WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
554 	WMSetTextFieldText(panel->text, defaultText);
555 	WMSetTextFieldFont(panel->text, defaultFont);
556 
557 	WMAddNotificationObserver(endedEditingObserver, panel, WMTextDidEndEditingNotification, panel->text);
558 
559 	/* create buttons */
560 	if (cancelButton)
561 		aw = WMWidthOfString(defaultFont, cancelButton, strlen(cancelButton));
562 
563 	if (okButton)
564 		dw = WMWidthOfString(defaultFont, okButton, strlen(okButton));
565 
566 	w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
567 	if (aw > w)
568 		w = aw;
569 
570 	w += 30;
571 	x = 310;
572 
573 	if (okButton) {
574 		x -= w + 10;
575 
576 		panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
577 						     | WBBPushChangeMask | WBBPushLightMask);
578 		WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
579 		WMMoveWidget(panel->defBtn, x, 124);
580 		WMResizeWidget(panel->defBtn, w, 24);
581 		WMSetButtonText(panel->defBtn, okButton);
582 		WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
583 		WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
584 		WMSetButtonImagePosition(panel->defBtn, WIPRight);
585 		WMSetButtonFont(panel->defBtn, defaultFont);
586 	}
587 	if (cancelButton) {
588 		x -= w + 10;
589 
590 		panel->altBtn = WMCreateCommandButton(panel->win);
591 		WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
592 		WMMoveWidget(panel->altBtn, x, 124);
593 		WMResizeWidget(panel->altBtn, w, 24);
594 		WMSetButtonText(panel->altBtn, cancelButton);
595 		WMSetButtonFont(panel->altBtn, defaultFont);
596 	}
597 
598 	WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress2, panel);
599 
600 	WMRealizeWidget(panel->win);
601 	WMMapSubwidgets(panel->win);
602 
603 	WMSetFocusToWidget(panel->text);
604 
605 	WMReleaseFont(defaultFont);
606 
607 	return panel;
608 }
609 
WMCreateScaledInputPanel(WMScreen * scrPtr,WMWindow * owner,const char * title,const char * msg,const char * defaultText,const char * okButton,const char * cancelButton)610 WMInputPanel *WMCreateScaledInputPanel(WMScreen * scrPtr, WMWindow * owner, const char *title, const char *msg,
611 				       const char *defaultText, const char *okButton, const char *cancelButton)
612 {
613 	WMInputPanel *panel;
614 	int x, dw = 0, aw = 0, w;
615 	int wmScaleWidth, wmScaleHeight;
616 
617 	panel = wmalloc(sizeof(WMInputPanel));
618 
619 	if (owner)
620 		panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel", WMTitledWindowMask);
621 	else
622 		panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel", WMTitledWindowMask);
623 	WMSetWindowTitle(panel->win, "");
624 
625 	WMGetScaleBaseFromSystemFont(scrPtr, &wmScaleWidth, &wmScaleHeight);
626 	WMResizeWidget(panel->win, WMScaleX(320), WMScaleY(160));
627 
628 	if (title) {
629 		WMFont *largeFont;
630 
631 		largeFont = WMBoldSystemFontOfSize(scrPtr, WMScaleY(24));
632 
633 		panel->tLbl = WMCreateLabel(panel->win);
634 		WMMoveWidget(panel->tLbl, WMScaleX(20), WMScaleY(16));
635 		WMResizeWidget(panel->tLbl, WMScaleX(320) - 2 * WMScaleX(20), WMFontHeight(largeFont) + WMScaleY(4));
636 		WMSetLabelText(panel->tLbl, title);
637 		WMSetLabelTextAlignment(panel->tLbl, WALeft);
638 		WMSetLabelFont(panel->tLbl, largeFont);
639 
640 		WMReleaseFont(largeFont);
641 	}
642 
643 	if (msg) {
644 		panel->mLbl = WMCreateLabel(panel->win);
645 		WMMoveWidget(panel->mLbl, WMScaleX(20), WMScaleY(50));
646 		WMResizeWidget(panel->mLbl, WMScaleX(320) - 2 * WMScaleX(20), WMFontHeight(scrPtr->normalFont) * 2);
647 		WMSetLabelText(panel->mLbl, msg);
648 		WMSetLabelTextAlignment(panel->mLbl, WALeft);
649 	}
650 
651 	panel->text = WMCreateTextField(panel->win);
652 	WMMoveWidget(panel->text, WMScaleX(20), WMScaleY(85));
653 	WMResizeWidget(panel->text, WMScaleX(320) - 2 * WMScaleX(20), WMScaleY(20));
654 	WMSetTextFieldText(panel->text, defaultText);
655 
656 	WMAddNotificationObserver(endedEditingObserver, panel, WMTextDidEndEditingNotification, panel->text);
657 
658 	/* create buttons */
659 	if (cancelButton)
660 		aw = WMWidthOfString(scrPtr->normalFont, cancelButton, strlen(cancelButton));
661 
662 	if (okButton)
663 		dw = WMWidthOfString(scrPtr->normalFont, okButton, strlen(okButton));
664 
665 	w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
666 	if (aw > w)
667 		w = aw;
668 
669 	w += WMScaleX(30);
670 	x = WMScaleX(310);
671 
672 	if (okButton) {
673 		x -= w + WMScaleX(10);
674 
675 		panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
676 						     | WBBPushChangeMask | WBBPushLightMask);
677 		WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
678 		WMMoveWidget(panel->defBtn, x, WMScaleY(124));
679 		WMResizeWidget(panel->defBtn, w, WMScaleY(24));
680 		WMSetButtonText(panel->defBtn, okButton);
681 		WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
682 		WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
683 		WMSetButtonImagePosition(panel->defBtn, WIPRight);
684 	}
685 	if (cancelButton) {
686 		x -= w + WMScaleX(10);
687 
688 		panel->altBtn = WMCreateCommandButton(panel->win);
689 		WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
690 		WMMoveWidget(panel->altBtn, x, WMScaleY(124));
691 		WMResizeWidget(panel->altBtn, w, WMScaleY(24));
692 		WMSetButtonText(panel->altBtn, cancelButton);
693 	}
694 
695 	WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress2, panel);
696 
697 	WMRealizeWidget(panel->win);
698 	WMMapSubwidgets(panel->win);
699 
700 	WMSetFocusToWidget(panel->text);
701 
702 	return panel;
703 }
704 
handleKeyPress3(XEvent * event,void * clientData)705 static void handleKeyPress3(XEvent * event, void *clientData)
706 {
707 	WMGenericPanel *panel = (WMGenericPanel *) clientData;
708 	KeySym ksym;
709 
710 	XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
711 
712 	if (ksym == XK_Return && panel->defBtn) {
713 		WMPerformButtonClick(panel->defBtn);
714 	} else if (ksym == XK_Escape) {
715 		if (panel->altBtn) {
716 			WMPerformButtonClick(panel->altBtn);
717 		} else {
718 			panel->result = WAPRDefault;
719 			WMBreakModalLoop(WMWidgetScreen(panel->win));
720 		}
721 	}
722 }
723 
WMDestroyGenericPanel(WMGenericPanel * panel)724 void WMDestroyGenericPanel(WMGenericPanel * panel)
725 {
726 	WMUnmapWidget(panel->win);
727 	WMDestroyWidget(panel->win);
728 	wfree(panel);
729 }
730 
WMCreateGenericPanel(WMScreen * scrPtr,WMWindow * owner,const char * title,const char * defaultButton,const char * alternateButton)731 WMGenericPanel *WMCreateGenericPanel(WMScreen * scrPtr, WMWindow * owner,
732 				     const char *title, const char *defaultButton, const char *alternateButton)
733 {
734 	WMGenericPanel *panel;
735 	WMFont *defaultFont;
736 	int dw = 0, aw = 0, w;
737 	WMBox *hbox;
738 	WMPixmap *icon;
739 
740 	defaultFont = WMSystemFontOfSize(scrPtr, 12);
741 	panel = wmalloc(sizeof(WMGenericPanel));
742 
743 	if (owner) {
744 		panel->win = WMCreatePanelWithStyleForWindow(owner, "genericPanel", WMTitledWindowMask);
745 	} else {
746 		panel->win = WMCreateWindowWithStyle(scrPtr, "genericPanel", WMTitledWindowMask);
747 	}
748 
749 	WMSetWindowInitialPosition(panel->win,
750 				   (scrPtr->rootView->size.width - WMWidgetWidth(panel->win)) / 2,
751 				   (scrPtr->rootView->size.height - WMWidgetHeight(panel->win)) / 2);
752 
753 	WMSetWindowTitle(panel->win, "");
754 
755 	panel->vbox = WMCreateBox(panel->win);
756 	WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
757 	WMSetBoxHorizontal(panel->vbox, False);
758 	WMMapWidget(panel->vbox);
759 
760 	hbox = WMCreateBox(panel->vbox);
761 	WMSetBoxBorderWidth(hbox, 5);
762 	WMSetBoxHorizontal(hbox, True);
763 	WMMapWidget(hbox);
764 	WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
765 
766 	panel->iLbl = WMCreateLabel(hbox);
767 	WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
768 	WMMapWidget(panel->iLbl);
769 	WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
770 	icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL);
771 	if (icon) {
772 		WMSetLabelImage(panel->iLbl, icon);
773 		WMReleasePixmap(icon);
774 	} else {
775 		WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
776 	}
777 
778 	if (title) {
779 		WMFont *largeFont;
780 
781 		largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
782 
783 		panel->tLbl = WMCreateLabel(hbox);
784 		WMMapWidget(panel->tLbl);
785 		WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True, 64, 0, 0);
786 		WMSetLabelText(panel->tLbl, title);
787 		WMSetLabelTextAlignment(panel->tLbl, WALeft);
788 		WMSetLabelFont(panel->tLbl, largeFont);
789 
790 		WMReleaseFont(largeFont);
791 	}
792 
793 	/* create divider line */
794 
795 	panel->line = WMCreateFrame(panel->vbox);
796 	WMMapWidget(panel->line);
797 	WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True, 2, 2, 5);
798 	WMSetFrameRelief(panel->line, WRGroove);
799 
800 	panel->content = WMCreateFrame(panel->vbox);
801 	WMMapWidget(panel->content);
802 	WMAddBoxSubview(panel->vbox, WMWidgetView(panel->content), True, True, 50, 0, 5);
803 	WMSetFrameRelief(panel->content, WRFlat);
804 
805 	hbox = WMCreateBox(panel->vbox);
806 	WMSetBoxBorderWidth(hbox, 10);
807 	WMSetBoxHorizontal(hbox, True);
808 	WMMapWidget(hbox);
809 	WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
810 
811 	/* create buttons */
812 	if (defaultButton)
813 		dw = WMWidthOfString(defaultFont, defaultButton, strlen(defaultButton));
814 
815 	if (alternateButton)
816 		aw = WMWidthOfString(defaultFont, alternateButton, strlen(alternateButton));
817 
818 	dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
819 
820 	aw += 30;
821 	dw += 30;
822 
823 	w = WMAX(dw, aw);
824 	if ((w + 10) * 2 < 400) {
825 		dw = w;
826 	} else {
827 		int t;
828 
829 		t = 400 - 40 - aw - dw;
830 		dw += t / 2;
831 	}
832 
833 	if (defaultButton) {
834 		panel->defBtn = WMCreateCommandButton(hbox);
835 		WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
836 		WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn), False, True, dw, 0, 0);
837 		WMSetButtonText(panel->defBtn, defaultButton);
838 		WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
839 		WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
840 		WMSetButtonImagePosition(panel->defBtn, WIPRight);
841 		WMSetButtonFont(panel->defBtn, defaultFont);
842 	}
843 
844 	WMMapSubwidgets(hbox);
845 
846 	WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress3, panel);
847 
848 	WMRealizeWidget(panel->win);
849 	WMMapSubwidgets(panel->win);
850 
851 	WMReleaseFont(defaultFont);
852 
853 	return panel;
854 }
855