Allow struts from all windows.
[wmaker-crm.git] / WINGs / wpanel.c
blob7e3f9f590ec2e32b4582b6fe59ca8bb38ace5091
2 #include "WINGsP.h"
4 #include <X11/keysym.h>
5 #include <stdint.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;
24 KeySym ksym;
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);
33 } else {
34 panel->result = WAPRDefault;
35 WMBreakModalLoop(WMWidgetScreen(panel->win));
40 int
41 WMRunAlertPanel(WMScreen * scrPtr, WMWindow * owner,
42 char *title, char *msg, char *defaultButton, char *alternateButton, char *otherButton)
44 WMAlertPanel *panel;
45 int tmp;
47 panel = WMCreateAlertPanel(scrPtr, owner, title, msg, defaultButton, alternateButton, otherButton);
50 int px, py;
51 WMView *view = WMWidgetView(panel->win);
53 if (owner) {
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;
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;
66 WMSetWindowInitialPosition(panel->win, px, py);
69 WMMapWidget(panel->win);
71 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
73 tmp = panel->result;
75 WMDestroyAlertPanel(panel);
77 return tmp;
80 void WMDestroyAlertPanel(WMAlertPanel * panel)
82 WMUnmapWidget(panel->win);
83 WMDestroyWidget(panel->win);
84 wfree(panel);
87 WMAlertPanel *WMCreateAlertPanel(WMScreen * scrPtr, WMWindow * owner,
88 char *title, char *msg, char *defaultButton,
89 char *alternateButton, char *otherButton)
91 WMAlertPanel *panel;
92 int dw = 0, aw = 0, ow = 0, w;
93 WMBox *hbox;
94 WMPixmap *icon;
96 panel = wmalloc(sizeof(WMAlertPanel));
98 if (owner) {
99 panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel", WMTitledWindowMask);
100 } else {
101 panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel", WMTitledWindowMask);
104 WMSetWindowInitialPosition(panel->win,
105 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win)) / 2,
106 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win)) / 2);
108 WMSetWindowTitle(panel->win, "");
110 panel->vbox = WMCreateBox(panel->win);
111 WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
112 WMSetBoxHorizontal(panel->vbox, False);
113 WMMapWidget(panel->vbox);
115 hbox = WMCreateBox(panel->vbox);
116 WMSetBoxBorderWidth(hbox, 5);
117 WMSetBoxHorizontal(hbox, True);
118 WMMapWidget(hbox);
119 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
121 panel->iLbl = WMCreateLabel(hbox);
122 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
123 WMMapWidget(panel->iLbl);
124 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
125 icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL);
126 if (icon) {
127 WMSetLabelImage(panel->iLbl, icon);
128 WMReleasePixmap(icon);
129 } else {
130 WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
133 if (title) {
134 WMFont *largeFont;
136 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
138 panel->tLbl = WMCreateLabel(hbox);
139 WMMapWidget(panel->tLbl);
140 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True, 64, 0, 0);
141 WMSetLabelText(panel->tLbl, title);
142 WMSetLabelTextAlignment(panel->tLbl, WALeft);
143 WMSetLabelFont(panel->tLbl, largeFont);
145 WMReleaseFont(largeFont);
148 /* create divider line */
150 panel->line = WMCreateFrame(panel->win);
151 WMMapWidget(panel->line);
152 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True, 2, 2, 5);
153 WMSetFrameRelief(panel->line, WRGroove);
155 if (msg) {
156 panel->mLbl = WMCreateLabel(panel->vbox);
157 WMSetLabelWraps(panel->mLbl, True);
158 WMMapWidget(panel->mLbl);
159 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->mLbl), True, True,
160 WMFontHeight(scrPtr->normalFont) * 4, 0, 5);
161 WMSetLabelText(panel->mLbl, msg);
162 WMSetLabelTextAlignment(panel->mLbl, WACenter);
165 panel->hbox = WMCreateBox(panel->vbox);
166 WMSetBoxBorderWidth(panel->hbox, 10);
167 WMSetBoxHorizontal(panel->hbox, True);
168 WMMapWidget(panel->hbox);
169 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->hbox), False, True, 44, 0, 0);
171 /* create buttons */
172 if (otherButton)
173 ow = WMWidthOfString(scrPtr->normalFont, otherButton, strlen(otherButton));
175 if (alternateButton)
176 aw = WMWidthOfString(scrPtr->normalFont, alternateButton, strlen(alternateButton));
178 if (defaultButton)
179 dw = WMWidthOfString(scrPtr->normalFont, defaultButton, strlen(defaultButton));
181 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
183 aw += 30;
184 ow += 30;
185 dw += 30;
187 w = WMAX(dw, WMAX(aw, ow));
188 if ((w + 10) * 3 < 400) {
189 aw = w;
190 ow = w;
191 dw = w;
192 } else {
193 int t;
195 t = 400 - 40 - aw - ow - dw;
196 aw += t / 3;
197 ow += t / 3;
198 dw += t / 3;
201 if (defaultButton) {
202 panel->defBtn = WMCreateCommandButton(panel->hbox);
203 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
204 WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->defBtn), False, True, dw, 0, 0);
205 WMSetButtonText(panel->defBtn, defaultButton);
206 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
207 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
208 WMSetButtonImagePosition(panel->defBtn, WIPRight);
210 if (alternateButton) {
211 panel->altBtn = WMCreateCommandButton(panel->hbox);
212 WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->altBtn), False, True, aw, 0, 5);
213 WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
214 WMSetButtonText(panel->altBtn, alternateButton);
216 if (otherButton) {
217 panel->othBtn = WMCreateCommandButton(panel->hbox);
218 WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
219 WMAddBoxSubviewAtEnd(panel->hbox, WMWidgetView(panel->othBtn), False, True, ow, 0, 5);
220 WMSetButtonText(panel->othBtn, otherButton);
223 WMMapSubwidgets(panel->hbox);
225 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress, panel);
227 WMRealizeWidget(panel->win);
228 WMMapSubwidgets(panel->win);
230 return panel;
233 static void inputBoxOnClick(WMWidget * self, void *clientData)
235 WMInputPanel *panel = clientData;
237 WMBreakModalLoop(WMWidgetScreen(self));
238 if (self == panel->defBtn) {
239 panel->result = WAPRDefault;
240 } else if (self == panel->altBtn) {
241 panel->result = WAPRAlternate;
245 static void handleKeyPress2(XEvent * event, void *clientData)
247 WMInputPanel *panel = (WMInputPanel *) clientData;
248 KeySym ksym;
250 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
252 if (ksym == XK_Return && panel->defBtn) {
253 WMPerformButtonClick(panel->defBtn);
254 } else if (ksym == XK_Escape) {
255 if (panel->altBtn) {
256 WMPerformButtonClick(panel->altBtn);
257 } else {
258 /* printf("got esc\n"); */
259 WMBreakModalLoop(WMWidgetScreen(panel->win));
260 panel->result = WAPRDefault;
265 char *WMRunInputPanel(WMScreen * scrPtr, WMWindow * owner, char *title,
266 char *msg, char *defaultText, char *okButton, char *cancelButton)
268 WMInputPanel *panel;
269 char *tmp;
271 panel = WMCreateInputPanel(scrPtr, owner, title, msg, defaultText, okButton, cancelButton);
274 int px, py;
275 WMView *view = WMWidgetView(panel->win);
277 if (owner) {
278 WMView *oview = WMWidgetView(owner);
279 WMPoint pt = WMGetViewScreenPosition(oview);
281 px = (W_VIEW_WIDTH(oview) - W_VIEW_WIDTH(view)) / 2;
282 py = (W_VIEW_HEIGHT(oview) - W_VIEW_HEIGHT(view)) / 2;
284 px += pt.x;
285 py += pt.y;
286 } else {
287 px = (W_VIEW_WIDTH(scrPtr->rootView) - W_VIEW_WIDTH(view)) / 2;
288 py = (W_VIEW_HEIGHT(scrPtr->rootView) - W_VIEW_HEIGHT(view)) / 2;
290 WMSetWindowInitialPosition(panel->win, px, py);
293 WMMapWidget(panel->win);
295 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
297 if (panel->result == WAPRDefault)
298 tmp = WMGetTextFieldText(panel->text);
299 else
300 tmp = NULL;
302 WMDestroyInputPanel(panel);
304 return tmp;
307 void WMDestroyInputPanel(WMInputPanel * panel)
309 WMRemoveNotificationObserver(panel);
310 WMUnmapWidget(panel->win);
311 WMDestroyWidget(panel->win);
312 wfree(panel);
315 static void endedEditingObserver(void *observerData, WMNotification * notification)
317 WMInputPanel *panel = (WMInputPanel *) observerData;
319 switch ((uintptr_t)WMGetNotificationClientData(notification)) {
320 case WMReturnTextMovement:
321 if (panel->defBtn)
322 WMPerformButtonClick(panel->defBtn);
323 break;
324 case WMEscapeTextMovement:
325 if (panel->altBtn)
326 WMPerformButtonClick(panel->altBtn);
327 else {
328 WMBreakModalLoop(WMWidgetScreen(panel->win));
329 panel->result = WAPRDefault;
331 break;
332 default:
333 break;
337 WMInputPanel *WMCreateInputPanel(WMScreen * scrPtr, WMWindow * owner, char *title, char *msg,
338 char *defaultText, char *okButton, char *cancelButton)
340 WMInputPanel *panel;
341 int x, dw = 0, aw = 0, w;
343 panel = wmalloc(sizeof(WMInputPanel));
345 if (owner)
346 panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel", WMTitledWindowMask);
347 else
348 panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel", WMTitledWindowMask);
349 WMSetWindowTitle(panel->win, "");
351 WMResizeWidget(panel->win, 320, 160);
353 if (title) {
354 WMFont *largeFont;
356 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
358 panel->tLbl = WMCreateLabel(panel->win);
359 WMMoveWidget(panel->tLbl, 20, 16);
360 WMResizeWidget(panel->tLbl, 320 - 40, WMFontHeight(largeFont) + 4);
361 WMSetLabelText(panel->tLbl, title);
362 WMSetLabelTextAlignment(panel->tLbl, WALeft);
363 WMSetLabelFont(panel->tLbl, largeFont);
365 WMReleaseFont(largeFont);
368 if (msg) {
369 panel->mLbl = WMCreateLabel(panel->win);
370 WMMoveWidget(panel->mLbl, 20, 50);
371 WMResizeWidget(panel->mLbl, 320 - 40, WMFontHeight(scrPtr->normalFont) * 2);
372 WMSetLabelText(panel->mLbl, msg);
373 WMSetLabelTextAlignment(panel->mLbl, WALeft);
376 panel->text = WMCreateTextField(panel->win);
377 WMMoveWidget(panel->text, 20, 85);
378 WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
379 WMSetTextFieldText(panel->text, defaultText);
381 WMAddNotificationObserver(endedEditingObserver, panel, WMTextDidEndEditingNotification, panel->text);
383 /* create buttons */
384 if (cancelButton)
385 aw = WMWidthOfString(scrPtr->normalFont, cancelButton, strlen(cancelButton));
387 if (okButton)
388 dw = WMWidthOfString(scrPtr->normalFont, okButton, strlen(okButton));
390 w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
391 if (aw > w)
392 w = aw;
394 w += 30;
395 x = 310;
397 if (okButton) {
398 x -= w + 10;
400 panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
401 | WBBPushChangeMask | WBBPushLightMask);
402 WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
403 WMMoveWidget(panel->defBtn, x, 124);
404 WMResizeWidget(panel->defBtn, w, 24);
405 WMSetButtonText(panel->defBtn, okButton);
406 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
407 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
408 WMSetButtonImagePosition(panel->defBtn, WIPRight);
410 if (cancelButton) {
411 x -= w + 10;
413 panel->altBtn = WMCreateCommandButton(panel->win);
414 WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
415 WMMoveWidget(panel->altBtn, x, 124);
416 WMResizeWidget(panel->altBtn, w, 24);
417 WMSetButtonText(panel->altBtn, cancelButton);
420 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress2, panel);
422 WMRealizeWidget(panel->win);
423 WMMapSubwidgets(panel->win);
425 WMSetFocusToWidget(panel->text);
427 return panel;
430 static void handleKeyPress3(XEvent * event, void *clientData)
432 WMGenericPanel *panel = (WMGenericPanel *) clientData;
433 KeySym ksym;
435 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
437 if (ksym == XK_Return && panel->defBtn) {
438 WMPerformButtonClick(panel->defBtn);
439 } else if (ksym == XK_Escape) {
440 if (panel->altBtn) {
441 WMPerformButtonClick(panel->altBtn);
442 } else {
443 panel->result = WAPRDefault;
444 WMBreakModalLoop(WMWidgetScreen(panel->win));
449 void WMDestroyGenericPanel(WMGenericPanel * panel)
451 WMUnmapWidget(panel->win);
452 WMDestroyWidget(panel->win);
453 wfree(panel);
456 WMGenericPanel *WMCreateGenericPanel(WMScreen * scrPtr, WMWindow * owner,
457 char *title, char *defaultButton, char *alternateButton)
459 WMGenericPanel *panel;
460 int dw = 0, aw = 0, w;
461 WMBox *hbox;
462 WMPixmap *icon;
464 panel = wmalloc(sizeof(WMGenericPanel));
466 if (owner) {
467 panel->win = WMCreatePanelWithStyleForWindow(owner, "genericPanel", WMTitledWindowMask);
468 } else {
469 panel->win = WMCreateWindowWithStyle(scrPtr, "genericPanel", WMTitledWindowMask);
472 WMSetWindowInitialPosition(panel->win,
473 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win)) / 2,
474 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win)) / 2);
476 WMSetWindowTitle(panel->win, "");
478 panel->vbox = WMCreateBox(panel->win);
479 WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
480 WMSetBoxHorizontal(panel->vbox, False);
481 WMMapWidget(panel->vbox);
483 hbox = WMCreateBox(panel->vbox);
484 WMSetBoxBorderWidth(hbox, 5);
485 WMSetBoxHorizontal(hbox, True);
486 WMMapWidget(hbox);
487 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
489 panel->iLbl = WMCreateLabel(hbox);
490 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
491 WMMapWidget(panel->iLbl);
492 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
493 icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL);
494 if (icon) {
495 WMSetLabelImage(panel->iLbl, icon);
496 WMReleasePixmap(icon);
497 } else {
498 WMSetLabelImage(panel->iLbl, scrPtr->applicationIconPixmap);
501 if (title) {
502 WMFont *largeFont;
504 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
506 panel->tLbl = WMCreateLabel(hbox);
507 WMMapWidget(panel->tLbl);
508 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True, 64, 0, 0);
509 WMSetLabelText(panel->tLbl, title);
510 WMSetLabelTextAlignment(panel->tLbl, WALeft);
511 WMSetLabelFont(panel->tLbl, largeFont);
513 WMReleaseFont(largeFont);
516 /* create divider line */
518 panel->line = WMCreateFrame(panel->vbox);
519 WMMapWidget(panel->line);
520 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True, 2, 2, 5);
521 WMSetFrameRelief(panel->line, WRGroove);
523 panel->content = WMCreateFrame(panel->vbox);
524 WMMapWidget(panel->content);
525 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->content), True, True, 50, 0, 5);
526 WMSetFrameRelief(panel->content, WRFlat);
528 hbox = WMCreateBox(panel->vbox);
529 WMSetBoxBorderWidth(hbox, 10);
530 WMSetBoxHorizontal(hbox, True);
531 WMMapWidget(hbox);
532 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
534 /* create buttons */
535 if (defaultButton)
536 dw = WMWidthOfString(scrPtr->normalFont, defaultButton, strlen(defaultButton));
538 if (alternateButton)
539 aw = WMWidthOfString(scrPtr->normalFont, alternateButton, strlen(alternateButton));
541 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
543 aw += 30;
544 dw += 30;
546 w = WMAX(dw, aw);
547 if ((w + 10) * 2 < 400) {
548 aw = w;
549 dw = w;
550 } else {
551 int t;
553 t = 400 - 40 - aw - dw;
554 aw += t / 2;
555 dw += t / 2;
558 if (defaultButton) {
559 panel->defBtn = WMCreateCommandButton(hbox);
560 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
561 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn), False, True, dw, 0, 0);
562 WMSetButtonText(panel->defBtn, defaultButton);
563 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
564 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
565 WMSetButtonImagePosition(panel->defBtn, WIPRight);
568 WMMapSubwidgets(hbox);
570 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask, handleKeyPress3, panel);
572 WMRealizeWidget(panel->win);
573 WMMapSubwidgets(panel->win);
575 return panel;