Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wpanel.c
1
2 #include "WINGsP.h"
3
4 #include <X11/keysym.h>
5 #include <stdint.h>
6
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
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
41 WMRunAlertPanel(WMScreen * scrPtr, WMWindow * owner,
42 char *title, char *msg, char *defaultButton, char *alternateButton, 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
80 void WMDestroyAlertPanel(WMAlertPanel * panel)
81 {
82 WMUnmapWidget(panel->win);
83 WMDestroyWidget(panel->win);
84 wfree(panel);
85 }
86
87 WMAlertPanel *WMCreateAlertPanel(WMScreen * scrPtr, WMWindow * owner,
88 char *title, char *msg, char *defaultButton,
89 char *alternateButton, char *otherButton)
90 {
91 WMAlertPanel *panel;
92 int dw = 0, aw = 0, ow = 0, w;
93 WMBox *hbox;
94 WMPixmap *icon;
95
96 panel = wmalloc(sizeof(WMAlertPanel));
97 memset(panel, 0, sizeof(WMAlertPanel));
98
99 if (owner) {
100 panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel", WMTitledWindowMask);
101 } else {
102 panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel", WMTitledWindowMask);
103 }
104
105 WMSetWindowInitialPosition(panel->win,
106 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win)) / 2,
107 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win)) / 2);
108
109 WMSetWindowTitle(panel->win, "");
110
111 panel->vbox = WMCreateBox(panel->win);
112 WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
113 WMSetBoxHorizontal(panel->vbox, False);
114 WMMapWidget(panel->vbox);
115
116 hbox = WMCreateBox(panel->vbox);
117 WMSetBoxBorderWidth(hbox, 5);
118 WMSetBoxHorizontal(hbox, True);
119 WMMapWidget(hbox);
120 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
121
122 panel->iLbl = WMCreateLabel(hbox);
123 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
124 WMMapWidget(panel->iLbl);
125 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
126 icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL);
127 if (icon) {
128 WMSetLabelImage(panel->iLbl, icon);
129 WMReleasePixmap(icon);
130 } else {
131 WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
132 }
133
134 if (title) {
135 WMFont *largeFont;
136
137 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
138
139 panel->tLbl = WMCreateLabel(hbox);
140 WMMapWidget(panel->tLbl);
141 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True, 64, 0, 0);
142 WMSetLabelText(panel->tLbl, title);
143 WMSetLabelTextAlignment(panel->tLbl, WALeft);
144 WMSetLabelFont(panel->tLbl, largeFont);
145
146 WMReleaseFont(largeFont);
147 }
148
149 /* create divider line */
150
151 panel->line = WMCreateFrame(panel->win);
152 WMMapWidget(panel->line);
153 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True, 2, 2, 5);
154 WMSetFrameRelief(panel->line, WRGroove);
155
156 if (msg) {
157 panel->mLbl = WMCreateLabel(panel->vbox);
158 WMSetLabelWraps(panel->mLbl, True);
159 WMMapWidget(panel->mLbl);
160 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->mLbl), True, True,
161 WMFontHeight(scrPtr->normalFont) * 4, 0, 5);
162 WMSetLabelText(panel->mLbl, msg);
163 WMSetLabelTextAlignment(panel->mLbl, WACenter);
164 }
165
166 panel->hbox = WMCreateBox(panel->vbox);
167 WMSetBoxBorderWidth(panel->hbox, 10);
168 WMSetBoxHorizontal(panel->hbox, True);
169 WMMapWidget(panel->hbox);
170 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->hbox), False, True, 44, 0, 0);
171
172 /* create buttons */
173 if (otherButton)
174 ow = WMWidthOfString(scrPtr->normalFont, otherButton, strlen(otherButton));
175
176 if (alternateButton)
177 aw = WMWidthOfString(scrPtr->normalFont, alternateButton, strlen(alternateButton));
178
179 if (defaultButton)
180 dw = WMWidthOfString(scrPtr->normalFont, defaultButton, strlen(defaultButton));
181
182 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
183
184 aw += 30;
185 ow += 30;
186 dw += 30;
187
188 w = WMAX(dw, WMAX(aw, ow));
189 if ((w + 10) * 3 < 400) {
190 aw = w;
191 ow = w;
192 dw = w;
193 } else {
194 int t;
195
196 t = 400 - 40 - aw - ow - dw;
197 aw += t / 3;
198 ow += t / 3;
199 dw += t / 3;
200 }
201
202 if (defaultButton) {
203 panel->defBtn = WMCreateCommandButton(panel->hbox);
204 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
205 WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->defBtn), False, True, dw, 0, 0);
206 WMSetButtonText(panel->defBtn, defaultButton);
207 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
208 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
209 WMSetButtonImagePosition(panel->defBtn, WIPRight);
210 }
211 if (alternateButton) {
212 panel->altBtn = WMCreateCommandButton(panel->hbox);
213 WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->altBtn), False, True, aw, 0, 5);
214 WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
215 WMSetButtonText(panel->altBtn, alternateButton);
216 }
217 if (otherButton) {
218 panel->othBtn = WMCreateCommandButton(panel->hbox);
219 WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
220 WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->othBtn), False, True, ow, 0, 5);
221 WMSetButtonText(panel->othBtn, otherButton);
222 }
223
224 WMMapSubwidgets(panel->hbox);
225
226 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress, panel);
227
228 WMRealizeWidget(panel->win);
229 WMMapSubwidgets(panel->win);
230
231 return panel;
232 }
233
234 static void inputBoxOnClick(WMWidget * self, void *clientData)
235 {
236 WMInputPanel *panel = clientData;
237
238 WMBreakModalLoop(WMWidgetScreen(self));
239 if (self == panel->defBtn) {
240 panel->result = WAPRDefault;
241 } else if (self == panel->altBtn) {
242 panel->result = WAPRAlternate;
243 }
244 }
245
246 static void handleKeyPress2(XEvent * event, void *clientData)
247 {
248 WMInputPanel *panel = (WMInputPanel *) clientData;
249 KeySym ksym;
250
251 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
252
253 if (ksym == XK_Return && panel->defBtn) {
254 WMPerformButtonClick(panel->defBtn);
255 } else if (ksym == XK_Escape) {
256 if (panel->altBtn) {
257 WMPerformButtonClick(panel->altBtn);
258 } else {
259 /* printf("got esc\n"); */
260 WMBreakModalLoop(WMWidgetScreen(panel->win));
261 panel->result = WAPRDefault;
262 }
263 }
264 }
265
266 char *WMRunInputPanel(WMScreen * scrPtr, WMWindow * owner, char *title,
267 char *msg, char *defaultText, char *okButton, char *cancelButton)
268 {
269 WMInputPanel *panel;
270 char *tmp;
271
272 panel = WMCreateInputPanel(scrPtr, owner, title, msg, defaultText, okButton, cancelButton);
273
274 {
275 int px, py;
276 WMView *view = WMWidgetView(panel->win);
277
278 if (owner) {
279 WMView *oview = WMWidgetView(owner);
280 WMPoint pt = WMGetViewScreenPosition(oview);
281
282 px = (W_VIEW_WIDTH(oview) - W_VIEW_WIDTH(view)) / 2;
283 py = (W_VIEW_HEIGHT(oview) - W_VIEW_HEIGHT(view)) / 2;
284
285 px += pt.x;
286 py += pt.y;
287 } else {
288 px = (W_VIEW_WIDTH(scrPtr->rootView) - W_VIEW_WIDTH(view)) / 2;
289 py = (W_VIEW_HEIGHT(scrPtr->rootView) - W_VIEW_HEIGHT(view)) / 2;
290 }
291 WMSetWindowInitialPosition(panel->win, px, py);
292 }
293
294 WMMapWidget(panel->win);
295
296 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
297
298 if (panel->result == WAPRDefault)
299 tmp = WMGetTextFieldText(panel->text);
300 else
301 tmp = NULL;
302
303 WMDestroyInputPanel(panel);
304
305 return tmp;
306 }
307
308 void WMDestroyInputPanel(WMInputPanel * panel)
309 {
310 WMRemoveNotificationObserver(panel);
311 WMUnmapWidget(panel->win);
312 WMDestroyWidget(panel->win);
313 wfree(panel);
314 }
315
316 static void endedEditingObserver(void *observerData, WMNotification * notification)
317 {
318 WMInputPanel *panel = (WMInputPanel *) observerData;
319
320 switch ((int)(uintptr_t) WMGetNotificationClientData(notification)) {
321 case WMReturnTextMovement:
322 if (panel->defBtn)
323 WMPerformButtonClick(panel->defBtn);
324 break;
325 case WMEscapeTextMovement:
326 if (panel->altBtn)
327 WMPerformButtonClick(panel->altBtn);
328 else {
329 WMBreakModalLoop(WMWidgetScreen(panel->win));
330 panel->result = WAPRDefault;
331 }
332 break;
333 default:
334 break;
335 }
336 }
337
338 WMInputPanel *WMCreateInputPanel(WMScreen * scrPtr, WMWindow * owner, char *title, char *msg,
339 char *defaultText, char *okButton, char *cancelButton)
340 {
341 WMInputPanel *panel;
342 int x, dw = 0, aw = 0, w;
343
344 panel = wmalloc(sizeof(WMInputPanel));
345 memset(panel, 0, sizeof(WMInputPanel));
346
347 if (owner)
348 panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel", WMTitledWindowMask);
349 else
350 panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel", WMTitledWindowMask);
351 WMSetWindowTitle(panel->win, "");
352
353 WMResizeWidget(panel->win, 320, 160);
354
355 if (title) {
356 WMFont *largeFont;
357
358 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
359
360 panel->tLbl = WMCreateLabel(panel->win);
361 WMMoveWidget(panel->tLbl, 20, 16);
362 WMResizeWidget(panel->tLbl, 320 - 40, WMFontHeight(largeFont) + 4);
363 WMSetLabelText(panel->tLbl, title);
364 WMSetLabelTextAlignment(panel->tLbl, WALeft);
365 WMSetLabelFont(panel->tLbl, largeFont);
366
367 WMReleaseFont(largeFont);
368 }
369
370 if (msg) {
371 panel->mLbl = WMCreateLabel(panel->win);
372 WMMoveWidget(panel->mLbl, 20, 50);
373 WMResizeWidget(panel->mLbl, 320 - 40, WMFontHeight(scrPtr->normalFont) * 2);
374 WMSetLabelText(panel->mLbl, msg);
375 WMSetLabelTextAlignment(panel->mLbl, WALeft);
376 }
377
378 panel->text = WMCreateTextField(panel->win);
379 WMMoveWidget(panel->text, 20, 85);
380 WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
381 WMSetTextFieldText(panel->text, defaultText);
382
383 WMAddNotificationObserver(endedEditingObserver, panel, WMTextDidEndEditingNotification, panel->text);
384
385 /* create buttons */
386 if (cancelButton)
387 aw = WMWidthOfString(scrPtr->normalFont, cancelButton, strlen(cancelButton));
388
389 if (okButton)
390 dw = WMWidthOfString(scrPtr->normalFont, okButton, strlen(okButton));
391
392 w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
393 if (aw > w)
394 w = aw;
395
396 w += 30;
397 x = 310;
398
399 if (okButton) {
400 x -= w + 10;
401
402 panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
403 | WBBPushChangeMask | WBBPushLightMask);
404 WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
405 WMMoveWidget(panel->defBtn, x, 124);
406 WMResizeWidget(panel->defBtn, w, 24);
407 WMSetButtonText(panel->defBtn, okButton);
408 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
409 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
410 WMSetButtonImagePosition(panel->defBtn, WIPRight);
411 }
412 if (cancelButton) {
413 x -= w + 10;
414
415 panel->altBtn = WMCreateCommandButton(panel->win);
416 WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
417 WMMoveWidget(panel->altBtn, x, 124);
418 WMResizeWidget(panel->altBtn, w, 24);
419 WMSetButtonText(panel->altBtn, cancelButton);
420 }
421
422 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress2, panel);
423
424 WMRealizeWidget(panel->win);
425 WMMapSubwidgets(panel->win);
426
427 WMSetFocusToWidget(panel->text);
428
429 return panel;
430 }
431
432 static void handleKeyPress3(XEvent * event, void *clientData)
433 {
434 WMGenericPanel *panel = (WMGenericPanel *) clientData;
435 KeySym ksym;
436
437 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
438
439 if (ksym == XK_Return && panel->defBtn) {
440 WMPerformButtonClick(panel->defBtn);
441 } else if (ksym == XK_Escape) {
442 if (panel->altBtn) {
443 WMPerformButtonClick(panel->altBtn);
444 } else {
445 panel->result = WAPRDefault;
446 WMBreakModalLoop(WMWidgetScreen(panel->win));
447 }
448 }
449 }
450
451 void WMDestroyGenericPanel(WMGenericPanel * panel)
452 {
453 WMUnmapWidget(panel->win);
454 WMDestroyWidget(panel->win);
455 wfree(panel);
456 }
457
458 WMGenericPanel *WMCreateGenericPanel(WMScreen * scrPtr, WMWindow * owner,
459 char *title, char *defaultButton, char *alternateButton)
460 {
461 WMGenericPanel *panel;
462 int dw = 0, aw = 0, w;
463 WMBox *hbox;
464 WMPixmap *icon;
465
466 panel = wmalloc(sizeof(WMGenericPanel));
467 memset(panel, 0, sizeof(WMGenericPanel));
468
469 if (owner) {
470 panel->win = WMCreatePanelWithStyleForWindow(owner, "genericPanel", WMTitledWindowMask);
471 } else {
472 panel->win = WMCreateWindowWithStyle(scrPtr, "genericPanel", WMTitledWindowMask);
473 }
474
475 WMSetWindowInitialPosition(panel->win,
476 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win)) / 2,
477 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win)) / 2);
478
479 WMSetWindowTitle(panel->win, "");
480
481 panel->vbox = WMCreateBox(panel->win);
482 WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
483 WMSetBoxHorizontal(panel->vbox, False);
484 WMMapWidget(panel->vbox);
485
486 hbox = WMCreateBox(panel->vbox);
487 WMSetBoxBorderWidth(hbox, 5);
488 WMSetBoxHorizontal(hbox, True);
489 WMMapWidget(hbox);
490 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
491
492 panel->iLbl = WMCreateLabel(hbox);
493 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
494 WMMapWidget(panel->iLbl);
495 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
496 icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL);
497 if (icon) {
498 WMSetLabelImage(panel->iLbl, icon);
499 WMReleasePixmap(icon);
500 } else {
501 WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
502 }
503
504 if (title) {
505 WMFont *largeFont;
506
507 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
508
509 panel->tLbl = WMCreateLabel(hbox);
510 WMMapWidget(panel->tLbl);
511 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True, 64, 0, 0);
512 WMSetLabelText(panel->tLbl, title);
513 WMSetLabelTextAlignment(panel->tLbl, WALeft);
514 WMSetLabelFont(panel->tLbl, largeFont);
515
516 WMReleaseFont(largeFont);
517 }
518
519 /* create divider line */
520
521 panel->line = WMCreateFrame(panel->vbox);
522 WMMapWidget(panel->line);
523 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True, 2, 2, 5);
524 WMSetFrameRelief(panel->line, WRGroove);
525
526 panel->content = WMCreateFrame(panel->vbox);
527 WMMapWidget(panel->content);
528 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->content), True, True, 50, 0, 5);
529 WMSetFrameRelief(panel->content, WRFlat);
530
531 hbox = WMCreateBox(panel->vbox);
532 WMSetBoxBorderWidth(hbox, 10);
533 WMSetBoxHorizontal(hbox, True);
534 WMMapWidget(hbox);
535 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
536
537 /* create buttons */
538 if (defaultButton)
539 dw = WMWidthOfString(scrPtr->normalFont, defaultButton, strlen(defaultButton));
540
541 if (alternateButton)
542 aw = WMWidthOfString(scrPtr->normalFont, alternateButton, strlen(alternateButton));
543
544 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
545
546 aw += 30;
547 dw += 30;
548
549 w = WMAX(dw, aw);
550 if ((w + 10) * 2 < 400) {
551 aw = w;
552 dw = w;
553 } else {
554 int t;
555
556 t = 400 - 40 - aw - dw;
557 aw += t / 2;
558 dw += t / 2;
559 }
560
561 if (defaultButton) {
562 panel->defBtn = WMCreateCommandButton(hbox);
563 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
564 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn), False, True, dw, 0, 0);
565 WMSetButtonText(panel->defBtn, defaultButton);
566 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
567 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
568 WMSetButtonImagePosition(panel->defBtn, WIPRight);
569 }
570
571 WMMapSubwidgets(hbox);
572
573 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress3, panel);
574
575 WMRealizeWidget(panel->win);
576 WMMapSubwidgets(panel->win);
577
578 return panel;
579 }