Fixed wrong size of the alert panel buttons
[wmaker-crm.git] / WINGs / wpanel.c
blobfe27d65465cb7e99d19e174560025cc57508bf98
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;
30 if (event->xkey.keycode == panel->retKey && panel->defBtn) {
31 WMPerformButtonClick(panel->defBtn);
33 if (event->xkey.keycode == panel->escKey) {
34 if (panel->altBtn || panel->othBtn) {
35 WMPerformButtonClick(panel->othBtn ? panel->othBtn : panel->altBtn);
36 } else {
37 panel->result = WAPRDefault;
38 WMBreakModalLoop(WMWidgetScreen(panel->win));
44 int
45 WMRunAlertPanel(WMScreen *scrPtr, WMWindow *owner,
46 char *title, char *msg, char *defaultButton,
47 char *alternateButton, char *otherButton)
49 WMAlertPanel *panel;
50 int tmp;
52 panel = WMCreateAlertPanel(scrPtr, owner, title, msg, defaultButton,
53 alternateButton, otherButton);
56 int px, py;
57 WMView *view = WMWidgetView(panel->win);
59 if (owner) {
60 WMView *oview = WMWidgetView(owner);
61 WMPoint pt = WMGetViewScreenPosition(oview);
63 px = (W_VIEW_WIDTH(oview)-W_VIEW_WIDTH(view))/2;
64 py = (W_VIEW_HEIGHT(oview)-W_VIEW_HEIGHT(view))/2;
66 px += pt.x;
67 py += pt.y;
68 } else {
69 px = (W_VIEW_WIDTH(scrPtr->rootView)-W_VIEW_WIDTH(view))/2;
70 py = (W_VIEW_HEIGHT(scrPtr->rootView)-W_VIEW_HEIGHT(view))/2;
72 WMSetWindowInitialPosition(panel->win, px, py);
75 WMMapWidget(panel->win);
77 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
79 tmp = panel->result;
81 WMDestroyAlertPanel(panel);
83 return tmp;
87 void
88 WMDestroyAlertPanel(WMAlertPanel *panel)
90 WMUnmapWidget(panel->win);
91 WMDestroyWidget(panel->win);
92 wfree(panel);
96 WMAlertPanel*
97 WMCreateAlertPanel(WMScreen *scrPtr, WMWindow *owner,
98 char *title, char *msg, char *defaultButton,
99 char *alternateButton, char *otherButton)
101 WMAlertPanel *panel;
102 int dw=0, aw=0, ow=0, w;
103 WMBox *hbox;
106 panel = wmalloc(sizeof(WMAlertPanel));
107 memset(panel, 0, sizeof(WMAlertPanel));
110 panel->retKey = XKeysymToKeycode(scrPtr->display, XK_Return);
111 panel->escKey = XKeysymToKeycode(scrPtr->display, XK_Escape);
113 if (owner) {
114 panel->win = WMCreatePanelWithStyleForWindow(owner, "alertPanel",
115 WMTitledWindowMask);
116 } else {
117 panel->win = WMCreateWindowWithStyle(scrPtr, "alertPanel",
118 WMTitledWindowMask);
121 WMSetWindowInitialPosition(panel->win,
122 (scrPtr->rootView->size.width - WMWidgetWidth(panel->win))/2,
123 (scrPtr->rootView->size.height - WMWidgetHeight(panel->win))/2);
125 WMSetWindowTitle(panel->win, "");
127 panel->vbox = WMCreateBox(panel->win);
128 WMSetBoxExpandsToParent(panel->vbox);
129 WMSetBoxHorizontal(panel->vbox, False);
130 WMMapWidget(panel->vbox);
132 hbox = WMCreateBox(panel->vbox);
133 WMSetBoxBorderWidth(hbox, 10);
134 WMSetBoxHorizontal(hbox, True);
135 WMMapWidget(hbox);
136 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 84, 0, 5);
138 panel->iLbl = WMCreateLabel(hbox);
139 WMSetLabelImagePosition(panel->iLbl, WIPImageOnly);
140 WMMapWidget(panel->iLbl);
141 WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10);
143 if (scrPtr->applicationIcon) {
144 WMSetLabelImage(panel->iLbl, scrPtr->applicationIcon);
147 if (title) {
148 WMFont *largeFont;
150 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
152 panel->tLbl = WMCreateLabel(hbox);
153 WMMapWidget(panel->tLbl);
154 WMAddBoxSubview(hbox, WMWidgetView(panel->tLbl), True, True,
155 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,
168 2, 2, 5);
169 WMSetFrameRelief(panel->line, WRGroove);
172 if (msg) {
173 panel->mLbl = WMCreateLabel(panel->win);
174 WMMapWidget(panel->mLbl);
175 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->mLbl), True, True,
176 WMFontHeight(scrPtr->normalFont)*4, 0, 5);
177 WMSetLabelText(panel->mLbl, msg);
178 WMSetLabelTextAlignment(panel->mLbl, WACenter);
181 hbox = WMCreateBox(panel->vbox);
182 WMSetBoxBorderWidth(hbox, 10);
183 WMSetBoxHorizontal(hbox, True);
184 WMMapWidget(hbox);
185 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
187 /* create buttons */
188 if (otherButton)
189 ow = WMWidthOfString(scrPtr->normalFont, otherButton,
190 strlen(otherButton));
192 if (alternateButton)
193 aw = WMWidthOfString(scrPtr->normalFont, alternateButton,
194 strlen(alternateButton));
196 if (defaultButton)
197 dw = WMWidthOfString(scrPtr->normalFont, defaultButton,
198 strlen(defaultButton));
200 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
202 aw += 30;
203 ow += 30;
204 dw += 30;
206 w = WMAX(dw, WMAX(aw, ow));
207 if ((w+10)*3 < 400) {
208 aw = w;
209 ow = w;
210 dw = w;
211 } else {
212 int t;
214 t = 400 - 40 - aw - ow - dw;
215 aw += t/3;
216 ow += t/3;
217 dw += t/3;
220 if (defaultButton) {
221 panel->defBtn = WMCreateCommandButton(hbox);
222 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
223 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn),
224 False, True, dw, 0, 0);
225 WMSetButtonText(panel->defBtn, defaultButton);
226 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
227 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
228 WMSetButtonImagePosition(panel->defBtn, WIPRight);
230 if (alternateButton) {
231 panel->altBtn = WMCreateCommandButton(hbox);
232 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->altBtn),
233 False, True, aw, 0, 5);
234 WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
235 WMSetButtonText(panel->altBtn, alternateButton);
237 if (otherButton) {
238 panel->othBtn = WMCreateCommandButton(hbox);
239 WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
240 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->othBtn),
241 False, True, ow, 0, 5);
242 WMSetButtonText(panel->othBtn, otherButton);
245 WMMapSubwidgets(hbox);
247 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
248 handleKeyPress, panel);
250 WMRealizeWidget(panel->win);
251 WMMapSubwidgets(panel->win);
253 return panel;
260 static void
261 inputBoxOnClick(WMWidget *self, void *clientData)
263 WMInputPanel *panel = clientData;
265 WMBreakModalLoop(WMWidgetScreen(self));
266 if (self == panel->defBtn) {
267 panel->result = WAPRDefault;
268 } else if (self == panel->altBtn) {
269 panel->result = WAPRAlternate;
275 static void
276 handleKeyPress2(XEvent *event, void *clientData)
278 WMInputPanel *panel = (WMInputPanel*)clientData;
280 if (event->xkey.keycode == panel->retKey && panel->defBtn) {
281 WMPerformButtonClick(panel->defBtn);
283 if (event->xkey.keycode == panel->escKey) {
284 if (panel->altBtn) {
285 WMPerformButtonClick(panel->altBtn);
286 } else {
287 /* printf("got esc\n");*/
288 WMBreakModalLoop(WMWidgetScreen(panel->win));
289 panel->result = WAPRDefault;
295 char*
296 WMRunInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title,
297 char *msg, char *defaultText,
298 char *okButton, char *cancelButton)
300 WMInputPanel *panel;
301 char *tmp;
303 panel = WMCreateInputPanel(scrPtr, owner, title, msg, defaultText,
304 okButton, cancelButton);
308 int px, py;
309 WMView *view = WMWidgetView(panel->win);
311 if (owner) {
312 WMView *oview = WMWidgetView(owner);
313 WMPoint pt = WMGetViewScreenPosition(oview);
315 px = (W_VIEW_WIDTH(oview)-W_VIEW_WIDTH(view))/2;
316 py = (W_VIEW_HEIGHT(oview)-W_VIEW_HEIGHT(view))/2;
318 px += pt.x;
319 py += pt.y;
320 } else {
321 px = (W_VIEW_WIDTH(scrPtr->rootView)-W_VIEW_WIDTH(view))/2;
322 py = (W_VIEW_HEIGHT(scrPtr->rootView)-W_VIEW_HEIGHT(view))/2;
324 WMSetWindowInitialPosition(panel->win, px, py);
327 WMMapWidget(panel->win);
329 WMRunModalLoop(scrPtr, W_VIEW(panel->win));
331 if (panel->result == WAPRDefault)
332 tmp = WMGetTextFieldText(panel->text);
333 else
334 tmp = NULL;
336 WMDestroyInputPanel(panel);
338 return tmp;
342 void
343 WMDestroyInputPanel(WMInputPanel *panel)
345 WMRemoveNotificationObserver(panel);
346 WMUnmapWidget(panel->win);
347 WMDestroyWidget(panel->win);
348 wfree(panel);
353 static void
354 endedEditingObserver(void *observerData, WMNotification *notification)
356 WMInputPanel *panel = (WMInputPanel*)observerData;
358 switch ((int)WMGetNotificationClientData(notification)) {
359 case WMReturnTextMovement:
360 if (panel->defBtn)
361 WMPerformButtonClick(panel->defBtn);
362 break;
363 case WMEscapeTextMovement:
364 if (panel->altBtn)
365 WMPerformButtonClick(panel->altBtn);
366 else {
367 WMBreakModalLoop(WMWidgetScreen(panel->win));
368 panel->result = WAPRDefault;
370 break;
371 default:
372 break;
377 WMInputPanel*
378 WMCreateInputPanel(WMScreen *scrPtr, WMWindow *owner, char *title, char *msg,
379 char *defaultText, char *okButton, char *cancelButton)
381 WMInputPanel *panel;
382 int x, dw=0, aw=0, w;
385 panel = wmalloc(sizeof(WMInputPanel));
386 memset(panel, 0, sizeof(WMInputPanel));
388 panel->retKey = XKeysymToKeycode(scrPtr->display, XK_Return);
389 panel->escKey = XKeysymToKeycode(scrPtr->display, XK_Escape);
391 if (owner)
392 panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel",
393 WMTitledWindowMask);
394 else
395 panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel",
396 WMTitledWindowMask);
397 WMSetWindowTitle(panel->win, "");
399 WMResizeWidget(panel->win, 320, 160);
401 if (title) {
402 WMFont *largeFont;
404 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
406 panel->tLbl = WMCreateLabel(panel->win);
407 WMMoveWidget(panel->tLbl, 20, 16);
408 WMResizeWidget(panel->tLbl, 320 - 40, WMFontHeight(largeFont)+4);
409 WMSetLabelText(panel->tLbl, title);
410 WMSetLabelTextAlignment(panel->tLbl, WALeft);
411 WMSetLabelFont(panel->tLbl, largeFont);
413 WMReleaseFont(largeFont);
417 if (msg) {
418 panel->mLbl = WMCreateLabel(panel->win);
419 WMMoveWidget(panel->mLbl, 20, 50);
420 WMResizeWidget(panel->mLbl, 320 - 40,
421 WMFontHeight(scrPtr->normalFont)*2);
422 WMSetLabelText(panel->mLbl, msg);
423 WMSetLabelTextAlignment(panel->mLbl, WALeft);
426 panel->text = WMCreateTextField(panel->win);
427 WMMoveWidget(panel->text, 20, 85);
428 WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
429 WMSetTextFieldText(panel->text, defaultText);
431 WMAddNotificationObserver(endedEditingObserver, panel,
432 WMTextDidEndEditingNotification, panel->text);
434 /* create buttons */
435 if (cancelButton)
436 aw = WMWidthOfString(scrPtr->normalFont, cancelButton,
437 strlen(cancelButton));
439 if (okButton)
440 dw = WMWidthOfString(scrPtr->normalFont, okButton,
441 strlen(okButton));
443 w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
444 if (aw > w)
445 w = aw;
447 w += 30;
448 x = 310;
450 if (okButton) {
451 x -= w + 10;
453 panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
454 |WBBPushChangeMask
455 |WBBPushLightMask);
456 WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
457 WMMoveWidget(panel->defBtn, x, 124);
458 WMResizeWidget(panel->defBtn, w, 24);
459 WMSetButtonText(panel->defBtn, okButton);
460 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
461 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
462 WMSetButtonImagePosition(panel->defBtn, WIPRight);
464 if (cancelButton) {
465 x -= w + 10;
467 panel->altBtn = WMCreateCommandButton(panel->win);
468 WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
469 WMMoveWidget(panel->altBtn, x, 124);
470 WMResizeWidget(panel->altBtn, w, 24);
471 WMSetButtonText(panel->altBtn, cancelButton);
474 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
475 handleKeyPress2, panel);
477 WMRealizeWidget(panel->win);
478 WMMapSubwidgets(panel->win);
480 WMSetFocusToWidget(panel->text);
482 return panel;