For libwraster:
[wmaker-crm.git] / WINGs / wpanel.c
blob2938c38300096ec4397e745033009447c438349f
3 #include "WINGsP.h"
5 #include <X11/keysym.h>
9 static void
10 alertPanelOnClick(WMWidget *self, void *clientData)
12 WMAlertPanel *panel = clientData;
14 WMBreakModalLoop(WMWidgetScreen(self));
15 if (self == panel->defBtn) {
16 panel->result = WAPRDefault;
17 } else if (self == panel->othBtn) {
18 panel->result = WAPROther;
19 } else if (self == panel->altBtn) {
20 panel->result = WAPRAlternate;
25 static void
26 handleKeyPress(XEvent *event, void *clientData)
28 WMAlertPanel *panel = (WMAlertPanel*)clientData;
29 KeySym ksym;
31 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
33 if (ksym == XK_Return && panel->defBtn) {
34 WMPerformButtonClick(panel->defBtn);
35 } else if (ksym == XK_Escape) {
36 if (panel->altBtn || panel->othBtn) {
37 WMPerformButtonClick(panel->othBtn ? panel->othBtn : panel->altBtn);
38 } else {
39 panel->result = WAPRDefault;
40 WMBreakModalLoop(WMWidgetScreen(panel->win));
46 int
47 WMRunAlertPanel(WMScreen *scrPtr, WMWindow *owner,
48 char *title, char *msg, char *defaultButton,
49 char *alternateButton, char *otherButton)
51 WMAlertPanel *panel;
52 int tmp;
54 panel = WMCreateAlertPanel(scrPtr, owner, title, msg, defaultButton,
55 alternateButton, otherButton);
58 int px, py;
59 WMView *view = WMWidgetView(panel->win);
61 if (owner) {
62 WMView *oview = WMWidgetView(owner);
63 WMPoint pt = WMGetViewScreenPosition(oview);
65 px = (W_VIEW_WIDTH(oview)-W_VIEW_WIDTH(view))/2;
66 py = (W_VIEW_HEIGHT(oview)-W_VIEW_HEIGHT(view))/2;
68 px += pt.x;
69 py += pt.y;
70 } else {
71 px = (W_VIEW_WIDTH(scrPtr->rootView)-W_VIEW_WIDTH(view))/2;
72 py = (W_VIEW_HEIGHT(scrPtr->rootView)-W_VIEW_HEIGHT(view))/2;
74 WMSetWindowInitialPosition(panel->win, px, py);
77 WMMapWidget(panel->win);
79 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
81 tmp = panel->result;
83 WMDestroyAlertPanel(panel);
85 return tmp;
89 void
90 WMDestroyAlertPanel(WMAlertPanel *panel)
92 WMUnmapWidget(panel->win);
93 WMDestroyWidget(panel->win);
94 wfree(panel);
98 WMAlertPanel*
99 WMCreateAlertPanel(WMScreen *scrPtr, WMWindow *owner,
100 char *title, char *msg, char *defaultButton,
101 char *alternateButton, char *otherButton)
103 WMAlertPanel *panel;
104 int dw=0, aw=0, ow=0, w;
105 WMBox *hbox;
106 WMPixmap *icon;
109 panel = wmalloc(sizeof(WMAlertPanel));
110 memset(panel, 0, sizeof(WMAlertPanel));
112 if (owner) {
113 panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel",
114 WMTitledWindowMask);
115 } else {
116 panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel",
117 WMTitledWindowMask);
120 WMSetWindowInitialPosition(panel->win,
121 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win))/2,
122 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win))/2);
124 WMSetWindowTitle(panel->win, "");
126 panel->vbox = WMCreateBox(panel->win);
127 WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
128 WMSetBoxHorizontal(panel->vbox, False);
129 WMMapWidget(panel->vbox);
131 hbox = WMCreateBox(panel->vbox);
132 WMSetBoxBorderWidth(hbox, 5);
133 WMSetBoxHorizontal(hbox, True);
134 WMMapWidget(hbox);
135 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
137 panel->iLbl = WMCreateLabel(hbox);
138 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
139 WMMapWidget(panel->iLbl);
140 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
141 icon = WMGetApplicationIconBlendedPixmap(scrPtr, (RColor*)NULL);
142 if (icon) {
143 WMSetLabelImage(panel->iLbl, icon);
144 WMReleasePixmap(icon);
145 } else {
146 WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
149 if (title) {
150 WMFont *largeFont;
152 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
154 panel->tLbl = WMCreateLabel(hbox);
155 WMMapWidget(panel->tLbl);
156 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True,
157 64, 0, 0);
158 WMSetLabelText(panel->tLbl, title);
159 WMSetLabelTextAlignment(panel->tLbl, WALeft);
160 WMSetLabelFont(panel->tLbl, largeFont);
162 WMReleaseFont(largeFont);
165 /* create divider line */
167 panel->line = WMCreateFrame(panel->win);
168 WMMapWidget(panel->line);
169 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True,
170 2, 2, 5);
171 WMSetFrameRelief(panel->line, WRGroove);
174 if (msg) {
175 panel->mLbl = WMCreateLabel(panel->vbox);
176 WMSetLabelWraps(panel->mLbl, True);
177 WMMapWidget(panel->mLbl);
178 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->mLbl), True, True,
179 WMFontHeight(scrPtr->normalFont)*4, 0, 5);
180 WMSetLabelText(panel->mLbl, msg);
181 WMSetLabelTextAlignment(panel->mLbl, WACenter);
184 hbox = WMCreateBox(panel->vbox);
185 WMSetBoxBorderWidth(hbox, 10);
186 WMSetBoxHorizontal(hbox, True);
187 WMMapWidget(hbox);
188 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
190 /* create buttons */
191 if (otherButton)
192 ow = WMWidthOfString(scrPtr->normalFont, otherButton,
193 strlen(otherButton));
195 if (alternateButton)
196 aw = WMWidthOfString(scrPtr->normalFont, alternateButton,
197 strlen(alternateButton));
199 if (defaultButton)
200 dw = WMWidthOfString(scrPtr->normalFont, defaultButton,
201 strlen(defaultButton));
203 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
205 aw += 30;
206 ow += 30;
207 dw += 30;
209 w = WMAX(dw, WMAX(aw, ow));
210 if ((w+10)*3 < 400) {
211 aw = w;
212 ow = w;
213 dw = w;
214 } else {
215 int t;
217 t = 400 - 40 - aw - ow - dw;
218 aw += t/3;
219 ow += t/3;
220 dw += t/3;
223 if (defaultButton) {
224 panel->defBtn = WMCreateCommandButton(hbox);
225 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
226 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn),
227 False, True, dw, 0, 0);
228 WMSetButtonText(panel->defBtn, defaultButton);
229 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
230 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
231 WMSetButtonImagePosition(panel->defBtn, WIPRight);
233 if (alternateButton) {
234 panel->altBtn = WMCreateCommandButton(hbox);
235 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->altBtn),
236 False, True, aw, 0, 5);
237 WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
238 WMSetButtonText(panel->altBtn, alternateButton);
240 if (otherButton) {
241 panel->othBtn = WMCreateCommandButton(hbox);
242 WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
243 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->othBtn),
244 False, True, ow, 0, 5);
245 WMSetButtonText(panel->othBtn, otherButton);
248 WMMapSubwidgets(hbox);
250 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
251 handleKeyPress, panel);
253 WMRealizeWidget(panel->win);
254 WMMapSubwidgets(panel->win);
256 return panel;
263 static void
264 inputBoxOnClick(WMWidget *self, void *clientData)
266 WMInputPanel *panel = clientData;
268 WMBreakModalLoop(WMWidgetScreen(self));
269 if (self == panel->defBtn) {
270 panel->result = WAPRDefault;
271 } else if (self == panel->altBtn) {
272 panel->result = WAPRAlternate;
278 static void
279 handleKeyPress2(XEvent *event, void *clientData)
281 WMInputPanel *panel = (WMInputPanel*)clientData;
282 KeySym ksym;
284 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
286 if (ksym == XK_Return && panel->defBtn) {
287 WMPerformButtonClick(panel->defBtn);
288 } else if (ksym == XK_Escape) {
289 if (panel->altBtn) {
290 WMPerformButtonClick(panel->altBtn);
291 } else {
292 /* printf("got esc\n");*/
293 WMBreakModalLoop(WMWidgetScreen(panel->win));
294 panel->result = WAPRDefault;
300 char*
301 WMRunInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title,
302 char *msg, char *defaultText,
303 char *okButton, char *cancelButton)
305 WMInputPanel *panel;
306 char *tmp;
308 panel = WMCreateInputPanel(scrPtr, owner, title, msg, defaultText,
309 okButton, cancelButton);
313 int px, py;
314 WMView *view = WMWidgetView(panel->win);
316 if (owner) {
317 WMView *oview = WMWidgetView(owner);
318 WMPoint pt = WMGetViewScreenPosition(oview);
320 px = (W_VIEW_WIDTH(oview)-W_VIEW_WIDTH(view))/2;
321 py = (W_VIEW_HEIGHT(oview)-W_VIEW_HEIGHT(view))/2;
323 px += pt.x;
324 py += pt.y;
325 } else {
326 px = (W_VIEW_WIDTH(scrPtr->rootView)-W_VIEW_WIDTH(view))/2;
327 py = (W_VIEW_HEIGHT(scrPtr->rootView)-W_VIEW_HEIGHT(view))/2;
329 WMSetWindowInitialPosition(panel->win, px, py);
332 WMMapWidget(panel->win);
334 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
336 if (panel->result == WAPRDefault)
337 tmp = WMGetTextFieldText(panel->text);
338 else
339 tmp = NULL;
341 WMDestroyInputPanel(panel);
343 return tmp;
347 void
348 WMDestroyInputPanel(WMInputPanel *panel)
350 WMRemoveNotificationObserver(panel);
351 WMUnmapWidget(panel->win);
352 WMDestroyWidget(panel->win);
353 wfree(panel);
358 static void
359 endedEditingObserver(void *observerData, WMNotification *notification)
361 WMInputPanel *panel = (WMInputPanel*)observerData;
363 switch ((int)WMGetNotificationClientData(notification)) {
364 case WMReturnTextMovement:
365 if (panel->defBtn)
366 WMPerformButtonClick(panel->defBtn);
367 break;
368 case WMEscapeTextMovement:
369 if (panel->altBtn)
370 WMPerformButtonClick(panel->altBtn);
371 else {
372 WMBreakModalLoop(WMWidgetScreen(panel->win));
373 panel->result = WAPRDefault;
375 break;
376 default:
377 break;
382 WMInputPanel*
383 WMCreateInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title, char *msg,
384 char *defaultText, char *okButton, char *cancelButton)
386 WMInputPanel *panel;
387 int x, dw=0, aw=0, w;
390 panel = wmalloc(sizeof(WMInputPanel));
391 memset(panel, 0, sizeof(WMInputPanel));
393 if (owner)
394 panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel",
395 WMTitledWindowMask);
396 else
397 panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel",
398 WMTitledWindowMask);
399 WMSetWindowTitle(panel->win, "");
401 WMResizeWidget(panel->win, 320, 160);
403 if (title) {
404 WMFont *largeFont;
406 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
408 panel->tLbl = WMCreateLabel(panel->win);
409 WMMoveWidget(panel->tLbl, 20, 16);
410 WMResizeWidget(panel->tLbl, 320 - 40, WMFontHeight(largeFont)+4);
411 WMSetLabelText(panel->tLbl, title);
412 WMSetLabelTextAlignment(panel->tLbl, WALeft);
413 WMSetLabelFont(panel->tLbl, largeFont);
415 WMReleaseFont(largeFont);
419 if (msg) {
420 panel->mLbl = WMCreateLabel(panel->win);
421 WMMoveWidget(panel->mLbl, 20, 50);
422 WMResizeWidget(panel->mLbl, 320 - 40,
423 WMFontHeight(scrPtr->normalFont)*2);
424 WMSetLabelText(panel->mLbl, msg);
425 WMSetLabelTextAlignment(panel->mLbl, WALeft);
428 panel->text = WMCreateTextField(panel->win);
429 WMMoveWidget(panel->text, 20, 85);
430 WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
431 WMSetTextFieldText(panel->text, defaultText);
433 WMAddNotificationObserver(endedEditingObserver, panel,
434 WMTextDidEndEditingNotification, panel->text);
436 /* create buttons */
437 if (cancelButton)
438 aw = WMWidthOfString(scrPtr->normalFont, cancelButton,
439 strlen(cancelButton));
441 if (okButton)
442 dw = WMWidthOfString(scrPtr->normalFont, okButton,
443 strlen(okButton));
445 w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
446 if (aw > w)
447 w = aw;
449 w += 30;
450 x = 310;
452 if (okButton) {
453 x -= w + 10;
455 panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
456 |WBBPushChangeMask
457 |WBBPushLightMask);
458 WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
459 WMMoveWidget(panel->defBtn, x, 124);
460 WMResizeWidget(panel->defBtn, w, 24);
461 WMSetButtonText(panel->defBtn, okButton);
462 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
463 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
464 WMSetButtonImagePosition(panel->defBtn, WIPRight);
466 if (cancelButton) {
467 x -= w + 10;
469 panel->altBtn = WMCreateCommandButton(panel->win);
470 WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
471 WMMoveWidget(panel->altBtn, x, 124);
472 WMResizeWidget(panel->altBtn, w, 24);
473 WMSetButtonText(panel->altBtn, cancelButton);
476 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
477 handleKeyPress2, panel);
479 WMRealizeWidget(panel->win);
480 WMMapSubwidgets(panel->win);
482 WMSetFocusToWidget(panel->text);
484 return panel;
490 static void
491 handleKeyPress3(XEvent *event, void *clientData)
493 WMGenericPanel *panel = (WMGenericPanel*)clientData;
494 KeySym ksym;
496 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
498 if (ksym == XK_Return && panel->defBtn) {
499 WMPerformButtonClick(panel->defBtn);
500 } else if (ksym == XK_Escape) {
501 if (panel->altBtn) {
502 WMPerformButtonClick(panel->altBtn);
503 } else {
504 panel->result = WAPRDefault;
505 WMBreakModalLoop(WMWidgetScreen(panel->win));
511 void
512 WMDestroyGenericPanel(WMGenericPanel *panel)
514 WMUnmapWidget(panel->win);
515 WMDestroyWidget(panel->win);
516 wfree(panel);
520 WMGenericPanel*
521 WMCreateGenericPanel(WMScreen *scrPtr, WMWindow *owner,
522 char *title, char *defaultButton,
523 char *alternateButton)
525 WMGenericPanel *panel;
526 int dw=0, aw=0, w;
527 WMBox *hbox;
528 WMPixmap *icon;
531 panel = wmalloc(sizeof(WMGenericPanel));
532 memset(panel, 0, sizeof(WMGenericPanel));
534 if (owner) {
535 panel->win = WMCreatePanelWithStyleForWindow(owner, "genericPanel",
536 WMTitledWindowMask);
537 } else {
538 panel->win = WMCreateWindowWithStyle(scrPtr, "genericPanel",
539 WMTitledWindowMask);
542 WMSetWindowInitialPosition(panel->win,
543 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win))/2,
544 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win))/2);
546 WMSetWindowTitle(panel->win, "");
548 panel->vbox = WMCreateBox(panel->win);
549 WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
550 WMSetBoxHorizontal(panel->vbox, False);
551 WMMapWidget(panel->vbox);
553 hbox = WMCreateBox(panel->vbox);
554 WMSetBoxBorderWidth(hbox, 5);
555 WMSetBoxHorizontal(hbox, True);
556 WMMapWidget(hbox);
557 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
559 panel->iLbl = WMCreateLabel(hbox);
560 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
561 WMMapWidget(panel->iLbl);
562 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
563 icon = WMGetApplicationIconBlendedPixmap(scrPtr, (RColor*)NULL);
564 if (icon) {
565 WMSetLabelImage(panel->iLbl, icon);
566 WMReleasePixmap(icon);
567 } else {
568 WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
571 if (title) {
572 WMFont *largeFont;
574 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
576 panel->tLbl = WMCreateLabel(hbox);
577 WMMapWidget(panel->tLbl);
578 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True,
579 64, 0, 0);
580 WMSetLabelText(panel->tLbl, title);
581 WMSetLabelTextAlignment(panel->tLbl, WALeft);
582 WMSetLabelFont(panel->tLbl, largeFont);
584 WMReleaseFont(largeFont);
587 /* create divider line */
589 panel->line = WMCreateFrame(panel->vbox);
590 WMMapWidget(panel->line);
591 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True,
592 2, 2, 5);
593 WMSetFrameRelief(panel->line, WRGroove);
596 panel->content = WMCreateFrame(panel->vbox);
597 WMMapWidget(panel->content);
598 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->content), True, True,
599 50, 0, 5);
600 WMSetFrameRelief(panel->content, WRFlat);
602 hbox = WMCreateBox(panel->vbox);
603 WMSetBoxBorderWidth(hbox, 10);
604 WMSetBoxHorizontal(hbox, True);
605 WMMapWidget(hbox);
606 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
608 /* create buttons */
609 if (defaultButton)
610 dw = WMWidthOfString(scrPtr->normalFont, defaultButton,
611 strlen(defaultButton));
613 if (alternateButton)
614 aw = WMWidthOfString(scrPtr->normalFont, alternateButton,
615 strlen(alternateButton));
618 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
620 aw += 30;
621 dw += 30;
623 w = WMAX(dw, aw);
624 if ((w+10)*2 < 400) {
625 aw = w;
626 dw = w;
627 } else {
628 int t;
630 t = 400 - 40 - aw - dw;
631 aw += t/2;
632 dw += t/2;
635 if (defaultButton) {
636 panel->defBtn = WMCreateCommandButton(hbox);
637 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
638 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn),
639 False, True, dw, 0, 0);
640 WMSetButtonText(panel->defBtn, defaultButton);
641 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
642 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
643 WMSetButtonImagePosition(panel->defBtn, WIPRight);
646 WMMapSubwidgets(hbox);
648 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
649 handleKeyPress3, panel);
651 WMRealizeWidget(panel->win);
652 WMMapSubwidgets(panel->win);
654 return panel;