wrlib: return NULL if XImage could not be taken, for consistency
[wmaker-crm.git] / WPrefs.app / Docks.c
blob8404941971932b19af9aadddb1e078d2d386f6d5
1 /* Workspace.c- workspace options
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 2012 Daniel Déchelotte (heavily inspired from file (c) Alfredo K. Kojima)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "WPrefs.h"
24 typedef struct _Panel {
25 WMBox *box;
27 char *sectionName;
29 char *description;
31 CallbackRec callbacks;
33 WMWidget *parent;
35 WMFrame *autoDelayF[2];
36 WMLabel *autoDelayL[4];
37 WMButton *autoDelayB[4][5];
38 WMTextField *autoDelayT[4];
39 WMLabel *autoDelayMsL[4];
41 WMFrame *dockF;
42 WMButton *docksB[3];
43 } _Panel;
45 #define ICON_FILE "dockclipdrawersection"
47 #define ARQUIVO_XIS "xis"
48 #define DELAY_ICON "timer%i"
49 #define DELAY_ICON_S "timer%is"
51 static const struct {
52 const char *key;
53 const char *string;
54 } auto_delay[] = {
55 { "ClipAutoexpandDelay", N_("Before auto-expansion") },
56 { "ClipAutocollapseDelay", N_("Before auto-collapsing") },
57 { "ClipAutoraiseDelay", N_("Before auto-raise") },
58 { "ClipAutolowerDelay", N_("Before auto-lowering") }
62 static char *autoDelayPresetValues[5] = { "0", "100", "250", "600", "1000" };
64 static const struct {
65 const char *disable_key;
66 const char *icon_file;
67 } dock_config[] = {
68 { "DisableDock", "dock" },
69 { "DisableClip", "clip" },
70 { "DisableDrawers", "drawer" }
73 static void showData(_Panel *panel);
74 static void storeData(_Panel *panel);
77 static void pushAutoDelayButton(WMWidget *w, void *data)
79 _Panel *panel = (_Panel *) data;
80 int i, j;
81 for (i = 0; i < 4; i++)
83 for (j = 0; j < 5; j++)
85 if (w == panel->autoDelayB[i][j])
87 WMSetTextFieldText(panel->autoDelayT[i], autoDelayPresetValues[j]);
88 return;
94 static void adjustButtonSelectionBasedOnValue(_Panel *panel, int row, const char *value)
96 int j;
98 if (!value)
99 return;
101 for (j = 0; j < 5; j++)
103 int isThatOne = !strcmp(autoDelayPresetValues[j], value);
104 WMSetButtonSelected(panel->autoDelayB[row][j], isThatOne);
105 if (isThatOne)
106 return;
110 static void autoDelayChanged(void *observerData, WMNotification *notification)
112 _Panel *panel = (_Panel *) observerData;
113 int row;
114 WMTextField *anAutoDelayT = (WMTextField *) WMGetNotificationObject(notification);
115 for (row = 0; row < 4; row++)
117 if (anAutoDelayT != panel->autoDelayT[row])
119 continue;
121 char *value = WMGetTextFieldText(anAutoDelayT);
122 adjustButtonSelectionBasedOnValue(panel, row, value);
123 free(value);
124 return;
128 static void pushDockButton(WMWidget *w, void *data)
130 _Panel *panel = (_Panel *) data;
131 WMButton *button = (WMButton *) w;
132 if (button == panel->docksB[0] &&
133 !WMGetButtonSelected(panel->docksB[0]))
135 WMSetButtonSelected(panel->docksB[2], False);
137 if (button == panel->docksB[2] &&
138 WMGetButtonSelected(panel->docksB[2]))
140 WMSetButtonSelected(panel->docksB[0], True);
144 static void createPanel(Panel *p)
146 _Panel *panel = (_Panel *) p;
147 WMScreen *scr = WMWidgetScreen(panel->parent);
148 WMPixmap *icon1, *icon2;
149 RImage *xis = NULL;
150 RContext *rc = WMScreenRContext(scr);
151 char *path;
152 int i, j, k;
153 char *buf1, *buf2;
154 WMColor *color;
155 WMFont *font;
157 path = LocateImage(ARQUIVO_XIS);
158 if (path) {
159 xis = RLoadImage(rc, path, 0);
160 if (!xis) {
161 wwarning(_("could not load image file %s"), path);
163 wfree(path);
166 panel->box = WMCreateBox(panel->parent);
167 WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
169 /***************** Auto-delays *****************/
170 buf1 = wmalloc(strlen(DELAY_ICON) + 1);
171 buf2 = wmalloc(strlen(DELAY_ICON_S) + 1);
173 for (k = 0; k < 2; k++)
175 panel->autoDelayF[k] = WMCreateFrame(panel->box);
176 WMResizeWidget(panel->autoDelayF[k], 370, 100);
177 WMMoveWidget(panel->autoDelayF[k], 15, 10 + k * 110);
178 if (k == 0)
179 WMSetFrameTitle(panel->autoDelayF[k], _("Clip autocollapsing delays"));
180 else
181 WMSetFrameTitle(panel->autoDelayF[k], _("Clip autoraising delays"));
183 for (i = 0; i < 2; i++)
185 panel->autoDelayL[i + k * 2] = WMCreateLabel(panel->autoDelayF[k]);
186 WMResizeWidget(panel->autoDelayL[i + k * 2], 155, 20);
187 WMMoveWidget(panel->autoDelayL[i + k * 2], 10, 27 + 40 * i);
188 WMSetLabelText(panel->autoDelayL[i + k * 2], _(auto_delay[i + k * 2].string));
189 /* WMSetLabelTextAlignment(panel->autoDelayL[i + k * 2], WARight); */
191 for (j = 0; j < 5; j++)
193 panel->autoDelayB[i + k * 2][j] = WMCreateCustomButton(panel->autoDelayF[k], WBBStateChangeMask);
194 WMResizeWidget(panel->autoDelayB[i + k * 2][j], 25, 25);
195 WMMoveWidget(panel->autoDelayB[i + k * 2][j], 145 + (28 * j), 25 + 40 * i);
196 WMSetButtonBordered(panel->autoDelayB[i + k * 2][j], False);
197 WMSetButtonImagePosition(panel->autoDelayB[i + k * 2][j], WIPImageOnly);
198 WMSetButtonAction(panel->autoDelayB[i + k * 2][j], pushAutoDelayButton, panel);
199 if (j > 0)
200 WMGroupButtons(panel->autoDelayB[i + k * 2][0], panel->autoDelayB[i + k * 2][j]);
201 sprintf(buf1, DELAY_ICON, j);
202 CreateImages(scr, rc, NULL, buf1, &icon1, NULL);
203 if (icon1) {
204 WMSetButtonImage(panel->autoDelayB[i + k * 2][j], icon1);
205 WMReleasePixmap(icon1);
206 } else {
207 wwarning(_("could not load icon file %s"), buf1);
209 sprintf(buf2, DELAY_ICON_S, j);
210 CreateImages(scr, rc, NULL, buf2, &icon2, NULL);
211 if (icon2) {
212 WMSetButtonAltImage(panel->autoDelayB[i + k * 2][j], icon2);
213 WMReleasePixmap(icon2);
214 } else {
215 wwarning(_("could not load icon file %s"), buf2);
219 panel->autoDelayT[i + k * 2] = WMCreateTextField(panel->autoDelayF[k]);
220 WMResizeWidget(panel->autoDelayT[i + k * 2], 36, 20);
221 WMMoveWidget(panel->autoDelayT[i + k * 2], 287, 27 + 40 * i);
222 WMAddNotificationObserver(autoDelayChanged, panel, WMTextDidChangeNotification, panel->autoDelayT[i + k * 2]);
224 color = WMDarkGrayColor(scr);
225 font = WMSystemFontOfSize(scr, 10);
226 panel->autoDelayMsL[i + k * 2] = WMCreateLabel(panel->autoDelayF[k]);
227 WMResizeWidget(panel->autoDelayMsL[i + k * 2], 36, 16);
228 WMMoveWidget(panel->autoDelayMsL[i + k * 2], 327, 33 + 40 *i);
229 WMSetLabelText(panel->autoDelayMsL[i + k * 2], _("msec"));
230 WMSetLabelTextColor(panel->autoDelayMsL[i + k * 2], color);
231 WMSetLabelFont(panel->autoDelayMsL[i + k * 2], font);
232 WMReleaseColor(color);
233 WMReleaseFont(font);
236 WMMapSubwidgets(panel->autoDelayF[k]);
238 wfree(buf1);
239 wfree(buf2);
241 /***************** Enable/disable clip/dock/drawers *****************/
242 panel->dockF = WMCreateFrame(panel->box);
243 WMResizeWidget(panel->dockF, 115, 210);
244 WMMoveWidget(panel->dockF, 390, 10);
245 WMSetFrameTitle(panel->dockF, _("Dock/Clip/Drawer"));
247 for (i = 0; i < 3; i++)
249 panel->docksB[i] = WMCreateButton(panel->dockF, WBTToggle);
250 WMResizeWidget(panel->docksB[i], 56, 56);
251 WMMoveWidget(panel->docksB[i], 30, 20 + 62 * i);
252 WMSetButtonImagePosition(panel->docksB[i], WIPImageOnly);
253 CreateImages(scr, rc, xis, dock_config[i].icon_file, &icon1, &icon2);
254 if (icon2) {
255 WMSetButtonImage(panel->docksB[i], icon2);
256 WMReleasePixmap(icon2);
258 if (icon1) {
259 WMSetButtonAltImage(panel->docksB[i], icon1);
260 WMReleasePixmap(icon1);
262 switch(i)
264 case 0:
265 WMSetBalloonTextForView(_("Disable/enable the application Dock (the\n"
266 "vertical icon bar in the side of the screen)."), WMWidgetView(panel->docksB[i]));
267 break;
268 case 1:
269 WMSetBalloonTextForView(_("Disable/enable the Clip (that thing with\n"
270 "a paper clip icon)."), WMWidgetView(panel->docksB[i]));
271 break;
272 case 2:
273 WMSetBalloonTextForView(_("Disable/enable Drawers (a dock that stores\n"
274 "application icons horizontally). The dock is required."), WMWidgetView(panel->docksB[i]));
275 break;
277 WMSetButtonAction(panel->docksB[i], pushDockButton, panel);
280 WMMapSubwidgets(panel->dockF);
282 if (xis)
283 RReleaseImage(xis);
285 WMRealizeWidget(panel->box);
286 WMMapSubwidgets(panel->box);
288 showData(panel);
291 static void storeData(_Panel *panel)
293 int i;
294 for (i = 0; i < 4; i++)
296 char *str;
298 str = WMGetTextFieldText(panel->autoDelayT[i]);
299 SetStringForKey(str, auto_delay[i].key);
300 wfree(str);
302 for (i = 0; i < 3; i++)
304 SetBoolForKey(!WMGetButtonSelected(panel->docksB[i]), dock_config[i].disable_key);
308 static void showData(_Panel *panel)
310 char *value;
311 int i;
312 for (i = 0; i < 4; i++)
314 value = GetStringForKey(auto_delay[i].key);
315 WMSetTextFieldText(panel->autoDelayT[i], value);
316 adjustButtonSelectionBasedOnValue(panel, i, value);
318 for (i = 0; i < 3; i++)
320 WMSetButtonSelected(panel->docksB[i], !GetBoolForKey(dock_config[i].disable_key));
324 Panel *InitDocks(WMWidget *parent)
326 _Panel *panel;
328 panel = wmalloc(sizeof(_Panel));
329 memset(panel, 0, sizeof(_Panel));
331 panel->sectionName = _("Dock Preferences");
333 panel->description = _("Dock and clip features.\n"
334 "Enable/disable the Dock and Clip, and tune some delays.");
336 panel->parent = parent;
338 panel->callbacks.createWidgets = createPanel;
339 panel->callbacks.updateDomain = storeData;
341 AddSection(panel, ICON_FILE);
343 return panel;