wmaker/WPrefs: Remove legacy support for deprecated apercus.
[wmaker-crm.git] / WPrefs.app / Icons.c
blobad4cfc67916ebcbaebf3dc3a809e94f452f79178
1 /* Icons.c- icon preferences
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 1998-2003 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"
25 static const struct {
26 const char *db_value;
27 const char *label;
28 } icon_animation[] = {
29 { "zoom", N_("Shrinking/Zooming") },
30 { "twist", N_("Spinning/Twisting") },
31 { "flip", N_("3D-flipping") },
32 { "none", N_("None") }
36 * The code is using a convenient trick to make the link between the icon
37 * position and its representing number:
38 * bit[0] tell if the icon are arranged horizontally or vertically
39 * bit[2:1] tell the corner to which they are starting from:
40 * bit[2] is for Top or Bottom choice
41 * bit[1] is for Left or Right choice
43 static const char icon_position_dbvalue[][4] = {
44 /* 000: */ "tlv",
45 /* 001: */ "tlh",
46 /* 010: */ "trv",
47 /* 011: */ "trh",
48 /* 100: */ "blv",
49 /* 101: */ "blh",
50 /* 110: */ "brv",
51 /* 111: */ "brh"
54 typedef struct _Panel {
55 WMBox *box;
57 char *sectionName;
59 char *description;
61 CallbackRec callbacks;
63 WMWidget *parent;
65 WMFrame *posF;
66 WMFrame *posVF;
67 WMFrame *posV;
69 struct {
70 int width, height;
71 } icon_position;
73 WMButton *posB[wlengthof_nocheck(icon_position_dbvalue)];
75 WMFrame *animF;
76 WMButton *animB[wlengthof_nocheck(icon_animation)];
78 WMFrame *optF;
79 WMButton *arrB;
80 WMButton *omnB;
81 WMButton *sclB;
83 struct {
84 WMFrame *frame;
85 WMSlider *slider;
86 WMLabel *label;
87 } minipreview;
89 WMFrame *sizeF;
90 WMPopUpButton *sizeP;
92 int iconPos;
93 } _Panel;
96 * Minimum size for a Mini-Preview:
97 * This value is actually twice the size of the minimum icon size choosable.
98 * We set the slider min to taht number minus one, because when set to this
99 * value WPrefs will consider that the user wants the feature turned off.
101 static const int minipreview_minimum_size = 2 * 24 - 1;
103 static const int minipreview_maximum_size = 512; /* Arbitrary limit for the slider */
105 #define ICON_FILE "iconprefs"
107 static void showIconLayout(WMWidget * widget, void *data)
109 _Panel *panel = (_Panel *) data;
110 int w, h;
111 int i;
113 for (i = 0; i < wlengthof(panel->posB); i++) {
114 if (panel->posB[i] == widget) {
115 panel->iconPos = i;
116 break;
120 if (panel->iconPos & 1) {
121 w = 32;
122 h = 8;
123 } else {
124 w = 8;
125 h = 32;
127 WMResizeWidget(panel->posV, w, h);
129 switch (panel->iconPos & ~1) {
130 case 0:
131 WMMoveWidget(panel->posV, 2, 2);
132 break;
133 case 2:
134 WMMoveWidget(panel->posV, panel->icon_position.width - 2 - w, 2);
135 break;
136 case 4:
137 WMMoveWidget(panel->posV, 2, panel->icon_position.height - 2 - h);
138 break;
139 default:
140 WMMoveWidget(panel->posV, panel->icon_position.width - 2 - w, panel->icon_position.height - 2 - h);
141 break;
145 static void minipreview_slider_changed(WMWidget *w, void *data)
147 _Panel *panel = (_Panel *) data;
148 char buffer[64];
149 int value;
151 /* Parameter is not used, but tell the compiler that it is ok */
152 (void) w;
154 value = WMGetSliderValue(panel->minipreview.slider);
156 /* Round the value to a multiple of 8 because it makes the displayed value look better */
157 value &= ~7;
159 if (value <= minipreview_minimum_size)
160 sprintf(buffer, _("OFF"));
161 else
162 sprintf(buffer, "%i", value);
164 WMSetLabelText(panel->minipreview.label, buffer);
167 static void showData(_Panel * panel)
169 int i;
170 char *str;
171 Bool b;
173 WMSetButtonSelected(panel->arrB, GetBoolForKey("AutoArrangeIcons"));
174 WMSetButtonSelected(panel->omnB, GetBoolForKey("StickyIcons"));
175 WMSetButtonSelected(panel->sclB, GetBoolForKey("SingleClickLaunch"));
177 str = GetStringForKey("IconPosition");
178 if (str != NULL) {
179 for (i = 0; i < wlengthof(icon_position_dbvalue); i++)
180 if (strcmp(str, icon_position_dbvalue[i]) == 0) {
181 panel->iconPos = i;
182 goto found_position_value;
184 wwarning(_("bad value \"%s\" for option %s, using default \"%s\""),
185 str, "IconPosition", icon_position_dbvalue[5]);
187 panel->iconPos = 5;
188 found_position_value:
189 WMPerformButtonClick(panel->posB[panel->iconPos]);
191 i = GetIntegerForKey("IconSize");
192 i = (i - 24) / 8;
194 if (i < 0)
195 i = 0;
196 else if (i > 9)
197 i = 9;
198 WMSetPopUpButtonSelectedItem(panel->sizeP, i);
200 /* Mini-Previews for Icons */
202 str = GetStringForKey("MiniwindowPreviewBalloons");
203 if (str != NULL) {
204 /* New names found, use them in priority */
205 b = GetBoolForKey("MiniwindowPreviewBalloons");
206 if (b) {
207 i = GetIntegerForKey("MiniPreviewSize");
208 if (i <= minipreview_minimum_size)
209 i = minipreview_minimum_size;
210 } else {
211 i = minipreview_minimum_size;
214 WMSetSliderValue(panel->minipreview.slider, i);
215 minipreview_slider_changed(panel->minipreview.slider, panel);
217 /* Animation */
218 str = GetStringForKey("IconificationStyle");
219 if (str != NULL) {
220 for (i = 0; i < wlengthof(icon_animation); i++) {
221 if (strcasecmp(str, icon_animation[i].db_value) == 0) {
222 WMPerformButtonClick(panel->animB[i]);
223 goto found_animation_value;
226 wwarning(_("animation style \"%s\" is unknown, resetting to \"%s\""),
227 str, icon_animation[0].db_value);
229 /* If we're here, no valid value have been found so we fall-back to the default */
230 WMPerformButtonClick(panel->animB[0]);
231 found_animation_value:
235 static void createPanel(Panel * p)
237 _Panel *panel = (_Panel *) p;
238 WMScreen *scr;
239 WMColor *color;
240 int i;
241 char buf[16];
242 int swidth, sheight;
243 int width, height;
244 int startx, starty;
246 panel->box = WMCreateBox(panel->parent);
247 WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
249 /***************** Positioning of Icons *****************/
250 panel->posF = WMCreateFrame(panel->box);
251 WMResizeWidget(panel->posF, 268, 155);
252 WMMoveWidget(panel->posF, 12, 6);
253 WMSetFrameTitle(panel->posF, _("Icon Positioning"));
256 * There is an available area of 240 x 122, starting at x=14 y=20
257 * We have to keep 14 pixels on each side for the buttons,
258 * and an extra pixel for spacing. We also want the final dimension
259 * to be an even number so we can have the 2 buttons per side of
260 * the same size.
261 * In this area, we want to have a rectangle with the same aspect
262 * ratio as the screen.
264 scr = WMWidgetScreen(panel->parent);
265 swidth = WidthOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr)));
266 sheight = HeightOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr)));
268 width = swidth * (122 - 15 * 2) / sheight;
269 if (width <= (240 - 15 * 2)) {
270 height = 122 - 15 * 2;
271 } else {
272 width = 240 - 15 * 2;
273 height = sheight * (240 - 15 * 2) / swidth;
276 panel->icon_position.width = width;
277 panel->icon_position.height = height;
279 startx = 14 + (240 - 15 * 2 - width) / 2;
280 starty = 20 + (122 - 15 * 2 - height) / 2;
282 for (i = 0; i < wlengthof(icon_position_dbvalue); i++) {
283 int x, y, w, h;
285 panel->posB[i] = WMCreateButton(panel->posF, WBTOnOff);
286 WMSetButtonAction(panel->posB[i], showIconLayout, panel);
288 if (i > 0)
289 WMGroupButtons(panel->posB[0], panel->posB[i]);
291 if (i & 1) { /* 0=Vertical, 1=Horizontal */
292 w = width / 2;
293 h = 14;
294 } else {
295 w = 14;
296 h = height / 2;
298 WMResizeWidget(panel->posB[i], w, h);
300 x = startx;
301 y = starty;
302 switch (i) {
303 case 0: x += 0; y += 15; break;
304 case 1: x += 15; y += 0; break;
305 case 2: x += 15 + width; y += 15; break;
306 case 3: x += 15 + w; y += 0; break;
307 case 4: x += 0; y += 15 + h; break;
308 case 5: x += 15; y += 15 + height; break;
309 case 6: x += 15 + width; y += 15 + h; break;
310 case 7: x += 15 + w; y += 15 + height; break;
312 WMMoveWidget(panel->posB[i], x, y);
315 color = WMCreateRGBColor(WMWidgetScreen(panel->parent), 0x5100, 0x5100, 0x7100, True);
316 panel->posVF = WMCreateFrame(panel->posF);
317 WMResizeWidget(panel->posVF, width, height);
318 WMMoveWidget(panel->posVF, startx + 15, starty + 15);
319 WMSetFrameRelief(panel->posVF, WRSunken);
320 WMSetWidgetBackgroundColor(panel->posVF, color);
321 WMReleaseColor(color);
323 panel->posV = WMCreateFrame(panel->posVF);
324 WMSetFrameRelief(panel->posV, WRSimple);
326 WMMapSubwidgets(panel->posF);
328 /***************** Icon Size ****************/
329 panel->sizeF = WMCreateFrame(panel->box);
330 WMResizeWidget(panel->sizeF, 100, 52);
331 WMMoveWidget(panel->sizeF, 12, 168);
332 WMSetFrameTitle(panel->sizeF, _("Icon Size"));
334 WMSetBalloonTextForView(_("The size of the dock/application icon and miniwindows"),
335 WMWidgetView(panel->sizeF));
337 panel->sizeP = WMCreatePopUpButton(panel->sizeF);
338 WMResizeWidget(panel->sizeP, 80, 20);
339 WMMoveWidget(panel->sizeP, 10, 19);
340 for (i = 24; i <= 96; i += 8) {
341 sprintf(buf, "%ix%i", i, i);
342 WMAddPopUpButtonItem(panel->sizeP, buf);
345 WMMapSubwidgets(panel->sizeF);
347 /***************** Mini-Previews ****************/
348 panel->minipreview.frame = WMCreateFrame(panel->box);
349 WMResizeWidget(panel->minipreview.frame, 156, 52);
350 WMMoveWidget(panel->minipreview.frame, 124, 168);
351 WMSetFrameTitle(panel->minipreview.frame, _("Mini-Previews for Icons"));
353 WMSetBalloonTextForView(_("The Mini-Preview provides a small view of the content of the\n"
354 "window when the mouse is placed over the icon."),
355 WMWidgetView(panel->minipreview.frame));
357 panel->minipreview.slider = WMCreateSlider(panel->minipreview.frame);
358 WMResizeWidget(panel->minipreview.slider, 109, 15);
359 WMMoveWidget(panel->minipreview.slider, 11, 23);
360 WMSetSliderMinValue(panel->minipreview.slider, minipreview_minimum_size);
361 WMSetSliderMaxValue(panel->minipreview.slider, minipreview_maximum_size);
362 WMSetSliderAction(panel->minipreview.slider, minipreview_slider_changed, panel);
364 panel->minipreview.label = WMCreateLabel(panel->minipreview.frame);
365 WMResizeWidget(panel->minipreview.label, 33, 15);
366 WMMoveWidget(panel->minipreview.label, 120, 23);
367 WMSetLabelText(panel->minipreview.label, _("OFF"));
369 WMMapSubwidgets(panel->minipreview.frame);
371 /***************** Animation ****************/
372 panel->animF = WMCreateFrame(panel->box);
373 WMResizeWidget(panel->animF, 215, 110);
374 WMMoveWidget(panel->animF, 292, 6);
375 WMSetFrameTitle(panel->animF, _("Iconification Animation"));
377 for (i = 0; i < wlengthof(icon_animation); i++) {
378 panel->animB[i] = WMCreateRadioButton(panel->animF);
379 WMResizeWidget(panel->animB[i], 192, 20);
380 WMMoveWidget(panel->animB[i], 12, 16 + i * 22);
382 if (i > 0)
383 WMGroupButtons(panel->animB[0], panel->animB[i]);
385 WMSetButtonText(panel->animB[i], _(icon_animation[i].label));
388 WMMapSubwidgets(panel->animF);
390 /***************** Options ****************/
391 panel->optF = WMCreateFrame(panel->box);
392 WMResizeWidget(panel->optF, 215, 90);
393 WMMoveWidget(panel->optF, 292, 130);
394 /* WMSetFrameTitle(panel->optF, _("Icon Display")); */
396 panel->arrB = WMCreateSwitchButton(panel->optF);
397 WMResizeWidget(panel->arrB, 198, 26);
398 WMMoveWidget(panel->arrB, 12, 8);
399 WMSetButtonText(panel->arrB, _("Auto-arrange icons"));
401 WMSetBalloonTextForView(_("Keep icons and miniwindows arranged all the time."), WMWidgetView(panel->arrB));
403 panel->omnB = WMCreateSwitchButton(panel->optF);
404 WMResizeWidget(panel->omnB, 198, 26);
405 WMMoveWidget(panel->omnB, 12, 34);
406 WMSetButtonText(panel->omnB, _("Omnipresent miniwindows"));
408 WMSetBalloonTextForView(_("Make miniwindows be present in all workspaces."), WMWidgetView(panel->omnB));
410 panel->sclB = WMCreateSwitchButton(panel->optF);
411 WMResizeWidget(panel->sclB, 198, 26);
412 WMMoveWidget(panel->sclB, 12, 60);
413 WMSetButtonText(panel->sclB, _("Single click activation"));
415 WMSetBalloonTextForView(_("Launch applications and restore windows with a single click."), WMWidgetView(panel->sclB));
417 WMMapSubwidgets(panel->optF);
419 WMRealizeWidget(panel->box);
420 WMMapSubwidgets(panel->box);
422 showData(panel);
425 static void storeData(_Panel * panel)
427 int i;
429 SetBoolForKey(WMGetButtonSelected(panel->arrB), "AutoArrangeIcons");
430 SetBoolForKey(WMGetButtonSelected(panel->omnB), "StickyIcons");
431 SetBoolForKey(WMGetButtonSelected(panel->sclB), "SingleClickLaunch");
433 SetIntegerForKey(WMGetPopUpButtonSelectedItem(panel->sizeP) * 8 + 24, "IconSize");
435 SetStringForKey(icon_position_dbvalue[panel->iconPos], "IconPosition");
437 i = WMGetSliderValue(panel->minipreview.slider);
438 if (i <= minipreview_minimum_size) {
439 SetBoolForKey(False, "MiniwindowPreviewBalloons");
440 } else {
441 SetBoolForKey(True, "MiniwindowPreviewBalloons");
442 if (i < minipreview_maximum_size) {
444 * If the value is bigger, it means it was edited by the user manually
445 * so we keep as-is. Otherwise, we round it to a multiple of 8 like it
446 * was done for display
448 i &= ~7;
450 SetIntegerForKey(i, "MiniPreviewSize");
453 for (i = 0; i < wlengthof(icon_animation); i++) {
454 if (WMGetButtonSelected(panel->animB[i])) {
455 SetStringForKey(icon_animation[i].db_value, "IconificationStyle");
456 break;
461 Panel *InitIcons(WMWidget *parent)
463 _Panel *panel;
465 panel = wmalloc(sizeof(_Panel));
467 panel->sectionName = _("Icon Preferences");
469 panel->description = _("Icon/Miniwindow handling options. Icon positioning\n"
470 "area, sizes of icons, miniaturization animation style.");
472 panel->parent = parent;
474 panel->callbacks.createWidgets = createPanel;
475 panel->callbacks.updateDomain = storeData;
477 AddSection(panel, ICON_FILE);
479 return panel;