4 #include <X11/keysym.h>
7 static void alertPanelOnClick(WMWidget
* self
, void *clientData
)
9 WMAlertPanel
*panel
= clientData
;
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
;
21 static void handleKeyPress(XEvent
* event
, void *clientData
)
23 WMAlertPanel
*panel
= (WMAlertPanel
*) clientData
;
26 XLookupString(&event
->xkey
, NULL
, 0, &ksym
, NULL
);
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
);
34 panel
->result
= WAPRDefault
;
35 WMBreakModalLoop(WMWidgetScreen(panel
->win
));
41 WMRunAlertPanel(WMScreen
* scrPtr
, WMWindow
* owner
,
42 const char *title
, const char *msg
, const char *defaultButton
, const char *alternateButton
, const char *otherButton
)
47 panel
= WMCreateAlertPanel(scrPtr
, owner
, title
, msg
, defaultButton
, alternateButton
, otherButton
);
51 WMView
*view
= WMWidgetView(panel
->win
);
54 WMView
*oview
= WMWidgetView(owner
);
55 WMPoint pt
= WMGetViewScreenPosition(oview
);
57 px
= (W_VIEW_WIDTH(oview
) - W_VIEW_WIDTH(view
)) / 2;
58 py
= (W_VIEW_HEIGHT(oview
) - W_VIEW_HEIGHT(view
)) / 2;
63 px
= (W_VIEW_WIDTH(scrPtr
->rootView
) - W_VIEW_WIDTH(view
)) / 2;
64 py
= (W_VIEW_HEIGHT(scrPtr
->rootView
) - W_VIEW_HEIGHT(view
)) / 2;
66 WMSetWindowInitialPosition(panel
->win
, px
, py
);
69 WMMapWidget(panel
->win
);
71 WMRunModalLoop(scrPtr
, W_VIEW(panel
->win
));
75 WMDestroyAlertPanel(panel
);
80 void WMDestroyAlertPanel(WMAlertPanel
* panel
)
82 WMUnmapWidget(panel
->win
);
83 WMDestroyWidget(panel
->win
);
87 WMAlertPanel
*WMCreateAlertPanel(WMScreen
* scrPtr
, WMWindow
* owner
,
88 const char *title
, const char *msg
, const char *defaultButton
,
89 const char *alternateButton
, const char *otherButton
)
92 int dw
= 0, aw
= 0, ow
= 0, w
;
98 panel
= wmalloc(sizeof(WMAlertPanel
));
101 panel
->win
= WMCreatePanelWithStyleForWindow(owner
, "alertPanel", WMTitledWindowMask
);
103 panel
->win
= WMCreateWindowWithStyle(scrPtr
, "alertPanel", WMTitledWindowMask
);
106 /* calculate and set the panel's size */
107 WMGetScaleBaseFromSystemFont(scrPtr
, &fw
, &fh
);
108 pwidth
= ScaleX(400);
109 pheight
= ScaleY(5) /* upper margin */
111 + ScaleY(5) /* space between icon and divider line */
112 + 2 /* divider line */
113 + ScaleY(5); /* space between divider line and message */
115 pheight
+= WMFontHeight(scrPtr
->normalFont
) * 4 + ScaleY(5);
116 pheight
+= ScaleY(44);
117 WMResizeWidget(panel
->win
, pwidth
, pheight
);
119 WMSetWindowInitialPosition(panel
->win
,
120 (scrPtr
->rootView
->size
.width
- pwidth
) / 2,
121 (scrPtr
->rootView
->size
.height
- pheight
) / 2);
123 WMSetWindowTitle(panel
->win
, "");
125 panel
->vbox
= WMCreateBox(panel
->win
);
126 WMSetViewExpandsToParent(WMWidgetView(panel
->vbox
), 0, 0, 0, 0);
127 WMSetBoxHorizontal(panel
->vbox
, False
);
128 WMMapWidget(panel
->vbox
);
130 hbox
= WMCreateBox(panel
->vbox
);
131 WMSetBoxBorderWidth(hbox
, ScaleX(5));
132 WMSetBoxHorizontal(hbox
, True
);
134 WMAddBoxSubview(panel
->vbox
, WMWidgetView(hbox
), False
, True
, 64 + 2 * ScaleY(5), 0, ScaleY(5));
136 panel
->iLbl
= WMCreateLabel(hbox
);
137 WMSetLabelImagePosition(panel
->iLbl
, WIPImageOnly
);
138 WMMapWidget(panel
->iLbl
);
139 WMAddBoxSubview(hbox
, WMWidgetView(panel
->iLbl
), False
, True
, 64, 0, 10);
140 icon
= WMCreateApplicationIconBlendedPixmap(scrPtr
, (RColor
*) NULL
);
142 WMSetLabelImage(panel
->iLbl
, icon
);
143 WMReleasePixmap(icon
);
145 WMSetLabelImage(panel
->iLbl
, scrPtr
->applicationIconPixmap
);
151 largeFont
= WMBoldSystemFontOfSize(scrPtr
, 24);
153 panel
->tLbl
= WMCreateLabel(hbox
);
154 WMMapWidget(panel
->tLbl
);
155 WMAddBoxSubview(hbox
, WMWidgetView(panel
->tLbl
), True
, True
, 64, 0, 0);
156 WMSetLabelText(panel
->tLbl
, title
);
157 WMSetLabelTextAlignment(panel
->tLbl
, WALeft
);
158 WMSetLabelFont(panel
->tLbl
, largeFont
);
160 WMReleaseFont(largeFont
);
163 /* create divider line */
165 panel
->line
= WMCreateFrame(panel
->win
);
166 WMMapWidget(panel
->line
);
167 WMAddBoxSubview(panel
->vbox
, WMWidgetView(panel
->line
), False
, True
, 2, 2, ScaleY(5));
168 WMSetFrameRelief(panel
->line
, WRGroove
);
171 panel
->mLbl
= WMCreateLabel(panel
->vbox
);
172 WMSetLabelWraps(panel
->mLbl
, True
);
173 WMMapWidget(panel
->mLbl
);
174 WMAddBoxSubview(panel
->vbox
, WMWidgetView(panel
->mLbl
), True
, True
,
175 WMFontHeight(scrPtr
->normalFont
) * 4, 0, ScaleY(5));
176 WMSetLabelText(panel
->mLbl
, msg
);
177 WMSetLabelTextAlignment(panel
->mLbl
, WACenter
);
180 panel
->hbox
= WMCreateBox(panel
->vbox
);
181 WMSetBoxBorderWidth(panel
->hbox
, ScaleX(10));
182 WMSetBoxHorizontal(panel
->hbox
, True
);
183 WMMapWidget(panel
->hbox
);
184 WMAddBoxSubview(panel
->vbox
, WMWidgetView(panel
->hbox
), False
, True
, ScaleY(44), 0, 0);
188 ow
= WMWidthOfString(scrPtr
->normalFont
, otherButton
, strlen(otherButton
));
191 aw
= WMWidthOfString(scrPtr
->normalFont
, alternateButton
, strlen(alternateButton
));
194 dw
= WMWidthOfString(scrPtr
->normalFont
, defaultButton
, strlen(defaultButton
));
196 dw
= dw
+ (scrPtr
->buttonArrow
? scrPtr
->buttonArrow
->width
: 0);
202 w
= WMAX(dw
, WMAX(aw
, ow
));
203 if ((w
+ ScaleX(10)) * 3 < pwidth
) {
210 t
= pwidth
- 4 * ScaleX(10) - aw
- ow
- dw
;
217 panel
->defBtn
= WMCreateCommandButton(panel
->hbox
);
218 WMResizeWidget(panel
->defBtn
, dw
, ScaleY(24));
219 WMSetButtonAction(panel
->defBtn
, alertPanelOnClick
, panel
);
220 WMAddBoxSubviewAtEnd(panel
->hbox
, WMWidgetView(panel
->defBtn
), False
, True
, dw
, 0, 0);
221 WMSetButtonText(panel
->defBtn
, defaultButton
);
222 WMSetButtonImage(panel
->defBtn
, scrPtr
->buttonArrow
);
223 WMSetButtonAltImage(panel
->defBtn
, scrPtr
->pushedButtonArrow
);
224 WMSetButtonImagePosition(panel
->defBtn
, WIPRight
);
226 if (alternateButton
) {
227 panel
->altBtn
= WMCreateCommandButton(panel
->hbox
);
228 WMResizeWidget(panel
->altBtn
, aw
, ScaleY(24));
229 WMAddBoxSubviewAtEnd(panel
->hbox
, WMWidgetView(panel
->altBtn
), False
, True
, aw
, 0, ScaleX(5));
230 WMSetButtonAction(panel
->altBtn
, alertPanelOnClick
, panel
);
231 WMSetButtonText(panel
->altBtn
, alternateButton
);
234 panel
->othBtn
= WMCreateCommandButton(panel
->hbox
);
235 WMResizeWidget(panel
->othBtn
, ow
, ScaleY(24));
236 WMSetButtonAction(panel
->othBtn
, alertPanelOnClick
, panel
);
237 WMAddBoxSubviewAtEnd(panel
->hbox
, WMWidgetView(panel
->othBtn
), False
, True
, ow
, 0, ScaleX(5));
238 WMSetButtonText(panel
->othBtn
, otherButton
);
241 WMMapSubwidgets(panel
->hbox
);
243 WMCreateEventHandler(W_VIEW(panel
->win
), KeyPressMask
, handleKeyPress
, panel
);
245 WMRealizeWidget(panel
->win
);
246 WMMapSubwidgets(panel
->win
);
251 static void inputBoxOnClick(WMWidget
* self
, void *clientData
)
253 WMInputPanel
*panel
= clientData
;
255 WMBreakModalLoop(WMWidgetScreen(self
));
256 if (self
== panel
->defBtn
) {
257 panel
->result
= WAPRDefault
;
258 } else if (self
== panel
->altBtn
) {
259 panel
->result
= WAPRAlternate
;
263 static void handleKeyPress2(XEvent
* event
, void *clientData
)
265 WMInputPanel
*panel
= (WMInputPanel
*) clientData
;
268 XLookupString(&event
->xkey
, NULL
, 0, &ksym
, NULL
);
270 if (ksym
== XK_Return
&& panel
->defBtn
) {
271 WMPerformButtonClick(panel
->defBtn
);
272 } else if (ksym
== XK_Escape
) {
274 WMPerformButtonClick(panel
->altBtn
);
276 /* printf("got esc\n"); */
277 WMBreakModalLoop(WMWidgetScreen(panel
->win
));
278 panel
->result
= WAPRDefault
;
283 char *WMRunInputPanel(WMScreen
* scrPtr
, WMWindow
* owner
, const char *title
,
284 const char *msg
, const char *defaultText
, const char *okButton
, const char *cancelButton
)
289 panel
= WMCreateInputPanel(scrPtr
, owner
, title
, msg
, defaultText
, okButton
, cancelButton
);
293 WMView
*view
= WMWidgetView(panel
->win
);
296 WMView
*oview
= WMWidgetView(owner
);
297 WMPoint pt
= WMGetViewScreenPosition(oview
);
299 px
= (W_VIEW_WIDTH(oview
) - W_VIEW_WIDTH(view
)) / 2;
300 py
= (W_VIEW_HEIGHT(oview
) - W_VIEW_HEIGHT(view
)) / 2;
305 px
= (W_VIEW_WIDTH(scrPtr
->rootView
) - W_VIEW_WIDTH(view
)) / 2;
306 py
= (W_VIEW_HEIGHT(scrPtr
->rootView
) - W_VIEW_HEIGHT(view
)) / 2;
308 WMSetWindowInitialPosition(panel
->win
, px
, py
);
311 WMMapWidget(panel
->win
);
313 WMRunModalLoop(scrPtr
, W_VIEW(panel
->win
));
315 if (panel
->result
== WAPRDefault
)
316 tmp
= WMGetTextFieldText(panel
->text
);
320 WMDestroyInputPanel(panel
);
325 void WMDestroyInputPanel(WMInputPanel
* panel
)
327 WMRemoveNotificationObserver(panel
);
328 WMUnmapWidget(panel
->win
);
329 WMDestroyWidget(panel
->win
);
333 static void endedEditingObserver(void *observerData
, WMNotification
* notification
)
335 WMInputPanel
*panel
= (WMInputPanel
*) observerData
;
337 switch ((uintptr_t)WMGetNotificationClientData(notification
)) {
338 case WMReturnTextMovement
:
340 WMPerformButtonClick(panel
->defBtn
);
342 case WMEscapeTextMovement
:
344 WMPerformButtonClick(panel
->altBtn
);
346 WMBreakModalLoop(WMWidgetScreen(panel
->win
));
347 panel
->result
= WAPRDefault
;
355 WMInputPanel
*WMCreateInputPanel(WMScreen
* scrPtr
, WMWindow
* owner
, const char *title
, const char *msg
,
356 const char *defaultText
, const char *okButton
, const char *cancelButton
)
359 int x
, dw
= 0, aw
= 0, w
;
361 panel
= wmalloc(sizeof(WMInputPanel
));
364 panel
->win
= WMCreatePanelWithStyleForWindow(owner
, "inputPanel", WMTitledWindowMask
);
366 panel
->win
= WMCreateWindowWithStyle(scrPtr
, "inputPanel", WMTitledWindowMask
);
367 WMSetWindowTitle(panel
->win
, "");
369 WMResizeWidget(panel
->win
, 320, 160);
374 largeFont
= WMBoldSystemFontOfSize(scrPtr
, 24);
376 panel
->tLbl
= WMCreateLabel(panel
->win
);
377 WMMoveWidget(panel
->tLbl
, 20, 16);
378 WMResizeWidget(panel
->tLbl
, 320 - 40, WMFontHeight(largeFont
) + 4);
379 WMSetLabelText(panel
->tLbl
, title
);
380 WMSetLabelTextAlignment(panel
->tLbl
, WALeft
);
381 WMSetLabelFont(panel
->tLbl
, largeFont
);
383 WMReleaseFont(largeFont
);
387 panel
->mLbl
= WMCreateLabel(panel
->win
);
388 WMMoveWidget(panel
->mLbl
, 20, 50);
389 WMResizeWidget(panel
->mLbl
, 320 - 40, WMFontHeight(scrPtr
->normalFont
) * 2);
390 WMSetLabelText(panel
->mLbl
, msg
);
391 WMSetLabelTextAlignment(panel
->mLbl
, WALeft
);
394 panel
->text
= WMCreateTextField(panel
->win
);
395 WMMoveWidget(panel
->text
, 20, 85);
396 WMResizeWidget(panel
->text
, 320 - 40, WMWidgetHeight(panel
->text
));
397 WMSetTextFieldText(panel
->text
, defaultText
);
399 WMAddNotificationObserver(endedEditingObserver
, panel
, WMTextDidEndEditingNotification
, panel
->text
);
403 aw
= WMWidthOfString(scrPtr
->normalFont
, cancelButton
, strlen(cancelButton
));
406 dw
= WMWidthOfString(scrPtr
->normalFont
, okButton
, strlen(okButton
));
408 w
= dw
+ (scrPtr
->buttonArrow
? scrPtr
->buttonArrow
->width
: 0);
418 panel
->defBtn
= WMCreateCustomButton(panel
->win
, WBBPushInMask
419 | WBBPushChangeMask
| WBBPushLightMask
);
420 WMSetButtonAction(panel
->defBtn
, inputBoxOnClick
, panel
);
421 WMMoveWidget(panel
->defBtn
, x
, 124);
422 WMResizeWidget(panel
->defBtn
, w
, 24);
423 WMSetButtonText(panel
->defBtn
, okButton
);
424 WMSetButtonImage(panel
->defBtn
, scrPtr
->buttonArrow
);
425 WMSetButtonAltImage(panel
->defBtn
, scrPtr
->pushedButtonArrow
);
426 WMSetButtonImagePosition(panel
->defBtn
, WIPRight
);
431 panel
->altBtn
= WMCreateCommandButton(panel
->win
);
432 WMSetButtonAction(panel
->altBtn
, inputBoxOnClick
, panel
);
433 WMMoveWidget(panel
->altBtn
, x
, 124);
434 WMResizeWidget(panel
->altBtn
, w
, 24);
435 WMSetButtonText(panel
->altBtn
, cancelButton
);
438 WMCreateEventHandler(W_VIEW(panel
->win
), KeyPressMask
, handleKeyPress2
, panel
);
440 WMRealizeWidget(panel
->win
);
441 WMMapSubwidgets(panel
->win
);
443 WMSetFocusToWidget(panel
->text
);
448 static void handleKeyPress3(XEvent
* event
, void *clientData
)
450 WMGenericPanel
*panel
= (WMGenericPanel
*) clientData
;
453 XLookupString(&event
->xkey
, NULL
, 0, &ksym
, NULL
);
455 if (ksym
== XK_Return
&& panel
->defBtn
) {
456 WMPerformButtonClick(panel
->defBtn
);
457 } else if (ksym
== XK_Escape
) {
459 WMPerformButtonClick(panel
->altBtn
);
461 panel
->result
= WAPRDefault
;
462 WMBreakModalLoop(WMWidgetScreen(panel
->win
));
467 void WMDestroyGenericPanel(WMGenericPanel
* panel
)
469 WMUnmapWidget(panel
->win
);
470 WMDestroyWidget(panel
->win
);
474 WMGenericPanel
*WMCreateGenericPanel(WMScreen
* scrPtr
, WMWindow
* owner
,
475 const char *title
, const char *defaultButton
, const char *alternateButton
)
477 WMGenericPanel
*panel
;
478 int dw
= 0, aw
= 0, w
;
482 panel
= wmalloc(sizeof(WMGenericPanel
));
485 panel
->win
= WMCreatePanelWithStyleForWindow(owner
, "genericPanel", WMTitledWindowMask
);
487 panel
->win
= WMCreateWindowWithStyle(scrPtr
, "genericPanel", WMTitledWindowMask
);
490 WMSetWindowInitialPosition(panel
->win
,
491 (scrPtr
->rootView
->size
.width
- WMWidgetWidth(panel
->win
)) / 2,
492 (scrPtr
->rootView
->size
.height
- WMWidgetHeight(panel
->win
)) / 2);
494 WMSetWindowTitle(panel
->win
, "");
496 panel
->vbox
= WMCreateBox(panel
->win
);
497 WMSetViewExpandsToParent(WMWidgetView(panel
->vbox
), 0, 0, 0, 0);
498 WMSetBoxHorizontal(panel
->vbox
, False
);
499 WMMapWidget(panel
->vbox
);
501 hbox
= WMCreateBox(panel
->vbox
);
502 WMSetBoxBorderWidth(hbox
, 5);
503 WMSetBoxHorizontal(hbox
, True
);
505 WMAddBoxSubview(panel
->vbox
, WMWidgetView(hbox
), False
, True
, 74, 0, 5);
507 panel
->iLbl
= WMCreateLabel(hbox
);
508 WMSetLabelImagePosition(panel
->iLbl
, WIPImageOnly
);
509 WMMapWidget(panel
->iLbl
);
510 WMAddBoxSubview(hbox
, WMWidgetView(panel
->iLbl
), False
, True
, 64, 0, 10);
511 icon
= WMCreateApplicationIconBlendedPixmap(scrPtr
, (RColor
*) NULL
);
513 WMSetLabelImage(panel
->iLbl
, icon
);
514 WMReleasePixmap(icon
);
516 WMSetLabelImage(panel
->iLbl
, scrPtr
->applicationIconPixmap
);
522 largeFont
= WMBoldSystemFontOfSize(scrPtr
, 24);
524 panel
->tLbl
= WMCreateLabel(hbox
);
525 WMMapWidget(panel
->tLbl
);
526 WMAddBoxSubview(hbox
, WMWidgetView(panel
->tLbl
), True
, True
, 64, 0, 0);
527 WMSetLabelText(panel
->tLbl
, title
);
528 WMSetLabelTextAlignment(panel
->tLbl
, WALeft
);
529 WMSetLabelFont(panel
->tLbl
, largeFont
);
531 WMReleaseFont(largeFont
);
534 /* create divider line */
536 panel
->line
= WMCreateFrame(panel
->vbox
);
537 WMMapWidget(panel
->line
);
538 WMAddBoxSubview(panel
->vbox
, WMWidgetView(panel
->line
), False
, True
, 2, 2, 5);
539 WMSetFrameRelief(panel
->line
, WRGroove
);
541 panel
->content
= WMCreateFrame(panel
->vbox
);
542 WMMapWidget(panel
->content
);
543 WMAddBoxSubview(panel
->vbox
, WMWidgetView(panel
->content
), True
, True
, 50, 0, 5);
544 WMSetFrameRelief(panel
->content
, WRFlat
);
546 hbox
= WMCreateBox(panel
->vbox
);
547 WMSetBoxBorderWidth(hbox
, 10);
548 WMSetBoxHorizontal(hbox
, True
);
550 WMAddBoxSubview(panel
->vbox
, WMWidgetView(hbox
), False
, True
, 44, 0, 0);
554 dw
= WMWidthOfString(scrPtr
->normalFont
, defaultButton
, strlen(defaultButton
));
557 aw
= WMWidthOfString(scrPtr
->normalFont
, alternateButton
, strlen(alternateButton
));
559 dw
= dw
+ (scrPtr
->buttonArrow
? scrPtr
->buttonArrow
->width
: 0);
565 if ((w
+ 10) * 2 < 400) {
570 t
= 400 - 40 - aw
- dw
;
575 panel
->defBtn
= WMCreateCommandButton(hbox
);
576 WMSetButtonAction(panel
->defBtn
, alertPanelOnClick
, panel
);
577 WMAddBoxSubviewAtEnd(hbox
, WMWidgetView(panel
->defBtn
), False
, True
, dw
, 0, 0);
578 WMSetButtonText(panel
->defBtn
, defaultButton
);
579 WMSetButtonImage(panel
->defBtn
, scrPtr
->buttonArrow
);
580 WMSetButtonAltImage(panel
->defBtn
, scrPtr
->pushedButtonArrow
);
581 WMSetButtonImagePosition(panel
->defBtn
, WIPRight
);
584 WMMapSubwidgets(hbox
);
586 WMCreateEventHandler(W_VIEW(panel
->win
), KeyPressMask
, handleKeyPress3
, panel
);
588 WMRealizeWidget(panel
->win
);
589 WMMapSubwidgets(panel
->win
);