fixed scroller bug when displaying scroller before
[wmaker-crm.git] / WINGs / wpanel.c
blobbcd308d12c2b27ddd0f64f7e6644217406ae0ce2
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;
108 panel = wmalloc(sizeof(WMAlertPanel));
109 memset(panel, 0, sizeof(WMAlertPanel));
111 if (owner) {
112 panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel",
113 WMTitledWindowMask);
114 } else {
115 panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel",
116 WMTitledWindowMask);
119 WMSetWindowInitialPosition(panel->win,
120 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win))/2,
121 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win))/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, 5);
132 WMSetBoxHorizontal(hbox, True);
133 WMMapWidget(hbox);
134 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 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);
141 if (scrPtr->applicationIcon) {
142 WMSetLabelImage(panel->iLbl, scrPtr->applicationIcon);
145 if (title) {
146 WMFont *largeFont;
148 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
150 panel->tLbl = WMCreateLabel(hbox);
151 WMMapWidget(panel->tLbl);
152 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True,
153 64, 0, 0);
154 WMSetLabelText(panel->tLbl, title);
155 WMSetLabelTextAlignment(panel->tLbl, WALeft);
156 WMSetLabelFont(panel->tLbl, largeFont);
158 WMReleaseFont(largeFont);
161 /* create divider line */
163 panel->line = WMCreateFrame(panel->win);
164 WMMapWidget(panel->line);
165 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True,
166 2, 2, 5);
167 WMSetFrameRelief(panel->line, WRGroove);
170 if (msg) {
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, 5);
176 WMSetLabelText(panel->mLbl, msg);
177 WMSetLabelTextAlignment(panel->mLbl, WACenter);
180 hbox = WMCreateBox(panel->vbox);
181 WMSetBoxBorderWidth(hbox, 10);
182 WMSetBoxHorizontal(hbox, True);
183 WMMapWidget(hbox);
184 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
186 /* create buttons */
187 if (otherButton)
188 ow = WMWidthOfString(scrPtr->normalFont, otherButton,
189 strlen(otherButton));
191 if (alternateButton)
192 aw = WMWidthOfString(scrPtr->normalFont, alternateButton,
193 strlen(alternateButton));
195 if (defaultButton)
196 dw = WMWidthOfString(scrPtr->normalFont, defaultButton,
197 strlen(defaultButton));
199 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
201 aw += 30;
202 ow += 30;
203 dw += 30;
205 w = WMAX(dw, WMAX(aw, ow));
206 if ((w+10)*3 < 400) {
207 aw = w;
208 ow = w;
209 dw = w;
210 } else {
211 int t;
213 t = 400 - 40 - aw - ow - dw;
214 aw += t/3;
215 ow += t/3;
216 dw += t/3;
219 if (defaultButton) {
220 panel->defBtn = WMCreateCommandButton(hbox);
221 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
222 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn),
223 False, True, dw, 0, 0);
224 WMSetButtonText(panel->defBtn, defaultButton);
225 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
226 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
227 WMSetButtonImagePosition(panel->defBtn, WIPRight);
229 if (alternateButton) {
230 panel->altBtn = WMCreateCommandButton(hbox);
231 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->altBtn),
232 False, True, aw, 0, 5);
233 WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
234 WMSetButtonText(panel->altBtn, alternateButton);
236 if (otherButton) {
237 panel->othBtn = WMCreateCommandButton(hbox);
238 WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
239 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->othBtn),
240 False, True, ow, 0, 5);
241 WMSetButtonText(panel->othBtn, otherButton);
244 WMMapSubwidgets(hbox);
246 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
247 handleKeyPress, panel);
249 WMRealizeWidget(panel->win);
250 WMMapSubwidgets(panel->win);
252 return panel;
259 static void
260 inputBoxOnClick(WMWidget *self, void *clientData)
262 WMInputPanel *panel = clientData;
264 WMBreakModalLoop(WMWidgetScreen(self));
265 if (self == panel->defBtn) {
266 panel->result = WAPRDefault;
267 } else if (self == panel->altBtn) {
268 panel->result = WAPRAlternate;
274 static void
275 handleKeyPress2(XEvent *event, void *clientData)
277 WMInputPanel *panel = (WMInputPanel*)clientData;
278 KeySym ksym;
280 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
282 if (ksym == XK_Return && panel->defBtn) {
283 WMPerformButtonClick(panel->defBtn);
284 } else if (ksym == XK_Escape) {
285 if (panel->altBtn) {
286 WMPerformButtonClick(panel->altBtn);
287 } else {
288 /* printf("got esc\n");*/
289 WMBreakModalLoop(WMWidgetScreen(panel->win));
290 panel->result = WAPRDefault;
296 char*
297 WMRunInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title,
298 char *msg, char *defaultText,
299 char *okButton, char *cancelButton)
301 WMInputPanel *panel;
302 char *tmp;
304 panel = WMCreateInputPanel(scrPtr, owner, title, msg, defaultText,
305 okButton, cancelButton);
309 int px, py;
310 WMView *view = WMWidgetView(panel->win);
312 if (owner) {
313 WMView *oview = WMWidgetView(owner);
314 WMPoint pt = WMGetViewScreenPosition(oview);
316 px = (W_VIEW_WIDTH(oview)-W_VIEW_WIDTH(view))/2;
317 py = (W_VIEW_HEIGHT(oview)-W_VIEW_HEIGHT(view))/2;
319 px += pt.x;
320 py += pt.y;
321 } else {
322 px = (W_VIEW_WIDTH(scrPtr->rootView)-W_VIEW_WIDTH(view))/2;
323 py = (W_VIEW_HEIGHT(scrPtr->rootView)-W_VIEW_HEIGHT(view))/2;
325 WMSetWindowInitialPosition(panel->win, px, py);
328 WMMapWidget(panel->win);
330 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
332 if (panel->result == WAPRDefault)
333 tmp = WMGetTextFieldText(panel->text);
334 else
335 tmp = NULL;
337 WMDestroyInputPanel(panel);
339 return tmp;
343 void
344 WMDestroyInputPanel(WMInputPanel *panel)
346 WMRemoveNotificationObserver(panel);
347 WMUnmapWidget(panel->win);
348 WMDestroyWidget(panel->win);
349 wfree(panel);
354 static void
355 endedEditingObserver(void *observerData, WMNotification *notification)
357 WMInputPanel *panel = (WMInputPanel*)observerData;
359 switch ((int)WMGetNotificationClientData(notification)) {
360 case WMReturnTextMovement:
361 if (panel->defBtn)
362 WMPerformButtonClick(panel->defBtn);
363 break;
364 case WMEscapeTextMovement:
365 if (panel->altBtn)
366 WMPerformButtonClick(panel->altBtn);
367 else {
368 WMBreakModalLoop(WMWidgetScreen(panel->win));
369 panel->result = WAPRDefault;
371 break;
372 default:
373 break;
378 WMInputPanel*
379 WMCreateInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title, char *msg,
380 char *defaultText, char *okButton, char *cancelButton)
382 WMInputPanel *panel;
383 int x, dw=0, aw=0, w;
386 panel = wmalloc(sizeof(WMInputPanel));
387 memset(panel, 0, sizeof(WMInputPanel));
389 if (owner)
390 panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel",
391 WMTitledWindowMask);
392 else
393 panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel",
394 WMTitledWindowMask);
395 WMSetWindowTitle(panel->win, "");
397 WMResizeWidget(panel->win, 320, 160);
399 if (title) {
400 WMFont *largeFont;
402 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
404 panel->tLbl = WMCreateLabel(panel->win);
405 WMMoveWidget(panel->tLbl, 20, 16);
406 WMResizeWidget(panel->tLbl, 320 - 40, WMFontHeight(largeFont)+4);
407 WMSetLabelText(panel->tLbl, title);
408 WMSetLabelTextAlignment(panel->tLbl, WALeft);
409 WMSetLabelFont(panel->tLbl, largeFont);
411 WMReleaseFont(largeFont);
415 if (msg) {
416 panel->mLbl = WMCreateLabel(panel->win);
417 WMMoveWidget(panel->mLbl, 20, 50);
418 WMResizeWidget(panel->mLbl, 320 - 40,
419 WMFontHeight(scrPtr->normalFont)*2);
420 WMSetLabelText(panel->mLbl, msg);
421 WMSetLabelTextAlignment(panel->mLbl, WALeft);
424 panel->text = WMCreateTextField(panel->win);
425 WMMoveWidget(panel->text, 20, 85);
426 WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
427 WMSetTextFieldText(panel->text, defaultText);
429 WMAddNotificationObserver(endedEditingObserver, panel,
430 WMTextDidEndEditingNotification, panel->text);
432 /* create buttons */
433 if (cancelButton)
434 aw = WMWidthOfString(scrPtr->normalFont, cancelButton,
435 strlen(cancelButton));
437 if (okButton)
438 dw = WMWidthOfString(scrPtr->normalFont, okButton,
439 strlen(okButton));
441 w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
442 if (aw > w)
443 w = aw;
445 w += 30;
446 x = 310;
448 if (okButton) {
449 x -= w + 10;
451 panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
452 |WBBPushChangeMask
453 |WBBPushLightMask);
454 WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
455 WMMoveWidget(panel->defBtn, x, 124);
456 WMResizeWidget(panel->defBtn, w, 24);
457 WMSetButtonText(panel->defBtn, okButton);
458 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
459 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
460 WMSetButtonImagePosition(panel->defBtn, WIPRight);
462 if (cancelButton) {
463 x -= w + 10;
465 panel->altBtn = WMCreateCommandButton(panel->win);
466 WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
467 WMMoveWidget(panel->altBtn, x, 124);
468 WMResizeWidget(panel->altBtn, w, 24);
469 WMSetButtonText(panel->altBtn, cancelButton);
472 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
473 handleKeyPress2, panel);
475 WMRealizeWidget(panel->win);
476 WMMapSubwidgets(panel->win);
478 WMSetFocusToWidget(panel->text);
480 return panel;
486 static void
487 handleKeyPress3(XEvent *event, void *clientData)
489 WMGenericPanel *panel = (WMAlertPanel*)clientData;
490 KeySym ksym;
492 XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
494 if (ksym == XK_Return && panel->defBtn) {
495 WMPerformButtonClick(panel->defBtn);
496 } else if (ksym == XK_Escape) {
497 if (panel->altBtn) {
498 WMPerformButtonClick(panel->altBtn);
499 } else {
500 panel->result = WAPRDefault;
501 WMBreakModalLoop(WMWidgetScreen(panel->win));
507 void
508 WMDestroyGenericPanel(WMGenericPanel *panel)
510 WMUnmapWidget(panel->win);
511 WMDestroyWidget(panel->win);
512 wfree(panel);
516 WMGenericPanel*
517 WMCreateGenericPanel(WMScreen *scrPtr, WMWindow *owner,
518 char *title, char *defaultButton,
519 char *alternateButton)
521 WMGenericPanel *panel;
522 int dw=0, aw=0, w;
523 WMBox *hbox;
526 panel = wmalloc(sizeof(WMGenericPanel));
527 memset(panel, 0, sizeof(WMGenericPanel));
529 if (owner) {
530 panel->win = WMCreatePanelWithStyleForWindow(owner, "genericPanel",
531 WMTitledWindowMask);
532 } else {
533 panel->win = WMCreateWindowWithStyle(scrPtr, "genericPanel",
534 WMTitledWindowMask);
537 WMSetWindowInitialPosition(panel->win,
538 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win))/2,
539 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win))/2);
541 WMSetWindowTitle(panel->win, "");
543 panel->vbox = WMCreateBox(panel->win);
544 WMSetViewExpandsToParent(WMWidgetView(panel->vbox), 0, 0, 0, 0);
545 WMSetBoxHorizontal(panel->vbox, False);
546 WMMapWidget(panel->vbox);
548 hbox = WMCreateBox(panel->vbox);
549 WMSetBoxBorderWidth(hbox, 5);
550 WMSetBoxHorizontal(hbox, True);
551 WMMapWidget(hbox);
552 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 0, 5);
554 panel->iLbl = WMCreateLabel(hbox);
555 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
556 WMMapWidget(panel->iLbl);
557 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
559 if (scrPtr->applicationIcon) {
560 WMSetLabelImage(panel->iLbl, scrPtr->applicationIcon);
563 if (title) {
564 WMFont *largeFont;
566 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
568 panel->tLbl = WMCreateLabel(hbox);
569 WMMapWidget(panel->tLbl);
570 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True,
571 64, 0, 0);
572 WMSetLabelText(panel->tLbl, title);
573 WMSetLabelTextAlignment(panel->tLbl, WALeft);
574 WMSetLabelFont(panel->tLbl, largeFont);
576 WMReleaseFont(largeFont);
579 /* create divider line */
581 panel->line = WMCreateFrame(panel->vbox);
582 WMMapWidget(panel->line);
583 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->line), False, True,
584 2, 2, 5);
585 WMSetFrameRelief(panel->line, WRGroove);
588 panel->content = WMCreateFrame(panel->vbox);
589 WMMapWidget(panel->content);
590 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->content), True, True,
591 50, 0, 5);
592 WMSetFrameRelief(panel->content, WRFlat);
594 hbox = WMCreateBox(panel->vbox);
595 WMSetBoxBorderWidth(hbox, 10);
596 WMSetBoxHorizontal(hbox, True);
597 WMMapWidget(hbox);
598 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
600 /* create buttons */
601 if (defaultButton)
602 dw = WMWidthOfString(scrPtr->normalFont, defaultButton,
603 strlen(defaultButton));
605 if (alternateButton)
606 aw = WMWidthOfString(scrPtr->normalFont, alternateButton,
607 strlen(alternateButton));
610 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
612 aw += 30;
613 dw += 30;
615 w = WMAX(dw, aw);
616 if ((w+10)*2 < 400) {
617 aw = w;
618 dw = w;
619 } else {
620 int t;
622 t = 400 - 40 - aw - dw;
623 aw += t/2;
624 dw += t/2;
627 if (defaultButton) {
628 panel->defBtn = WMCreateCommandButton(hbox);
629 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
630 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn),
631 False, True, dw, 0, 0);
632 WMSetButtonText(panel->defBtn, defaultButton);
633 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
634 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
635 WMSetButtonImagePosition(panel->defBtn, WIPRight);
638 WMMapSubwidgets(hbox);
640 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
641 handleKeyPress3, panel);
643 WMRealizeWidget(panel->win);
644 WMMapSubwidgets(panel->win);
646 return panel;