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.
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] = {
54 typedef struct _Panel
{
61 CallbackRec callbacks
;
63 Bool have_legacy_apercu
;
75 WMButton
*posB
[wlengthof_nocheck(icon_position_dbvalue
)];
78 WMButton
*animB
[wlengthof_nocheck(icon_animation
)];
98 * Minimum size for a Mini-Preview:
99 * This value is actually twice the size of the minimum icon size choosable.
100 * We set the slider min to taht number minus one, because when set to this
101 * value WPrefs will consider that the user wants the feature turned off.
103 static const int minipreview_minimum_size
= 2 * 24 - 1;
105 static const int minipreview_maximum_size
= 512; /* Arbitrary limit for the slider */
107 #define ICON_FILE "iconprefs"
109 static void showIconLayout(WMWidget
* widget
, void *data
)
111 _Panel
*panel
= (_Panel
*) data
;
115 for (i
= 0; i
< wlengthof(panel
->posB
); i
++) {
116 if (panel
->posB
[i
] == widget
) {
122 if (panel
->iconPos
& 1) {
129 WMResizeWidget(panel
->posV
, w
, h
);
131 switch (panel
->iconPos
& ~1) {
133 WMMoveWidget(panel
->posV
, 2, 2);
136 WMMoveWidget(panel
->posV
, panel
->icon_position
.width
- 2 - w
, 2);
139 WMMoveWidget(panel
->posV
, 2, panel
->icon_position
.height
- 2 - h
);
142 WMMoveWidget(panel
->posV
, panel
->icon_position
.width
- 2 - w
, panel
->icon_position
.height
- 2 - h
);
147 static void minipreview_slider_changed(WMWidget
*w
, void *data
)
149 _Panel
*panel
= (_Panel
*) data
;
153 /* Parameter is not used, but tell the compiler that it is ok */
156 value
= WMGetSliderValue(panel
->minipreview
.slider
);
158 /* Round the value to a multiple of 8 because it makes the displayed value look better */
161 if (value
<= minipreview_minimum_size
)
162 sprintf(buffer
, _("OFF"));
164 sprintf(buffer
, "%i", value
);
166 WMSetLabelText(panel
->minipreview
.label
, buffer
);
169 static void showData(_Panel
* panel
)
175 WMSetButtonSelected(panel
->arrB
, GetBoolForKey("AutoArrangeIcons"));
176 WMSetButtonSelected(panel
->omnB
, GetBoolForKey("StickyIcons"));
177 WMSetButtonSelected(panel
->sclB
, GetBoolForKey("SingleClickLaunch"));
179 str
= GetStringForKey("IconPosition");
181 for (i
= 0; i
< wlengthof(icon_position_dbvalue
); i
++)
182 if (strcmp(str
, icon_position_dbvalue
[i
]) == 0) {
184 goto found_position_value
;
186 wwarning(_("bad value \"%s\" for option %s, using default \"%s\""),
187 str
, "IconPosition", icon_position_dbvalue
[5]);
190 found_position_value
:
191 WMPerformButtonClick(panel
->posB
[panel
->iconPos
]);
193 i
= GetIntegerForKey("IconSize");
200 WMSetPopUpButtonSelectedItem(panel
->sizeP
, i
);
202 /* Mini-Previews for Icons */
205 * Backward Compatibility:
206 * These settings changed names after 0.95.6, so to avoid breaking user's
207 * config we still support the old names, and silently convert them to the
209 * This hack should be kept for at least 2 years, that means >= 2017.
211 panel
->have_legacy_apercu
= False
;
212 str
= GetStringForKey("MiniwindowPreviewBalloons");
214 /* New names found, use them in priority */
215 b
= GetBoolForKey("MiniwindowPreviewBalloons");
217 i
= GetIntegerForKey("MiniPreviewSize");
218 if (i
<= minipreview_minimum_size
)
219 i
= minipreview_minimum_size
;
221 i
= minipreview_minimum_size
;
224 /* No new names, try the legacy names */
225 b
= GetBoolForKey("MiniwindowApercuBalloons");
227 panel
->have_legacy_apercu
= True
;
228 i
= GetIntegerForKey("ApercuSize");
231 * In the beginning, the option was coded as a multiple of the icon
232 * size; then it was converted to pixel size
235 i
*= GetIntegerForKey("IconSize");
237 if (i
<= minipreview_minimum_size
)
238 i
= minipreview_minimum_size
+ 1; /* +1 to not display as "off" */
240 i
= minipreview_minimum_size
;
243 WMSetSliderValue(panel
->minipreview
.slider
, i
);
244 minipreview_slider_changed(panel
->minipreview
.slider
, panel
);
247 str
= GetStringForKey("IconificationStyle");
249 for (i
= 0; i
< wlengthof(icon_animation
); i
++) {
250 if (strcasecmp(str
, icon_animation
[i
].db_value
) == 0) {
251 WMPerformButtonClick(panel
->animB
[i
]);
252 goto found_animation_value
;
255 wwarning(_("animation style \"%s\" is unknown, resetting to \"%s\""),
256 str
, icon_animation
[0].db_value
);
258 /* If we're here, no valid value have been found so we fall-back to the default */
259 WMPerformButtonClick(panel
->animB
[0]);
260 found_animation_value
:
264 static void createPanel(Panel
* p
)
266 _Panel
*panel
= (_Panel
*) p
;
275 panel
->box
= WMCreateBox(panel
->parent
);
276 WMSetViewExpandsToParent(WMWidgetView(panel
->box
), 2, 2, 2, 2);
278 /***************** Positioning of Icons *****************/
279 panel
->posF
= WMCreateFrame(panel
->box
);
280 WMResizeWidget(panel
->posF
, 268, 155);
281 WMMoveWidget(panel
->posF
, 12, 6);
282 WMSetFrameTitle(panel
->posF
, _("Icon Positioning"));
285 * There is an available area of 240 x 122, starting at x=14 y=20
286 * We have to keep 14 pixels on each side for the buttons,
287 * and an extra pixel for spacing. We also want the final dimension
288 * to be an even number so we can have the 2 buttons per side of
290 * In this area, we want to have a rectangle with the same aspect
291 * ratio as the screen.
293 scr
= WMWidgetScreen(panel
->parent
);
294 swidth
= WidthOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr
)));
295 sheight
= HeightOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr
)));
297 width
= swidth
* (122 - 15 * 2) / sheight
;
298 if (width
<= (240 - 15 * 2)) {
299 height
= 122 - 15 * 2;
301 width
= 240 - 15 * 2;
302 height
= sheight
* (240 - 15 * 2) / swidth
;
305 panel
->icon_position
.width
= width
;
306 panel
->icon_position
.height
= height
;
308 startx
= 14 + (240 - 15 * 2 - width
) / 2;
309 starty
= 20 + (122 - 15 * 2 - height
) / 2;
311 for (i
= 0; i
< wlengthof(icon_position_dbvalue
); i
++) {
314 panel
->posB
[i
] = WMCreateButton(panel
->posF
, WBTOnOff
);
315 WMSetButtonAction(panel
->posB
[i
], showIconLayout
, panel
);
318 WMGroupButtons(panel
->posB
[0], panel
->posB
[i
]);
320 if (i
& 1) { /* 0=Vertical, 1=Horizontal */
327 WMResizeWidget(panel
->posB
[i
], w
, h
);
332 case 0: x
+= 0; y
+= 15; break;
333 case 1: x
+= 15; y
+= 0; break;
334 case 2: x
+= 15 + width
; y
+= 15; break;
335 case 3: x
+= 15 + w
; y
+= 0; break;
336 case 4: x
+= 0; y
+= 15 + h
; break;
337 case 5: x
+= 15; y
+= 15 + height
; break;
338 case 6: x
+= 15 + width
; y
+= 15 + h
; break;
339 case 7: x
+= 15 + w
; y
+= 15 + height
; break;
341 WMMoveWidget(panel
->posB
[i
], x
, y
);
344 color
= WMCreateRGBColor(WMWidgetScreen(panel
->parent
), 0x5100, 0x5100, 0x7100, True
);
345 panel
->posVF
= WMCreateFrame(panel
->posF
);
346 WMResizeWidget(panel
->posVF
, width
, height
);
347 WMMoveWidget(panel
->posVF
, startx
+ 15, starty
+ 15);
348 WMSetFrameRelief(panel
->posVF
, WRSunken
);
349 WMSetWidgetBackgroundColor(panel
->posVF
, color
);
350 WMReleaseColor(color
);
352 panel
->posV
= WMCreateFrame(panel
->posVF
);
353 WMSetFrameRelief(panel
->posV
, WRSimple
);
355 WMMapSubwidgets(panel
->posF
);
357 /***************** Icon Size ****************/
358 panel
->sizeF
= WMCreateFrame(panel
->box
);
359 WMResizeWidget(panel
->sizeF
, 100, 52);
360 WMMoveWidget(panel
->sizeF
, 12, 168);
361 WMSetFrameTitle(panel
->sizeF
, _("Icon Size"));
363 WMSetBalloonTextForView(_("The size of the dock/application icon and miniwindows"),
364 WMWidgetView(panel
->sizeF
));
366 panel
->sizeP
= WMCreatePopUpButton(panel
->sizeF
);
367 WMResizeWidget(panel
->sizeP
, 80, 20);
368 WMMoveWidget(panel
->sizeP
, 10, 19);
369 for (i
= 24; i
<= 96; i
+= 8) {
370 sprintf(buf
, "%ix%i", i
, i
);
371 WMAddPopUpButtonItem(panel
->sizeP
, buf
);
374 WMMapSubwidgets(panel
->sizeF
);
376 /***************** Mini-Previews ****************/
377 panel
->minipreview
.frame
= WMCreateFrame(panel
->box
);
378 WMResizeWidget(panel
->minipreview
.frame
, 156, 52);
379 WMMoveWidget(panel
->minipreview
.frame
, 124, 168);
380 WMSetFrameTitle(panel
->minipreview
.frame
, _("Mini-Previews for Icons"));
382 WMSetBalloonTextForView(_("The Mini-Preview provides a small view of the content of the\n"
383 "window when the mouse is placed over the icon."),
384 WMWidgetView(panel
->minipreview
.frame
));
386 panel
->minipreview
.slider
= WMCreateSlider(panel
->minipreview
.frame
);
387 WMResizeWidget(panel
->minipreview
.slider
, 109, 15);
388 WMMoveWidget(panel
->minipreview
.slider
, 11, 23);
389 WMSetSliderMinValue(panel
->minipreview
.slider
, minipreview_minimum_size
);
390 WMSetSliderMaxValue(panel
->minipreview
.slider
, minipreview_maximum_size
);
391 WMSetSliderAction(panel
->minipreview
.slider
, minipreview_slider_changed
, panel
);
393 panel
->minipreview
.label
= WMCreateLabel(panel
->minipreview
.frame
);
394 WMResizeWidget(panel
->minipreview
.label
, 33, 15);
395 WMMoveWidget(panel
->minipreview
.label
, 120, 23);
396 WMSetLabelText(panel
->minipreview
.label
, _("OFF"));
398 WMMapSubwidgets(panel
->minipreview
.frame
);
400 /***************** Animation ****************/
401 panel
->animF
= WMCreateFrame(panel
->box
);
402 WMResizeWidget(panel
->animF
, 215, 110);
403 WMMoveWidget(panel
->animF
, 292, 6);
404 WMSetFrameTitle(panel
->animF
, _("Iconification Animation"));
406 for (i
= 0; i
< wlengthof(icon_animation
); i
++) {
407 panel
->animB
[i
] = WMCreateRadioButton(panel
->animF
);
408 WMResizeWidget(panel
->animB
[i
], 192, 20);
409 WMMoveWidget(panel
->animB
[i
], 12, 16 + i
* 22);
412 WMGroupButtons(panel
->animB
[0], panel
->animB
[i
]);
414 WMSetButtonText(panel
->animB
[i
], _(icon_animation
[i
].label
));
417 WMMapSubwidgets(panel
->animF
);
419 /***************** Options ****************/
420 panel
->optF
= WMCreateFrame(panel
->box
);
421 WMResizeWidget(panel
->optF
, 215, 90);
422 WMMoveWidget(panel
->optF
, 292, 130);
423 /* WMSetFrameTitle(panel->optF, _("Icon Display")); */
425 panel
->arrB
= WMCreateSwitchButton(panel
->optF
);
426 WMResizeWidget(panel
->arrB
, 198, 26);
427 WMMoveWidget(panel
->arrB
, 12, 8);
428 WMSetButtonText(panel
->arrB
, _("Auto-arrange icons"));
430 WMSetBalloonTextForView(_("Keep icons and miniwindows arranged all the time."), WMWidgetView(panel
->arrB
));
432 panel
->omnB
= WMCreateSwitchButton(panel
->optF
);
433 WMResizeWidget(panel
->omnB
, 198, 26);
434 WMMoveWidget(panel
->omnB
, 12, 34);
435 WMSetButtonText(panel
->omnB
, _("Omnipresent miniwindows"));
437 WMSetBalloonTextForView(_("Make miniwindows be present in all workspaces."), WMWidgetView(panel
->omnB
));
439 panel
->sclB
= WMCreateSwitchButton(panel
->optF
);
440 WMResizeWidget(panel
->sclB
, 198, 26);
441 WMMoveWidget(panel
->sclB
, 12, 60);
442 WMSetButtonText(panel
->sclB
, _("Single click activation"));
444 WMSetBalloonTextForView(_("Launch applications and restore windows with a single click."), WMWidgetView(panel
->sclB
));
446 WMMapSubwidgets(panel
->optF
);
448 WMRealizeWidget(panel
->box
);
449 WMMapSubwidgets(panel
->box
);
454 static void storeData(_Panel
* panel
)
458 SetBoolForKey(WMGetButtonSelected(panel
->arrB
), "AutoArrangeIcons");
459 SetBoolForKey(WMGetButtonSelected(panel
->omnB
), "StickyIcons");
460 SetBoolForKey(WMGetButtonSelected(panel
->sclB
), "SingleClickLaunch");
462 SetIntegerForKey(WMGetPopUpButtonSelectedItem(panel
->sizeP
) * 8 + 24, "IconSize");
464 SetStringForKey(icon_position_dbvalue
[panel
->iconPos
], "IconPosition");
466 i
= WMGetSliderValue(panel
->minipreview
.slider
);
467 if (i
<= minipreview_minimum_size
) {
468 SetBoolForKey(False
, "MiniwindowPreviewBalloons");
470 SetBoolForKey(True
, "MiniwindowPreviewBalloons");
471 if (i
< minipreview_maximum_size
) {
473 * If the value is bigger, it means it was edited by the user manually
474 * so we keep as-is. Otherwise, we round it to a multiple of 8 like it
475 * was done for display
479 SetIntegerForKey(i
, "MiniPreviewSize");
481 if (panel
->have_legacy_apercu
) {
482 RemoveObjectForKey("MiniwindowApercuBalloons");
483 RemoveObjectForKey("ApercuSize");
486 for (i
= 0; i
< wlengthof(icon_animation
); i
++) {
487 if (WMGetButtonSelected(panel
->animB
[i
])) {
488 SetStringForKey(icon_animation
[i
].db_value
, "IconificationStyle");
494 Panel
*InitIcons(WMWidget
*parent
)
498 panel
= wmalloc(sizeof(_Panel
));
500 panel
->sectionName
= _("Icon Preferences");
502 panel
->description
= _("Icon/Miniwindow handling options. Icon positioning\n"
503 "area, sizes of icons, miniaturization animation style.");
505 panel
->parent
= parent
;
507 panel
->callbacks
.createWidgets
= createPanel
;
508 panel
->callbacks
.updateDomain
= storeData
;
510 AddSection(panel
, ICON_FILE
);