2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2009 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include "e16-ecore_list.h"
36 #define DEBUG_DIALOGS 0
53 int base_orig_w, base_orig_h;
54 int knob_orig_w, knob_orig_h;
56 int base_x, base_y, base_w, base_h;
57 int knob_x, knob_y, knob_w, knob_h;
58 int numeric_x, numeric_y, numeric_w, numeric_h;
72 DialogItemCallbackFunc *init_func;
73 DialogItemCallbackFunc *event_func;
78 int check_orig_w, check_orig_h;
102 int radio_orig_w, radio_orig_h;
108 DialogItemCallbackFunc *event_func;
114 DialogCallbackFunc *func;
119 EImageBorder padding;
132 DItemCheckButton check_button;
135 DItemSeparator separator;
136 DItemRadioButton radio_button;
151 DialogCallbackFunc *func;
166 DialogCallbackFunc *exit_func;
169 DKeyBind *keybindings;
177 int xu1, yu1, xu2, yu2;
180 static EWin *FindEwinByDialog(Dialog * d);
181 static int FindADialog(void);
183 static void DialogHandleEvents(Win win, XEvent * ev, void *prm);
184 static void DItemHandleEvents(Win win, XEvent * ev, void *prm);
186 static void MoveTableBy(Dialog * d, DItem * di, int dx, int dy);
187 static void DialogItemsRealize(Dialog * d);
188 static void DialogItemDestroy(DItem * di, int clean);
190 static int DialogItemCheckButtonGetState(DItem * di);
192 static void DialogUpdate(Dialog * d);
194 static void DialogAddFooter(Dialog * d, DItem * parent,
195 int flags, DialogCallbackFunc * cb);
196 static void DialogAddHeader(Dialog * d, DItem * parent,
197 const char *img, const char *txt);
199 static Ecore_List *dialog_list = NULL;
201 static char dialog_update_pending = 0;
204 DialogBindKey(Dialog * d, const char *key, DialogCallbackFunc * func, int val,
208 d->keybindings = EREALLOC(DKeyBind, d->keybindings, d->num_bindings);
209 d->keybindings[d->num_bindings - 1].val = val;
210 d->keybindings[d->num_bindings - 1].func = func;
211 d->keybindings[d->num_bindings - 1].data = data;
212 d->keybindings[d->num_bindings - 1].key = EKeynameToKeycode(key);
216 DialogKeybindingsDestroy(Dialog * d)
218 Efree(d->keybindings);
219 d->keybindings = NULL;
224 DialogCreate(const char *name)
228 d = ECALLOC(Dialog, 1);
233 dialog_list = ecore_list_new();
234 ecore_list_append(dialog_list, d);
236 d->name = Estrdup(name);
237 d->win = ECreateClientWindow(VROOT, -20, -20, 2, 2);
238 EventCallbackRegister(d->win, 0, DialogHandleEvents, d);
240 d->iclass = ImageclassAlloc("DIALOG", 1);
241 d->tclass = TextclassAlloc("DIALOG", 1);
243 d->xu1 = d->yu1 = 99999;
250 DialogDestroy(Dialog * d)
252 ecore_list_node_remove(dialog_list, d);
256 DialogKeybindingsDestroy(d);
258 DialogItemDestroy(d->item, 0);
259 ImageclassFree(d->iclass);
260 TextclassFree(d->tclass);
262 FreePmapMask(&(d->pmm_bg));
268 _DialogMatchName(const void *data, const void *match)
270 return strcmp(((const Dialog *)data)->name, (const char *)match);
274 DialogFind(const char *name)
276 return (Dialog *) ecore_list_find(dialog_list, _DialogMatchName, name);
280 DialogSetTitle(Dialog * d, const char *title)
283 d->title = Estrdup(title);
288 DialogSetExitFunction(Dialog * d, DialogCallbackFunc * func, int val)
295 DialogCallExitFunction(Dialog * d)
298 d->exit_func(d, d->exit_val, NULL);
302 DialogSetData(Dialog * d, void *data)
308 DialogGetData(Dialog * d)
313 #if 0 /* FIXME - Merge/remove */
315 DialogAddButton(Dialog * d, const char *text, DialogCallbackFunc * func,
316 char doclose, int image)
322 db = EMALLOC(DButton, 1);
325 d->button = EREALLOC(DButton *, d->button, d->num_buttons);
326 d->button[d->num_buttons - 1] = db;
329 db->text = Estrdup(text);
332 db->win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
333 EventCallbackRegister(db->win, 0, DButtonHandleEvents, db);
343 db->tclass = TextclassAlloc("DIALOG_BUTTON", 1);
344 db->iclass = ImageclassAlloc("DIALOG_BUTTON", 1);
346 TextSize(db->tclass, 0, 0, STATE_NORMAL, text, &w, &h, 17);
347 pad = ImageclassGetPadding(db->iclass);
348 db->h = h + pad->top + pad->bottom;
349 db->w = w + pad->left + pad->right;
350 if (Conf.dialogs.button_image && db->image)
353 ESelectInput(db->win,
354 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
359 DialogDrawButton(Dialog * d __UNUSED__, DButton * db)
364 state = STATE_NORMAL;
365 if ((db->hilited) && (db->clicked))
367 state = STATE_CLICKED;
369 else if ((db->hilited) && (!db->clicked))
371 state = STATE_HILITED;
373 else if (!(db->hilited) && (db->clicked))
375 state = STATE_CLICKED;
379 if (Conf.dialogs.button_image)
384 im = ThemeImageLoad("pix/ok.png");
386 case DLG_BUTTON_CANCEL:
387 im = ThemeImageLoad("pix/cancel.png");
389 case DLG_BUTTON_APPLY:
390 im = ThemeImageLoad("pix/apply.png");
392 case DLG_BUTTON_CLOSE:
393 im = ThemeImageLoad("pix/close.png");
402 ImageClass *ic = db->iclass;
406 ImageclassApply(db->iclass, db->win, 0, 0, state, ST_WIDGET);
408 pad = ImageclassGetPadding(ic);
409 h = db->h - (pad->top + pad->bottom);
410 TextDraw(db->tclass, db->win, None, 0, 0, state, db->text,
411 h + 2 + pad->left, pad->top,
412 db->w - (h + 2 + pad->left + pad->right),
413 h, h, TextclassGetJustification(db->tclass));
415 EImageRenderOnDrawable(im, db->win, None,
416 EIMAGE_BLEND | EIMAGE_ANTI_ALIAS,
417 pad->left, pad->top, h, h);
422 ITApply(db->win, db->iclass, NULL, state, 0, 0,
423 ST_WIDGET, db->tclass, NULL, db->text, 0);
429 DialogItemAddButton(DItem * parent, const char *text, DialogCallbackFunc * func,
430 int val, char doclose, int image __UNUSED__)
434 di = DialogAddItem(parent, DITEM_BUTTON);
435 DialogItemSetText(di, text);
436 DialogItemSetCallback(di, func, 0, NULL);
438 di->do_close = doclose;
444 DialogRedraw(Dialog * d)
446 if ((!d->tclass) || (!d->iclass))
450 Eprintf("DialogRedraw win=%#lx pmap=%#lx\n",
451 WinGetXwin(d->win), WinGetPmap(d->win));
454 FreePmapMask(&(d->pmm_bg));
455 ImageclassApplyCopy(d->iclass, d->win, d->w, d->h, 0, 0, STATE_NORMAL,
456 &(d->pmm_bg), IC_FLAG_FULL_SIZE, ST_DIALOG);
457 if (d->pmm_bg.pmap == None)
460 EGetWindowBackgroundPixmap(d->win);
461 EXCopyArea(d->pmm_bg.pmap, WinGetPmap(d->win), 0, 0, d->w, d->h, 0, 0);
465 DialogDrawItems(d, d->item, 0, 0, 99999, 99999);
469 _DialogEwinInit(EWin * ewin)
471 Dialog *d = (Dialog *) ewin->data;
473 EwinSetTitle(ewin, d->title);
474 EwinSetClass(ewin, d->name, "Enlightenment_Dialog");
477 ewin->props.focus_when_mapped = 1;
479 EoSetLayer(ewin, 10);
483 _DialogEwinMoveResize(EWin * ewin, int resize __UNUSED__)
485 Dialog *d = (Dialog *) ewin->data;
487 if (!d || Mode.mode != MODE_NONE || !EoIsShown(ewin))
490 if (TransparencyUpdateNeeded() || ImageclassIsTransparent(d->iclass))
495 _DialogEwinClose(EWin * ewin)
497 DialogDestroy((Dialog *) ewin->data);
501 static const EWinOps _DialogEwinOps = {
504 _DialogEwinMoveResize,
509 DialogArrange(Dialog * d, int resize)
512 DialogItemsRealize(d);
516 EwinSetTitle(d->ewin, d->title);
520 ICCCM_SetSizeConstraints(d->ewin, d->w, d->h, d->w, d->h, 0, 0, 1, 1,
525 EwinResize(d->ewin, d->w, d->h);
530 ArrangeEwinCentered(d->ewin);
535 DialogShowArranged(Dialog * d, int center)
539 ewin = FindEwinByDialog(d);
542 #if 0 /* Make dialogs sticky? */
543 if (EoGetDesk(ewin) != DesksGetCurrent())
544 EwinMoveToDesktop(ewin, DesksGetCurrent());
551 DialogItemsRealize(d);
553 ewin = AddInternalToFamily(d->win, "DIALOG", EWIN_TYPE_DIALOG,
561 ewin->client.event_mask |= KeyPressMask;
562 ESelectInput(d->win, ewin->client.event_mask);
564 EwinMoveToDesktop(ewin, EoGetDesk(ewin));
566 if (ewin->state.placed)
568 EwinMoveResize(ewin, EoGetX(ewin), EoGetY(ewin), d->w, d->h);
572 EwinResize(ewin, d->w, d->h);
573 if (center || FindADialog() == 1)
574 ArrangeEwinCentered(ewin);
585 DialogShow(Dialog * d)
587 DialogShowArranged(d, 0);
591 DialogShowCentered(Dialog * d)
593 DialogShowArranged(d, 1);
597 DialogClose(Dialog * d)
603 _DialogClose(Dialog * d)
608 DialogCallExitFunction(d);
614 DialogShowSimple(const DialogDef * dd, void *data)
616 DialogShowSimpleWithName(dd, dd->name, data);
620 DialogFill(Dialog * d, DItem * parent, const DialogDef * dd, void *data)
624 if (Conf.dialogs.headers && (dd->header_image || dd->header_text))
625 DialogAddHeader(d, parent, dd->header_image, _(dd->header_text));
627 content = DialogAddItem(parent, DITEM_TABLE);
631 dd->fill(d, content, data);
634 DialogAddFooter(d, parent, dd->flags, dd->func);
638 DialogShowSimpleWithName(const DialogDef * dd, const char *name, void *data)
643 d = DialogFind(name);
646 SoundPlay(SOUND_SETTINGS_ACTIVE);
650 SoundPlay(dd->sound);
652 d = DialogCreate(name);
656 DialogSetTitle(d, _(dd->title));
658 table = DialogInitItem(d);
662 DialogFill(d, table, dd, data);
668 DialogItemCreate(int type)
672 di = ECALLOC(DItem, 1);
679 di->item.table.num_columns = 1;
680 di->item.table.border = 0;
681 di->item.table.homogenous_h = 0;
682 di->item.table.homogenous_v = 0;
683 di->item.table.num_items = 0;
684 di->item.table.items = NULL;
686 DialogItemSetPadding(di, 2, 2, 2, 2);
687 DialogItemSetFill(di, 1, 0);
693 DialogInitItem(Dialog * d)
700 di = DialogItemCreate(DITEM_TABLE);
706 di->item.table.num_columns = 1;
712 DialogAddItem(DItem * dii, int type)
716 di = DialogItemCreate(type);
725 di->item.area.w = 32;
726 di->item.area.h = 32;
728 case DITEM_CHECKBUTTON:
729 di->item.check_button.check_win = 0;
730 di->item.check_button.onoff = 0;
731 di->item.check_button.onoff_ptr = &(di->item.check_button.onoff);
732 di->item.check_button.check_orig_w = 10;
733 di->item.check_button.check_orig_h = 10;
736 di->item.table.num_columns = 1;
737 di->item.table.border = 0;
738 di->item.table.homogenous_h = 0;
739 di->item.table.homogenous_v = 0;
740 di->item.table.num_items = 0;
741 di->item.table.items = NULL;
744 di->item.image.image = NULL;
746 case DITEM_SEPARATOR:
747 di->item.separator.horizontal = 0;
749 case DITEM_RADIOBUTTON:
750 di->item.radio_button.radio_win = 0;
751 di->item.radio_button.onoff = 0;
752 di->item.radio_button.val = 0;
753 di->item.radio_button.val_ptr = 0;
754 di->item.radio_button.next = NULL;
755 di->item.radio_button.first = NULL;
756 di->item.radio_button.radio_orig_w = 10;
757 di->item.radio_button.radio_orig_h = 10;
758 di->item.radio_button.event_func = NULL;
761 di->item.slider.horizontal = 1;
762 di->item.slider.numeric = 0;
763 di->item.slider.numeric_side = 0;
764 di->item.slider.upper = 100;
765 di->item.slider.lower = 0;
766 di->item.slider.unit = 10;
767 di->item.slider.jump = 20;
768 di->item.slider.val = 0;
769 di->item.slider.val_ptr = NULL;
770 di->item.slider.min_length = 64;
771 di->item.slider.ic_base = NULL;
772 di->item.slider.ic_knob = NULL;
773 di->item.slider.base_win = 0;
774 di->item.slider.knob_win = 0;
775 di->item.slider.base_orig_w = 10;
776 di->item.slider.base_orig_h = 10;
777 di->item.slider.knob_orig_w = 6;
778 di->item.slider.knob_orig_h = 6;
779 di->item.slider.base_x = 0;
780 di->item.slider.base_y = 0;
781 di->item.slider.base_w = 0;
782 di->item.slider.base_h = 0;
783 di->item.slider.knob_x = 0;
784 di->item.slider.knob_y = 0;
785 di->item.slider.knob_w = 0;
786 di->item.slider.knob_h = 0;
787 di->item.slider.numeric_x = 0;
788 di->item.slider.numeric_y = 0;
789 di->item.slider.numeric_w = 0;
790 di->item.slider.numeric_h = 0;
791 di->item.slider.in_drag = 0;
797 dii->item.table.num_items++;
798 dii->item.table.items =
799 EREALLOC(DItem *, dii->item.table.items, dii->item.table.num_items);
800 dii->item.table.items[dii->item.table.num_items - 1] = di;
808 DialogAddHeader(Dialog * d __UNUSED__, DItem * parent, const char *img,
813 table = DialogAddItem(parent, DITEM_TABLE);
814 DialogItemTableSetOptions(table, 2, 0, 0, 0);
815 DialogItemSetAlign(table, 512, 0);
816 DialogItemSetFill(table, 0, 0);
818 di = DialogAddItem(table, DITEM_IMAGE);
819 DialogItemImageSetFile(di, img);
821 di = DialogAddItem(table, DITEM_TEXT);
822 DialogItemSetText(di, txt);
824 di = DialogAddItem(parent, DITEM_SEPARATOR);
828 DialogAddFooter(Dialog * d, DItem * parent, int flags, DialogCallbackFunc * cb)
833 if (!(flags & DLG_NO_SEPARATOR))
834 di = DialogAddItem(parent, DITEM_SEPARATOR);
836 table = DialogAddItem(parent, DITEM_TABLE);
837 DialogItemSetAlign(table, 512, 0);
838 DialogItemSetFill(table, 0, 0);
840 /* FIXME - The "real" dialog buttons are slightly different */
844 di = DialogItemAddButton(table, _("OK"), cb, 0, 1, DLG_BUTTON_OK);
849 di = DialogItemAddButton(table, _("Apply"), cb, 1, 0, DLG_BUTTON_APPLY);
850 DialogBindKey(d, "Return", cb, 1, NULL);
856 DialogItemAddButton(table, _("Close"), NULL, 0, 1, DLG_BUTTON_CLOSE);
857 DialogBindKey(d, "Escape", DialogCallbackClose, 0, NULL);
861 DialogItemTableSetOptions(table, n_buttons, 0, 1, 0);
863 DialogSetExitFunction(d, cb, 2);
867 DialogItemGetDialog(DItem * di)
873 DialogItemSetCallback(DItem * di, DialogCallbackFunc * func, int val,
882 DialogItemSetPadding(DItem * di, int left, int right, int top, int bottom)
884 di->padding.left = left;
885 di->padding.right = right;
886 di->padding.top = top;
887 di->padding.bottom = bottom;
891 DialogItemSetFill(DItem * di, char fill_h, char fill_v)
898 DialogItemSetAlign(DItem * di, int align_h, int align_v)
900 di->align_h = align_h;
901 di->align_v = align_v;
905 DialogItemSetRowSpan(DItem * di, int row_span)
907 di->row_span = row_span;
911 DialogItemSetColSpan(DItem * di, int col_span)
913 di->col_span = col_span;
917 DialogItemCallCallback(Dialog * d, DItem * di)
920 di->func(d, di->val, di->data);
924 DialogRealizeItem(Dialog * d, DItem * di)
926 const char *iclass, *tclass;
928 int register_win_callback;
932 if (di->realized && di->type != DITEM_TABLE)
936 iclass = tclass = NULL;
937 if (di->type == DITEM_BUTTON)
939 iclass = "DIALOG_WIDGET_BUTTON";
942 else if (di->type == DITEM_CHECKBUTTON)
944 iclass = "DIALOG_WIDGET_CHECK_BUTTON";
947 else if (di->type == DITEM_TEXT)
949 tclass = "DIALOG_WIDGET_TEXT";
951 else if (di->type == DITEM_SEPARATOR)
953 iclass = "DIALOG_WIDGET_SEPARATOR";
955 else if (di->type == DITEM_RADIOBUTTON)
957 iclass = "DIALOG_WIDGET_RADIO_BUTTON";
961 else if (di->type == DITEM_SLIDER)
966 else if (di->type == DITEM_AREA)
968 iclass = "DIALOG_WIDGET_AREA";
971 if (!di->iclass && iclass)
973 di->iclass = ImageclassAlloc(iclass, 1);
976 di->type = DITEM_NONE;
981 if (!di->tclass && tclass)
983 di->tclass = TextclassAlloc(tclass, 1);
986 di->type = DITEM_NONE;
991 if (di->type == DITEM_TABLE)
995 for (i = 0; i < di->item.table.num_items; i++)
996 DialogRealizeItem(d, di->item.table.items[i]);
999 register_win_callback = 1;
1004 if (di->item.slider.numeric)
1006 di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
1007 EMapWindow(di->win);
1008 ESelectInput(di->win,
1009 EnterWindowMask | LeaveWindowMask |
1010 ButtonPressMask | ButtonReleaseMask);
1012 di->item.slider.base_win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
1013 EMapWindow(di->item.slider.base_win);
1014 di->item.slider.knob_win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
1015 EMapWindow(di->item.slider.knob_win);
1016 ESelectInput(di->item.slider.base_win,
1017 EnterWindowMask | LeaveWindowMask |
1018 ButtonPressMask | ButtonReleaseMask);
1019 EventCallbackRegister(di->item.slider.base_win, 0, DItemHandleEvents,
1021 ESelectInput(di->item.slider.knob_win,
1022 EnterWindowMask | LeaveWindowMask |
1023 ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
1024 EventCallbackRegister(di->item.slider.knob_win, 0, DItemHandleEvents,
1027 if (!di->item.slider.ic_base)
1029 if (di->item.slider.horizontal)
1030 di->item.slider.ic_base =
1031 ImageclassAlloc("DIALOG_WIDGET_SLIDER_BASE_HORIZONTAL", 1);
1033 di->item.slider.ic_base =
1034 ImageclassAlloc("DIALOG_WIDGET_SLIDER_BASE_VERTICAL", 1);
1036 im = ImageclassGetImage(di->item.slider.ic_base, 0, 0, 0);
1039 EImageGetSize(im, &di->item.slider.base_orig_w,
1040 &di->item.slider.base_orig_h);
1044 if (!di->item.slider.ic_knob)
1046 if (di->item.slider.horizontal)
1047 di->item.slider.ic_knob =
1048 ImageclassAlloc("DIALOG_WIDGET_SLIDER_KNOB_HORIZONTAL", 1);
1050 di->item.slider.ic_knob =
1051 ImageclassAlloc("DIALOG_WIDGET_SLIDER_KNOB_VERTICAL", 1);
1053 im = ImageclassGetImage(di->item.slider.ic_knob, 0, 0, 0);
1056 EImageGetSize(im, &di->item.slider.knob_orig_w,
1057 &di->item.slider.knob_orig_h);
1061 pad = ImageclassGetPadding(di->item.slider.ic_base);
1062 if (di->item.slider.horizontal)
1064 iw = di->item.slider.min_length + pad->left + pad->right;
1065 ih = di->item.slider.base_orig_h;
1069 iw = di->item.slider.base_orig_w;
1070 ih = di->item.slider.min_length + pad->top + pad->bottom;
1076 pad = ImageclassGetPadding(di->iclass);
1077 TextSize(di->tclass, 0, 0, STATE_NORMAL, di->text, &iw, &ih, 17);
1078 iw += pad->left + pad->right;
1079 ih += pad->top + pad->bottom;
1080 di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
1081 EMapWindow(di->win);
1082 ESelectInput(di->win,
1083 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
1089 pad = ImageclassGetPadding(di->iclass);
1090 iw = di->item.area.w;
1091 ih = di->item.area.h;
1092 iw += pad->left + pad->right;
1093 ih += pad->top + pad->bottom;
1094 di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
1095 EMapWindow(di->win);
1096 di->item.area.area_win = ECreateWindow(di->win, -20, -20, 2, 2, 0);
1097 EMapWindow(di->item.area.area_win);
1098 ESelectInput(di->item.area.area_win,
1099 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
1100 ButtonReleaseMask | PointerMotionMask);
1101 EventCallbackRegister(di->item.area.area_win, 0, DItemHandleEvents, di);
1105 case DITEM_CHECKBUTTON:
1106 pad = ImageclassGetPadding(di->iclass);
1107 im = ImageclassGetImage(di->iclass, 0, 0, 0);
1110 EImageGetSize(im, &di->item.check_button.check_orig_w,
1111 &di->item.check_button.check_orig_h);
1114 TextSize(di->tclass, 0, 0, STATE_NORMAL, di->text, &iw, &ih, 17);
1115 if (ih < di->item.check_button.check_orig_h)
1116 ih = di->item.check_button.check_orig_h;
1117 iw += di->item.check_button.check_orig_w + pad->left;
1118 di->item.check_button.check_win =
1119 ECreateWindow(d->win, -20, -20, 2, 2, 0);
1120 di->win = ECreateEventWindow(d->win, -20, -20, 2, 2);
1121 EMapWindow(di->item.check_button.check_win);
1122 EMapWindow(di->win);
1123 ESelectInput(di->win,
1124 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
1130 TextSize(di->tclass, 0, 0, STATE_NORMAL, di->text, &iw, &ih, 17);
1135 im = ThemeImageLoad(di->item.image.image);
1138 EImageGetSize(im, &iw, &ih);
1139 di->win = ECreateWindow(d->win, 0, 0, iw, ih, 0);
1140 EMapWindow(di->win);
1141 EImageApplyToWin(im, di->win, 0, 0, 0);
1146 register_win_callback = 0;
1148 case DITEM_SEPARATOR:
1149 pad = ImageclassGetPadding(di->iclass);
1150 iw = pad->left + pad->right;
1151 ih = pad->top + pad->bottom;
1152 di->win = ECreateWindow(d->win, -20, -20, 2, 2, 0);
1153 EMapWindow(di->win);
1156 register_win_callback = 0;
1158 case DITEM_RADIOBUTTON:
1159 pad = ImageclassGetPadding(di->iclass);
1160 im = ImageclassGetImage(di->iclass, 0, 0, 0);
1163 EImageGetSize(im, &di->item.radio_button.radio_orig_w,
1164 &di->item.radio_button.radio_orig_h);
1167 TextSize(di->tclass, 0, 0, STATE_NORMAL, di->text, &iw, &ih, 17);
1168 if (ih < di->item.radio_button.radio_orig_h)
1169 ih = di->item.radio_button.radio_orig_h;
1170 iw += di->item.radio_button.radio_orig_w + pad->left;
1171 di->item.radio_button.radio_win =
1172 ECreateWindow(d->win, -20, -20, 2, 2, 0);
1173 di->win = ECreateEventWindow(d->win, -20, -20, 2, 2);
1174 EMapWindow(di->item.radio_button.radio_win);
1175 EMapWindow(di->win);
1176 ESelectInput(di->win,
1177 EnterWindowMask | LeaveWindowMask | ButtonPressMask |
1186 pad = ImageclassGetPadding(d->iclass);
1188 cols = di->item.table.num_columns;
1193 int *col_size, *row_size;
1195 col_size = EMALLOC(int, cols);
1196 row_size = EMALLOC(int, rows);
1199 for (i = 0; i < cols; i++)
1203 for (i = 0; i < di->item.table.num_items; i++)
1208 dii = di->item.table.items[i];
1209 w = dii->w + (dii->padding.left + dii->padding.right);
1210 h = dii->h + (dii->padding.top + dii->padding.bottom);
1212 for (j = 0; j < dii->col_span; j++)
1213 ww += col_size[c + j];
1216 ww = (w + dii->col_span - 1) / dii->col_span;
1217 for (j = 0; j < dii->col_span; j++)
1218 if (col_size[c + j] < ww)
1219 col_size[c + j] = ww;
1221 if (h > row_size[r])
1229 row_size = EREALLOC(int, row_size, rows);
1231 row_size[rows - 1] = 0;
1234 if (di->item.table.homogenous_h)
1238 for (i = 0; i < cols; i++)
1240 if (col_size[i] > max)
1243 for (i = 0; i < cols; i++)
1246 if (di->item.table.homogenous_v)
1250 for (i = 0; i < rows; i++)
1252 if (row_size[i] > max)
1255 for (i = 0; i < rows; i++)
1260 for (i = 0; i < cols; i++)
1262 for (i = 0; i < rows; i++)
1269 for (i = 0; i < di->item.table.num_items; i++)
1272 int j, sw = 0, sh = 0;
1274 dii = di->item.table.items[i];
1276 for (j = 0; j < dii->col_span; j++)
1277 sw += col_size[c + j];
1278 for (j = 0; j < dii->row_span; j++)
1279 sh += row_size[r + j];
1281 dii->w = sw - (dii->padding.left + dii->padding.right);
1283 dii->h = sh - (dii->padding.top + dii->padding.bottom);
1284 if (dii->w <= 0 || dii->h <= 0)
1286 if (dii->type == DITEM_TABLE)
1288 int dx, dy, newx, newy;
1291 di->x + x + pad->left +
1294 - (dii->padding.left + dii->padding.right) -
1295 dii->w) * dii->align_h) >> 10);
1297 di->y + y + pad->top +
1300 - (dii->padding.top + dii->padding.bottom) -
1301 dii->h) * dii->align_v) >> 10);
1302 dx = newx - dii->x - pad->left;
1303 dy = newy - dii->y - pad->top;
1304 MoveTableBy(d, dii, dx, dy);
1309 di->x + x + pad->left +
1312 - (dii->padding.left + dii->padding.right) -
1313 dii->w) * dii->align_h) >> 10);
1315 di->y + y + pad->top +
1318 - (dii->padding.top + dii->padding.bottom) -
1319 dii->h) * dii->align_v) >> 10);
1321 EMoveResizeWindow(dii->win, dii->x, dii->y,
1323 if (dii->type == DITEM_CHECKBUTTON)
1324 EMoveResizeWindow(dii->item.check_button.
1328 dii->item.check_button.
1330 dii->item.check_button.
1332 dii->item.check_button.
1334 if (dii->type == DITEM_RADIOBUTTON)
1335 EMoveResizeWindow(dii->item.radio_button.
1339 dii->item.radio_button.
1341 dii->item.radio_button.
1343 dii->item.radio_button.
1345 if (dii->type == DITEM_AREA)
1347 pad = ImageclassGetPadding(dii->iclass);
1349 dii->w - (pad->left + pad->right);
1351 dii->h - (pad->top + pad->bottom);
1352 EMoveResizeWindow(dii->item.area.area_win,
1353 pad->left, pad->top,
1357 if (dii->type == DITEM_SLIDER)
1359 dii->item.slider.base_x = 0;
1360 dii->item.slider.base_y = 0;
1361 dii->item.slider.base_w = dii->w;
1362 dii->item.slider.base_h = dii->h;
1363 dii->item.slider.knob_w =
1364 dii->item.slider.knob_orig_w;
1365 dii->item.slider.knob_h =
1366 dii->item.slider.knob_orig_h;
1367 if (dii->item.slider.base_win)
1368 EMoveResizeWindow(dii->item.slider.base_win,
1370 dii->item.slider.base_x,
1372 dii->item.slider.base_y,
1373 dii->item.slider.base_w,
1374 dii->item.slider.base_h);
1376 EMoveResizeWindow(dii->win,
1385 dii->item.slider.numeric_h);
1411 if (di->win && register_win_callback)
1412 EventCallbackRegister(di->win, 0, DItemHandleEvents, di);
1416 MoveTableBy(Dialog * d, DItem * di, int dx, int dy)
1422 for (i = 0; i < di->item.table.num_items; i++)
1426 dii = di->item.table.items[i];
1428 if (dii->type == DITEM_TABLE)
1430 MoveTableBy(d, dii, dx, dy);
1438 EMoveWindow(dii->win, dii->x, dii->y);
1442 case DITEM_CHECKBUTTON:
1443 EMoveWindow(dii->item.check_button.check_win, dii->x,
1445 ((dii->h - dii->item.check_button.check_orig_h) / 2));
1447 case DITEM_RADIOBUTTON:
1448 EMoveWindow(dii->item.radio_button.radio_win, dii->x,
1450 ((dii->h - dii->item.radio_button.radio_orig_h) / 2));
1454 if (dii->item.slider.base_win)
1455 EMoveResizeWindow(dii->item.slider.base_win,
1456 dii->x + dii->item.slider.base_x,
1457 dii->y + dii->item.slider.base_y,
1458 dii->item.slider.base_w,
1459 dii->item.slider.base_h);
1460 if (dii->item.slider.knob_win)
1461 EMoveResizeWindow(dii->item.slider.knob_win,
1462 dii->x + dii->item.slider.knob_x,
1463 dii->y + dii->item.slider.knob_y,
1464 dii->item.slider.knob_w,
1465 dii->item.slider.knob_h);
1467 EMoveResizeWindow(dii->win,
1468 dii->x + dii->item.slider.numeric_x,
1469 dii->y + dii->item.slider.numeric_y,
1470 dii->item.slider.numeric_w,
1471 dii->item.slider.numeric_h);
1479 DialogDrawItems(Dialog * d, DItem * di, int x, int y, int w, int h)
1495 dialog_update_pending = 1;
1498 Eprintf("DialogDrawItems t=%d u=%d - %d,%d -> %d,%d\n", di->type, di->update,
1499 d->xu1, d->yu1, d->xu2, d->yu2);
1504 DialogDrawItem(Dialog * d, DItem * di)
1509 if (!di->update && di->type != DITEM_TABLE)
1512 if (di->x > d->xu2 || di->y > d->yu2 ||
1513 di->x + di->w <= d->xu1 || di->y + di->h <= d->yu1)
1517 Eprintf("DialogDrawItem t=%d u=%d - %d,%d -> %d,%d\n", di->type, di->update,
1518 d->xu1, d->yu1, d->xu2, d->yu2);
1528 for (i = 0; i < di->item.table.num_items; i++)
1530 dii = di->item.table.items[i];
1533 DialogDrawItem(d, dii);
1541 pad = ImageclassGetPadding(d->iclass);
1542 gcv.subwindow_mode = IncludeInferiors;
1543 gc = EXCreateGC(WinGetPmap(d->win), GCSubwindowMode, &gcv);
1544 XSetForeground(disp, gc, Dpy.pixel_black);
1545 XDrawRectangle(disp, WinGetPmap(d->win), gc,
1546 pad->left + di->x, pad->top + di->y, di->w, di->h);
1554 if (di->item.slider.horizontal)
1556 di->item.slider.knob_x = di->item.slider.base_x +
1557 (((di->item.slider.base_w - di->item.slider.knob_w) *
1558 (di->item.slider.val - di->item.slider.lower)) /
1559 (di->item.slider.upper - di->item.slider.lower));
1560 di->item.slider.knob_y = di->item.slider.base_y +
1561 ((di->item.slider.base_h - di->item.slider.knob_h) / 2);
1565 di->item.slider.knob_y = di->item.slider.base_y +
1566 (((di->item.slider.base_h - di->item.slider.knob_h) *
1567 (di->item.slider.val - di->item.slider.lower)) /
1568 (di->item.slider.upper - di->item.slider.lower));
1569 di->item.slider.knob_x = di->item.slider.base_x +
1570 ((di->item.slider.base_w - di->item.slider.knob_w) / 2);
1572 if (di->item.slider.knob_win)
1573 EMoveResizeWindow(di->item.slider.knob_win,
1574 di->x + di->item.slider.knob_x,
1575 di->y + di->item.slider.knob_y,
1576 di->item.slider.knob_w, di->item.slider.knob_h);
1577 if (di->item.slider.base_win)
1578 ImageclassApply(di->item.slider.ic_base,
1579 di->item.slider.base_win,
1580 0, 0, STATE_NORMAL, ST_WIDGET);
1581 state = STATE_NORMAL;
1582 if ((di->hilited) && (di->clicked))
1583 state = STATE_CLICKED;
1584 else if ((di->hilited) && (!di->clicked))
1585 state = STATE_HILITED;
1586 else if (!(di->hilited) && (di->clicked))
1587 state = STATE_CLICKED;
1588 if (di->item.slider.knob_win)
1589 ImageclassApply(di->item.slider.ic_knob,
1590 di->item.slider.knob_win, 0, 0, state, ST_WIDGET);
1594 state = STATE_NORMAL;
1595 if ((di->hilited) && (di->clicked))
1596 state = STATE_CLICKED;
1597 else if ((di->hilited) && (!di->clicked))
1598 state = STATE_HILITED;
1599 else if (!(di->hilited) && (di->clicked))
1600 state = STATE_CLICKED;
1601 ITApply(di->win, di->iclass, NULL, state, 0, 0,
1602 ST_WIDGET, di->tclass, NULL, di->text, 0);
1608 ImageclassApply(di->iclass, di->win, 0, 0, STATE_NORMAL, ST_DIALOG);
1609 if (di->item.area.init_func)
1610 di->item.area.init_func(di, 0, NULL);
1613 case DITEM_SEPARATOR:
1616 if (di->item.separator.horizontal)
1617 ImageclassApply(di->iclass, di->win, 0, 0, STATE_NORMAL, ST_WIDGET);
1619 ImageclassApply(di->iclass, di->win, 0, 0, STATE_CLICKED, ST_WIDGET);
1623 state = STATE_NORMAL;
1628 case DITEM_CHECKBUTTON:
1629 state = STATE_NORMAL;
1630 if ((di->hilited) && (di->clicked))
1631 state = STATE_CLICKED;
1632 else if ((di->hilited) && (!di->clicked))
1633 state = STATE_HILITED;
1634 else if (!(di->hilited) && (di->clicked))
1635 state = STATE_CLICKED;
1636 ImageclassApply(di->iclass, di->item.check_button.check_win,
1637 DialogItemCheckButtonGetState(di), 0, state, ST_WIDGET);
1639 (TextclassGetTextState(di->tclass, di->state, 0, 0) ==
1640 TextclassGetTextState(di->tclass, state, 0, 0)))
1642 pad = ImageclassGetPadding(di->iclass);
1643 x = di->x + di->item.check_button.check_orig_w + pad->left;
1644 w = di->w - di->item.check_button.check_orig_w - pad->left;
1647 case DITEM_RADIOBUTTON:
1648 state = STATE_NORMAL;
1649 if ((di->hilited) && (di->clicked))
1650 state = STATE_CLICKED;
1651 else if ((di->hilited) && (!di->clicked))
1652 state = STATE_HILITED;
1653 else if (!(di->hilited) && (di->clicked))
1654 state = STATE_CLICKED;
1655 ImageclassApply(di->iclass, di->item.radio_button.radio_win,
1656 di->item.radio_button.onoff, 0, state, ST_WIDGET);
1658 (TextclassGetTextState(di->tclass, di->state, 0, 0) ==
1659 TextclassGetTextState(di->tclass, state, 0, 0)))
1661 pad = ImageclassGetPadding(di->iclass);
1662 x = di->x + di->item.radio_button.radio_orig_w + pad->left;
1663 w = di->w - di->item.radio_button.radio_orig_w - pad->left;
1671 if (!di->text || !di->tclass)
1673 if (!d->redraw || di->update)
1674 EXCopyArea(d->pmm_bg.pmap, WinGetPmap(d->win),
1675 di->x, di->y, di->w, di->h, di->x, di->y);
1676 TextDraw(di->tclass, d->win, WinGetPmap(d->win), 0, 0, state, di->text,
1677 x, di->y, w, 99999, 17, TextclassGetJustification(di->tclass));
1686 DialogUpdate(Dialog * d)
1692 DialogDrawItem(d, d->item);
1695 if (d->xu1 < d->xu2 && d->yu1 < d->yu2)
1696 EClearArea(d->win, d->xu1, d->yu1, d->xu2 - d->xu1, d->yu2 - d->yu1);
1697 d->xu1 = d->yu1 = 99999;
1698 d->xu2 = d->yu2 = 0;
1702 _DialogsCheckUpdate(void *data __UNUSED__)
1706 if (!dialog_update_pending)
1708 dialog_update_pending = 0;
1710 ECORE_LIST_FOR_EACH(dialog_list, d)
1721 IdlerAdd(_DialogsCheckUpdate, NULL);
1725 DialogItemsRealize(Dialog * d)
1732 DialogRealizeItem(d, d->item);
1733 DialogDrawItems(d, d->item, 0, 0, 99999, 99999);
1734 pad = ImageclassGetPadding(d->iclass);
1735 d->w = d->item->w + pad->left + pad->right;
1736 d->h = d->item->h + pad->top + pad->bottom;
1737 EResizeWindow(d->win, d->w, d->h);
1741 DialogItemSetText(DItem * di, const char *text)
1744 di->text = Estrdup(text);
1748 DialogItemRadioButtonSetEventFunc(DItem * di, DialogItemCallbackFunc * func)
1750 di->item.radio_button.event_func = func;
1754 DialogItemRadioButtonSetFirst(DItem * di, DItem * first)
1756 di->item.radio_button.first = first;
1759 while (first->item.radio_button.next)
1760 first = first->item.radio_button.next;
1761 first->item.radio_button.next = di;
1765 DialogItemRadioButtonGroupSetValPtr(DItem * di, int *val_ptr)
1769 di->item.radio_button.val_ptr = val_ptr;
1770 if (*val_ptr == di->item.radio_button.val)
1771 di->item.radio_button.onoff = 1;
1772 di = di->item.radio_button.next;
1777 DialogItemRadioButtonGroupSetVal(DItem * di, int val)
1779 di->item.radio_button.val = val;
1783 DialogItemCheckButtonSetState(DItem * di, char onoff)
1785 *(di->item.check_button.onoff_ptr) = onoff;
1789 DialogItemCheckButtonSetPtr(DItem * di, char *onoff_ptr)
1791 di->item.check_button.onoff_ptr = onoff_ptr;
1795 DialogItemCheckButtonGetState(DItem * di)
1797 return *(di->item.check_button.onoff_ptr) ? 1 : 0;
1801 DialogItemTableSetOptions(DItem * di, int num_columns, char border,
1802 char homogenous_h, char homogenous_v)
1804 di->item.table.num_columns = num_columns;
1805 di->item.table.border = border;
1806 di->item.table.homogenous_h = homogenous_h;
1807 di->item.table.homogenous_v = homogenous_v;
1811 DialogItemSeparatorSetOrientation(DItem * di, char horizontal)
1813 di->item.separator.horizontal = horizontal;
1817 DialogItemImageSetFile(DItem * di, const char *image)
1819 Efree(di->item.image.image);
1820 di->item.image.image = Estrdup(image);
1826 DialogItemSliderSetVal(DItem * di, int val)
1828 if (val < di->item.slider.lower)
1829 val = di->item.slider.lower;
1830 else if (val > di->item.slider.upper)
1831 val = di->item.slider.upper;
1832 di->item.slider.val = val;
1833 if (di->item.slider.val_ptr)
1834 *di->item.slider.val_ptr = val;
1838 DialogItemSliderSetValPtr(DItem * di, int *val_ptr)
1840 di->item.slider.val_ptr = val_ptr;
1841 DialogItemSliderSetVal(di, *val_ptr);
1845 DialogItemSliderSetBounds(DItem * di, int lower, int upper)
1849 di->item.slider.lower = lower;
1850 di->item.slider.upper = upper;
1854 di->item.slider.lower = upper;
1855 di->item.slider.upper = lower;
1857 if (di->item.slider.upper <= di->item.slider.lower)
1858 di->item.slider.upper = di->item.slider.lower + 1;
1862 DialogItemSliderSetUnits(DItem * di, int units)
1864 di->item.slider.unit = units;
1868 DialogItemSliderSetJump(DItem * di, int jump)
1870 di->item.slider.jump = jump;
1874 DialogItemSliderSetMinLength(DItem * di, int min)
1876 di->item.slider.min_length = min;
1880 DialogItemSliderSetOrientation(DItem * di, char horizontal)
1882 di->item.slider.horizontal = horizontal;
1886 DialogItemSliderGetVal(DItem * di)
1888 return di->item.slider.val;
1892 DialogItemSliderGetBounds(DItem * di, int *lower, int *upper)
1895 *lower = di->item.slider.lower;
1897 *upper = di->item.slider.upper;
1901 DialogItemAreaSetSize(DItem * di, int w, int h)
1903 di->item.area.w = w;
1904 di->item.area.h = h;
1908 DialogItemAreaGetWindow(DItem * di)
1910 return di->item.area.area_win;
1914 DialogItemAreaGetSize(DItem * di, int *w, int *h)
1916 *w = di->item.area.w;
1917 *h = di->item.area.h;
1921 DialogItemAreaSetInitFunc(DItem * di, DialogItemCallbackFunc * func)
1923 di->item.area.init_func = func;
1927 DialogItemAreaSetEventFunc(DItem * di, DialogItemCallbackFunc * func)
1929 di->item.area.event_func = func;
1933 DialogItemTableEmpty(DItem * di)
1937 if (di->type != DITEM_TABLE)
1940 for (i = 0; i < di->item.table.num_items; i++)
1941 DialogItemDestroy(di->item.table.items[i], 1);
1943 Efree(di->item.table.items);
1944 di->item.table.items = NULL;
1945 di->item.table.num_items = 0;
1949 DialogItemDestroy(DItem * di, int clean)
1951 if (di->type == DITEM_TABLE)
1952 DialogItemTableEmpty(di);
1960 case DITEM_CHECKBUTTON:
1963 EDestroyWindow(di->item.check_button.check_win);
1966 Efree(di->item.image.image);
1968 case DITEM_RADIOBUTTON:
1971 EDestroyWindow(di->item.radio_button.radio_win);
1974 ImageclassFree(di->item.slider.ic_base);
1975 ImageclassFree(di->item.slider.ic_knob);
1978 EDestroyWindow(di->item.slider.base_win);
1979 EDestroyWindow(di->item.slider.knob_win);
1984 EDestroyWindow(di->item.area.area_win);
1988 if (clean && di->win)
1989 EDestroyWindow(di->win);
1990 ImageclassFree(di->iclass);
1991 TextclassFree(di->tclass);
1996 /* Convenience callback to close dialog */
1998 DialogCallbackClose(Dialog * d, int val __UNUSED__, void *data __UNUSED__)
2004 * Predefined dialogs
2008 DialogOK(const char *title, const char *fmt, ...)
2013 va_start(args, fmt);
2014 Evsnprintf(text, sizeof(text), fmt, args);
2017 DialogOKstr(title, text);
2021 DialogOKstr(const char *title, const char *txt)
2026 d = DialogCreate("DIALOG");
2028 table = DialogInitItem(d);
2029 DialogSetTitle(d, title);
2031 di = DialogAddItem(table, DITEM_TEXT);
2032 DialogItemSetText(di, txt);
2034 di = DialogItemAddButton(table, _("OK"), DialogCallbackClose, 0, 1,
2036 DialogItemSetFill(di, 0, 0);
2038 DialogBindKey(d, "Return", DialogCallbackClose, 0, NULL);
2039 DialogBindKey(d, "Escape", DialogCallbackClose, 0, NULL);
2045 * Dialog event handlers
2048 _DlgPixToVal(const DItem * di, int dx, int sr)
2052 vr = di->item.slider.upper - di->item.slider.lower;
2053 dx = (int)(((float)dx / (sr * di->item.slider.unit)) * vr + .5);
2054 dx *= di->item.slider.unit;
2055 value = di->item.slider.lower + dx;
2057 if (value < di->item.slider.lower)
2058 value = di->item.slider.lower;
2059 if (value > di->item.slider.upper)
2060 value = di->item.slider.upper;
2066 DialogEventKeyPress(Dialog * d, XEvent * ev)
2070 for (i = 0; i < d->num_bindings; i++)
2072 if (ev->xkey.keycode != d->keybindings[i].key)
2074 d->keybindings[i].func(d, d->keybindings[i].val,
2075 d->keybindings[i].data);
2081 DialogHandleEvents(Win win __UNUSED__, XEvent * ev, void *prm)
2083 Dialog *d = (Dialog *) prm;
2088 DialogEventKeyPress(d, ev);
2097 DItemEventMotion(Win win __UNUSED__, DItem * di, XEvent * ev)
2102 if (di->item.area.event_func)
2103 di->item.area.event_func(di, 0, ev);
2107 if (!di->item.slider.in_drag)
2109 if (ev->xmotion.window == WinGetXwin(di->item.slider.knob_win))
2111 if (di->item.slider.horizontal)
2113 di->item.slider.val =
2115 ev->xbutton.x + di->item.slider.knob_x -
2116 di->item.slider.knob_w / 2,
2117 di->item.slider.base_w -
2118 di->item.slider.knob_w);
2122 di->item.slider.val =
2124 ev->xbutton.y + di->item.slider.knob_y -
2125 di->item.slider.knob_h / 2,
2126 di->item.slider.base_h -
2127 di->item.slider.knob_h);
2129 if (di->item.slider.val_ptr)
2130 *di->item.slider.val_ptr = di->item.slider.val;
2132 (di->func) (di->dlg, di->val, di->data);
2135 DialogDrawItems(di->dlg, di, di->x, di->y, di->w, di->h);
2141 DItemEventMouseDown(Win win, DItem * di, XEvent * ev)
2143 int x, y, wheel_jump;
2148 if (di->item.area.event_func)
2149 di->item.area.event_func(di, 0, ev);
2153 if (ev->xbutton.window == WinGetXwin(di->item.slider.knob_win))
2155 if (ev->xbutton.button >= 1 && ev->xbutton.button <= 3)
2157 di->item.slider.in_drag = 1;
2162 /* Coords -> item.slider.base_win */
2163 ETranslateCoordinates(win, di->item.slider.base_win,
2164 ev->xbutton.x, ev->xbutton.y, &x, &y, NULL);
2166 switch (ev->xbutton.button)
2170 if (di->item.slider.horizontal)
2173 (di->item.slider.knob_x + (di->item.slider.knob_w / 2)))
2174 di->item.slider.val += di->item.slider.jump;
2176 di->item.slider.val -= di->item.slider.jump;
2181 (di->item.slider.knob_y + (di->item.slider.knob_h / 2)))
2182 di->item.slider.val += di->item.slider.jump;
2184 di->item.slider.val -= di->item.slider.jump;
2189 if (di->item.slider.horizontal)
2191 di->item.slider.val =
2193 ev->xbutton.x - di->item.slider.knob_w / 2,
2194 di->item.slider.base_w -
2195 di->item.slider.knob_w);
2199 di->item.slider.val =
2201 ev->xbutton.y - di->item.slider.knob_h / 2,
2202 di->item.slider.base_h -
2203 di->item.slider.knob_h);
2209 wheel_jump = di->item.slider.jump / 2;
2213 if (ev->xbutton.button == 5)
2215 di->item.slider.val -= wheel_jump;
2217 else if (ev->xbutton.button == 4)
2219 di->item.slider.val += wheel_jump;
2223 if (di->item.slider.val < di->item.slider.lower)
2224 di->item.slider.val = di->item.slider.lower;
2225 if (di->item.slider.val > di->item.slider.upper)
2226 di->item.slider.val = di->item.slider.upper;
2227 if (di->item.slider.val_ptr)
2228 *di->item.slider.val_ptr = di->item.slider.val;
2231 (di->func) (d, di->val, di->data);
2238 DialogDrawItems(di->dlg, di, di->x, di->y, di->w, di->h);
2242 DItemEventMouseUp(Win win, DItem * di, XEvent * ev)
2246 if (ev->xbutton.window != Mode.events.last_bpress)
2252 if (di->item.area.event_func)
2253 di->item.area.event_func(di, 0, ev);
2256 case DITEM_CHECKBUTTON:
2257 DialogItemCheckButtonSetState(di, !DialogItemCheckButtonGetState(di));
2260 case DITEM_RADIOBUTTON:
2261 dii = di->item.radio_button.first;
2264 if (dii->item.radio_button.onoff)
2266 dii->item.radio_button.onoff = 0;
2267 DialogDrawItems(di->dlg, dii, dii->x, dii->y, dii->w, dii->h);
2269 dii = dii->item.radio_button.next;
2271 di->item.radio_button.onoff = 1;
2272 if (di->item.radio_button.val_ptr)
2273 *di->item.radio_button.val_ptr = di->item.radio_button.val;
2277 if (win == di->item.slider.knob_win)
2278 di->item.slider.in_drag = 0;
2282 if (di->hilited && di->clicked)
2285 di->func(di->dlg, di->val, di->data);
2293 DialogDrawItems(di->dlg, di, di->x, di->y, di->w, di->h);
2297 DItemEventMouseIn(Win win __UNUSED__, DItem * di, XEvent * ev)
2302 if (di->item.area.event_func)
2303 di->item.area.event_func(di, 0, ev);
2306 case DITEM_RADIOBUTTON:
2307 if (di->item.radio_button.event_func)
2308 di->item.radio_button.event_func(di, di->item.radio_button.val, ev);
2314 DialogDrawItems(di->dlg, di, di->x, di->y, di->w, di->h);
2318 DItemEventMouseOut(Win win __UNUSED__, DItem * di, XEvent * ev)
2323 if (di->item.area.event_func)
2324 di->item.area.event_func(di, 0, ev);
2327 case DITEM_RADIOBUTTON:
2328 if (di->item.radio_button.event_func)
2329 di->item.radio_button.event_func(di, di->item.radio_button.val,
2337 DialogDrawItems(di->dlg, di, di->x, di->y, di->w, di->h);
2341 DItemHandleEvents(Win win, XEvent * ev, void *prm)
2343 DItem *di = (DItem *) prm;
2348 DItemEventMouseDown(win, di, ev);
2351 DItemEventMouseUp(win, di, ev);
2354 DItemEventMotion(win, di, ev);
2357 DItemEventMouseIn(win, di, ev);
2360 DItemEventMouseOut(win, di, ev);
2365 _DialogClose(di->dlg);
2373 FindEwinByDialog(Dialog * d)
2378 ewins = EwinListGetAll(&num);
2379 for (i = 0; i < num; i++)
2381 if ((Dialog *) (ewins[i]->data) == d)
2394 ewins = EwinListGetAll(&num);
2395 for (i = n = 0; i < num; i++)
2397 if (ewins[i]->type == EWIN_TYPE_DIALOG)
2404 #endif /* ENABLE_DIALOGS */