New wkdemenu.pl from Malcolm Cowe
[wmaker-crm.git] / WINGs / wpanel.c
blobd4bc1b2cbe4af9d43549c071ee2edff250efed75
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, 0, 0, 0, 0);
129 WMSetBoxHorizontal(panel->vbox, False);
130 WMMapWidget(panel->vbox);
132 hbox = WMCreateBox(panel->vbox);
133 WMSetBoxBorderWidth(hbox, 5);
134 WMSetBoxHorizontal(hbox, True);
135 WMMapWidget(hbox);
136 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 74, 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 WMSetLabelWraps(panel->mLbl, True);
175 WMMapWidget(panel->mLbl);
176 WMAddBoxSubview(panel->vbox, WMWidgetView(panel->mLbl), True, True,
177 WMFontHeight(scrPtr->normalFont)*4, 0, 5);
178 WMSetLabelText(panel->mLbl, msg);
179 WMSetLabelTextAlignment(panel->mLbl, WACenter);
182 hbox = WMCreateBox(panel->vbox);
183 WMSetBoxBorderWidth(hbox, 10);
184 WMSetBoxHorizontal(hbox, True);
185 WMMapWidget(hbox);
186 WMAddBoxSubview(panel->vbox, WMWidgetView(hbox), False, True, 44, 0, 0);
188 /* create buttons */
189 if (otherButton)
190 ow = WMWidthOfString(scrPtr->normalFont, otherButton,
191 strlen(otherButton));
193 if (alternateButton)
194 aw = WMWidthOfString(scrPtr->normalFont, alternateButton,
195 strlen(alternateButton));
197 if (defaultButton)
198 dw = WMWidthOfString(scrPtr->normalFont, defaultButton,
199 strlen(defaultButton));
201 dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
203 aw += 30;
204 ow += 30;
205 dw += 30;
207 w = WMAX(dw, WMAX(aw, ow));
208 if ((w+10)*3 < 400) {
209 aw = w;
210 ow = w;
211 dw = w;
212 } else {
213 int t;
215 t = 400 - 40 - aw - ow - dw;
216 aw += t/3;
217 ow += t/3;
218 dw += t/3;
221 if (defaultButton) {
222 panel->defBtn = WMCreateCommandButton(hbox);
223 WMSetButtonAction(panel->defBtn, alertPanelOnClick, panel);
224 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->defBtn),
225 False, True, dw, 0, 0);
226 WMSetButtonText(panel->defBtn, defaultButton);
227 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
228 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
229 WMSetButtonImagePosition(panel->defBtn, WIPRight);
231 if (alternateButton) {
232 panel->altBtn = WMCreateCommandButton(hbox);
233 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->altBtn),
234 False, True, aw, 0, 5);
235 WMSetButtonAction(panel->altBtn, alertPanelOnClick, panel);
236 WMSetButtonText(panel->altBtn, alternateButton);
238 if (otherButton) {
239 panel->othBtn = WMCreateCommandButton(hbox);
240 WMSetButtonAction(panel->othBtn, alertPanelOnClick, panel);
241 WMAddBoxSubviewAtEnd(hbox, WMWidgetView(panel->othBtn),
242 False, True, ow, 0, 5);
243 WMSetButtonText(panel->othBtn, otherButton);
246 WMMapSubwidgets(hbox);
248 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
249 handleKeyPress, panel);
251 WMRealizeWidget(panel->win);
252 WMMapSubwidgets(panel->win);
254 return panel;
261 static void
262 inputBoxOnClick(WMWidget *self, void *clientData)
264 WMInputPanel *panel = clientData;
266 WMBreakModalLoop(WMWidgetScreen(self));
267 if (self == panel->defBtn) {
268 panel->result = WAPRDefault;
269 } else if (self == panel->altBtn) {
270 panel->result = WAPRAlternate;
276 static void
277 handleKeyPress2(XEvent *event, void *clientData)
279 WMInputPanel *panel = (WMInputPanel*)clientData;
281 if (event->xkey.keycode == panel->retKey && panel->defBtn) {
282 WMPerformButtonClick(panel->defBtn);
284 if (event->xkey.keycode == panel->escKey) {
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 panel->retKey = XKeysymToKeycode(scrPtr->display, XK_Return);
390 panel->escKey = XKeysymToKeycode(scrPtr->display, XK_Escape);
392 if (owner)
393 panel->win = WMCreatePanelWithStyleForWindow(owner, "inputPanel",
394 WMTitledWindowMask);
395 else
396 panel->win = WMCreateWindowWithStyle(scrPtr, "inputPanel",
397 WMTitledWindowMask);
398 WMSetWindowTitle(panel->win, "");
400 WMResizeWidget(panel->win, 320, 160);
402 if (title) {
403 WMFont *largeFont;
405 largeFont = WMBoldSystemFontOfSize(scrPtr, 24);
407 panel->tLbl = WMCreateLabel(panel->win);
408 WMMoveWidget(panel->tLbl, 20, 16);
409 WMResizeWidget(panel->tLbl, 320 - 40, WMFontHeight(largeFont)+4);
410 WMSetLabelText(panel->tLbl, title);
411 WMSetLabelTextAlignment(panel->tLbl, WALeft);
412 WMSetLabelFont(panel->tLbl, largeFont);
414 WMReleaseFont(largeFont);
418 if (msg) {
419 panel->mLbl = WMCreateLabel(panel->win);
420 WMMoveWidget(panel->mLbl, 20, 50);
421 WMResizeWidget(panel->mLbl, 320 - 40,
422 WMFontHeight(scrPtr->normalFont)*2);
423 WMSetLabelText(panel->mLbl, msg);
424 WMSetLabelTextAlignment(panel->mLbl, WALeft);
427 panel->text = WMCreateTextField(panel->win);
428 WMMoveWidget(panel->text, 20, 85);
429 WMResizeWidget(panel->text, 320 - 40, WMWidgetHeight(panel->text));
430 WMSetTextFieldText(panel->text, defaultText);
432 WMAddNotificationObserver(endedEditingObserver, panel,
433 WMTextDidEndEditingNotification, panel->text);
435 /* create buttons */
436 if (cancelButton)
437 aw = WMWidthOfString(scrPtr->normalFont, cancelButton,
438 strlen(cancelButton));
440 if (okButton)
441 dw = WMWidthOfString(scrPtr->normalFont, okButton,
442 strlen(okButton));
444 w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0);
445 if (aw > w)
446 w = aw;
448 w += 30;
449 x = 310;
451 if (okButton) {
452 x -= w + 10;
454 panel->defBtn = WMCreateCustomButton(panel->win, WBBPushInMask
455 |WBBPushChangeMask
456 |WBBPushLightMask);
457 WMSetButtonAction(panel->defBtn, inputBoxOnClick, panel);
458 WMMoveWidget(panel->defBtn, x, 124);
459 WMResizeWidget(panel->defBtn, w, 24);
460 WMSetButtonText(panel->defBtn, okButton);
461 WMSetButtonImage(panel->defBtn, scrPtr->buttonArrow);
462 WMSetButtonAltImage(panel->defBtn, scrPtr->pushedButtonArrow);
463 WMSetButtonImagePosition(panel->defBtn, WIPRight);
465 if (cancelButton) {
466 x -= w + 10;
468 panel->altBtn = WMCreateCommandButton(panel->win);
469 WMSetButtonAction(panel->altBtn, inputBoxOnClick, panel);
470 WMMoveWidget(panel->altBtn, x, 124);
471 WMResizeWidget(panel->altBtn, w, 24);
472 WMSetButtonText(panel->altBtn, cancelButton);
475 WMCreateEventHandler(W_VIEW(panel->win), KeyPressMask,
476 handleKeyPress2, panel);
478 WMRealizeWidget(panel->win);
479 WMMapSubwidgets(panel->win);
481 WMSetFocusToWidget(panel->text);
483 return panel;