mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 04:20:27 +01:00
The current findBestIcon function usually selects an icon image
that almost completely fills up the (default) 64x64 pixels of an
icon. As Dan noted in the function, the icon images should use only
75% of the available space, which would result in room for the
miniwindow title and better overall aesthetics.
This feature option provides for enabling such an automatic "icon
shrinking" functionality.
Note: This commit only introduces the new option, not the actual
image shrinking.
486 lines
14 KiB
C
486 lines
14 KiB
C
/* Icons.c- icon preferences
|
|
*
|
|
* WPrefs - Window Maker Preferences Program
|
|
*
|
|
* Copyright (c) 1998-2003 Alfredo K. Kojima
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "WPrefs.h"
|
|
|
|
|
|
static const struct {
|
|
const char *db_value;
|
|
const char *label;
|
|
} icon_animation[] = {
|
|
{ "zoom", N_("Shrinking/Zooming") },
|
|
{ "twist", N_("Spinning/Twisting") },
|
|
{ "flip", N_("3D-flipping") },
|
|
{ "none", N_("None") }
|
|
};
|
|
|
|
/*
|
|
* The code is using a convenient trick to make the link between the icon
|
|
* position and its representing number:
|
|
* bit[0] tell if the icon are arranged horizontally or vertically
|
|
* bit[2:1] tell the corner to which they are starting from:
|
|
* bit[2] is for Top or Bottom choice
|
|
* bit[1] is for Left or Right choice
|
|
*/
|
|
static const char icon_position_dbvalue[][4] = {
|
|
/* 000: */ "tlv",
|
|
/* 001: */ "tlh",
|
|
/* 010: */ "trv",
|
|
/* 011: */ "trh",
|
|
/* 100: */ "blv",
|
|
/* 101: */ "blh",
|
|
/* 110: */ "brv",
|
|
/* 111: */ "brh"
|
|
};
|
|
|
|
typedef struct _Panel {
|
|
WMBox *box;
|
|
|
|
char *sectionName;
|
|
|
|
char *description;
|
|
|
|
CallbackRec callbacks;
|
|
|
|
WMWidget *parent;
|
|
|
|
WMFrame *posF;
|
|
WMFrame *posVF;
|
|
WMFrame *posV;
|
|
|
|
struct {
|
|
int width, height;
|
|
} icon_position;
|
|
|
|
WMButton *posB[wlengthof_nocheck(icon_position_dbvalue)];
|
|
|
|
WMFrame *animF;
|
|
WMPopUpButton *animP;
|
|
|
|
WMFrame *optF;
|
|
WMButton *arrB;
|
|
WMButton *omnB;
|
|
WMButton *sclB;
|
|
WMButton *marginB;
|
|
|
|
struct {
|
|
WMFrame *frame;
|
|
WMSlider *slider;
|
|
WMLabel *label;
|
|
} minipreview;
|
|
|
|
WMFrame *sizeF;
|
|
WMPopUpButton *sizeP;
|
|
|
|
int iconPos;
|
|
} _Panel;
|
|
|
|
/*
|
|
* Minimum size for a Mini-Preview:
|
|
* This value is actually twice the size of the minimum icon size choosable.
|
|
* We set the slider min to taht number minus one, because when set to this
|
|
* value WPrefs will consider that the user wants the feature turned off.
|
|
*/
|
|
static const int minipreview_minimum_size = 2 * 24 - 1;
|
|
|
|
static const int minipreview_maximum_size = 512; /* Arbitrary limit for the slider */
|
|
|
|
#define ICON_FILE "iconprefs"
|
|
|
|
static void showIconLayout(WMWidget * widget, void *data)
|
|
{
|
|
_Panel *panel = (_Panel *) data;
|
|
int w, h;
|
|
int i;
|
|
|
|
for (i = 0; i < wlengthof(panel->posB); i++) {
|
|
if (panel->posB[i] == widget) {
|
|
panel->iconPos = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (panel->iconPos & 1) {
|
|
w = 32;
|
|
h = 8;
|
|
} else {
|
|
w = 8;
|
|
h = 32;
|
|
}
|
|
WMResizeWidget(panel->posV, w, h);
|
|
|
|
switch (panel->iconPos & ~1) {
|
|
case 0:
|
|
WMMoveWidget(panel->posV, 2, 2);
|
|
break;
|
|
case 2:
|
|
WMMoveWidget(panel->posV, panel->icon_position.width - 2 - w, 2);
|
|
break;
|
|
case 4:
|
|
WMMoveWidget(panel->posV, 2, panel->icon_position.height - 2 - h);
|
|
break;
|
|
default:
|
|
WMMoveWidget(panel->posV, panel->icon_position.width - 2 - w, panel->icon_position.height - 2 - h);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void minipreview_slider_changed(WMWidget *w, void *data)
|
|
{
|
|
_Panel *panel = (_Panel *) data;
|
|
char buffer[64];
|
|
int value;
|
|
|
|
/* Parameter is not used, but tell the compiler that it is ok */
|
|
(void) w;
|
|
|
|
value = WMGetSliderValue(panel->minipreview.slider);
|
|
|
|
/* Round the value to a multiple of 8 because it makes the displayed value look better */
|
|
value &= ~7;
|
|
|
|
if (value <= minipreview_minimum_size)
|
|
sprintf(buffer, _("OFF"));
|
|
else
|
|
sprintf(buffer, "%i", value);
|
|
|
|
WMSetLabelText(panel->minipreview.label, buffer);
|
|
}
|
|
|
|
static void showData(_Panel * panel)
|
|
{
|
|
int i;
|
|
char *str;
|
|
Bool b;
|
|
|
|
WMSetButtonSelected(panel->arrB, GetBoolForKey("AutoArrangeIcons"));
|
|
WMSetButtonSelected(panel->omnB, GetBoolForKey("StickyIcons"));
|
|
WMSetButtonSelected(panel->sclB, GetBoolForKey("SingleClickLaunch"));
|
|
WMSetButtonSelected(panel->marginB, GetBoolForKey("EnforceIconMargin"));
|
|
|
|
str = GetStringForKey("IconPosition");
|
|
if (str != NULL) {
|
|
for (i = 0; i < wlengthof(icon_position_dbvalue); i++)
|
|
if (strcmp(str, icon_position_dbvalue[i]) == 0) {
|
|
panel->iconPos = i;
|
|
goto found_position_value;
|
|
}
|
|
wwarning(_("bad value \"%s\" for option %s, using default \"%s\""),
|
|
str, "IconPosition", icon_position_dbvalue[5]);
|
|
}
|
|
panel->iconPos = 5;
|
|
found_position_value:
|
|
WMPerformButtonClick(panel->posB[panel->iconPos]);
|
|
|
|
i = GetIntegerForKey("IconSize");
|
|
i = (i - 24) / 8;
|
|
|
|
if (i < 0)
|
|
i = 0;
|
|
else if (i > 9)
|
|
i = 9;
|
|
WMSetPopUpButtonSelectedItem(panel->sizeP, i);
|
|
|
|
/* Mini-Previews for Icons */
|
|
|
|
str = GetStringForKey("MiniwindowPreviewBalloons");
|
|
if (str != NULL) {
|
|
/* New names found, use them in priority */
|
|
b = GetBoolForKey("MiniwindowPreviewBalloons");
|
|
if (b) {
|
|
i = GetIntegerForKey("MiniPreviewSize");
|
|
if (i <= minipreview_minimum_size)
|
|
i = minipreview_minimum_size;
|
|
} else {
|
|
i = minipreview_minimum_size;
|
|
}
|
|
}
|
|
WMSetSliderValue(panel->minipreview.slider, i);
|
|
minipreview_slider_changed(panel->minipreview.slider, panel);
|
|
|
|
/* Animation */
|
|
str = GetStringForKey("IconificationStyle");
|
|
if (str != NULL) {
|
|
for (i = 0; i < wlengthof(icon_animation); i++) {
|
|
if (strcasecmp(str, icon_animation[i].db_value) == 0) {
|
|
WMSetPopUpButtonSelectedItem(panel->animP, i);
|
|
goto found_animation_value;
|
|
}
|
|
}
|
|
wwarning(_("animation style \"%s\" is unknown, resetting to \"%s\""),
|
|
str, icon_animation[0].db_value);
|
|
}
|
|
/* If we're here, no valid value have been found so we fall-back to the default */
|
|
WMSetPopUpButtonSelectedItem(panel->animP, 0);
|
|
found_animation_value:
|
|
;
|
|
}
|
|
|
|
static void createPanel(Panel * p)
|
|
{
|
|
_Panel *panel = (_Panel *) p;
|
|
WMScreen *scr;
|
|
WMColor *color;
|
|
int i;
|
|
char buf[16];
|
|
int swidth, sheight;
|
|
int width, height;
|
|
int startx, starty;
|
|
|
|
panel->box = WMCreateBox(panel->parent);
|
|
WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
|
|
|
|
/***************** Positioning of Icons *****************/
|
|
panel->posF = WMCreateFrame(panel->box);
|
|
WMResizeWidget(panel->posF, 268, 155);
|
|
WMMoveWidget(panel->posF, 12, 6);
|
|
WMSetFrameTitle(panel->posF, _("Icon Positioning"));
|
|
|
|
/*
|
|
* There is an available area of 240 x 122, starting at x=14 y=20
|
|
* We have to keep 14 pixels on each side for the buttons,
|
|
* and an extra pixel for spacing. We also want the final dimension
|
|
* to be an even number so we can have the 2 buttons per side of
|
|
* the same size.
|
|
* In this area, we want to have a rectangle with the same aspect
|
|
* ratio as the screen.
|
|
*/
|
|
scr = WMWidgetScreen(panel->parent);
|
|
swidth = WidthOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr)));
|
|
sheight = HeightOfScreen(DefaultScreenOfDisplay(WMScreenDisplay(scr)));
|
|
|
|
width = swidth * (122 - 15 * 2) / sheight;
|
|
if (width <= (240 - 15 * 2)) {
|
|
height = 122 - 15 * 2;
|
|
} else {
|
|
width = 240 - 15 * 2;
|
|
height = sheight * (240 - 15 * 2) / swidth;
|
|
}
|
|
|
|
panel->icon_position.width = width;
|
|
panel->icon_position.height = height;
|
|
|
|
startx = 14 + (240 - 15 * 2 - width) / 2;
|
|
starty = 20 + (122 - 15 * 2 - height) / 2;
|
|
|
|
for (i = 0; i < wlengthof(icon_position_dbvalue); i++) {
|
|
int x, y, w, h;
|
|
|
|
panel->posB[i] = WMCreateButton(panel->posF, WBTOnOff);
|
|
WMSetButtonAction(panel->posB[i], showIconLayout, panel);
|
|
|
|
if (i > 0)
|
|
WMGroupButtons(panel->posB[0], panel->posB[i]);
|
|
|
|
if (i & 1) { /* 0=Vertical, 1=Horizontal */
|
|
w = width / 2;
|
|
h = 14;
|
|
} else {
|
|
w = 14;
|
|
h = height / 2;
|
|
}
|
|
WMResizeWidget(panel->posB[i], w, h);
|
|
|
|
x = startx;
|
|
y = starty;
|
|
switch (i) {
|
|
case 0: x += 0; y += 15; break;
|
|
case 1: x += 15; y += 0; break;
|
|
case 2: x += 15 + width; y += 15; break;
|
|
case 3: x += 15 + w; y += 0; break;
|
|
case 4: x += 0; y += 15 + h; break;
|
|
case 5: x += 15; y += 15 + height; break;
|
|
case 6: x += 15 + width; y += 15 + h; break;
|
|
case 7: x += 15 + w; y += 15 + height; break;
|
|
}
|
|
WMMoveWidget(panel->posB[i], x, y);
|
|
}
|
|
|
|
color = WMCreateRGBColor(WMWidgetScreen(panel->parent), 0x5100, 0x5100, 0x7100, True);
|
|
panel->posVF = WMCreateFrame(panel->posF);
|
|
WMResizeWidget(panel->posVF, width, height);
|
|
WMMoveWidget(panel->posVF, startx + 15, starty + 15);
|
|
WMSetFrameRelief(panel->posVF, WRSunken);
|
|
WMSetWidgetBackgroundColor(panel->posVF, color);
|
|
WMReleaseColor(color);
|
|
|
|
panel->posV = WMCreateFrame(panel->posVF);
|
|
WMSetFrameRelief(panel->posV, WRSimple);
|
|
|
|
WMMapSubwidgets(panel->posF);
|
|
|
|
/***************** Icon Size ****************/
|
|
panel->sizeF = WMCreateFrame(panel->box);
|
|
WMResizeWidget(panel->sizeF, 100, 52);
|
|
WMMoveWidget(panel->sizeF, 12, 168);
|
|
WMSetFrameTitle(panel->sizeF, _("Icon Size"));
|
|
|
|
WMSetBalloonTextForView(_("The size of the dock/application icon and miniwindows"),
|
|
WMWidgetView(panel->sizeF));
|
|
|
|
panel->sizeP = WMCreatePopUpButton(panel->sizeF);
|
|
WMResizeWidget(panel->sizeP, 80, 20);
|
|
WMMoveWidget(panel->sizeP, 10, 19);
|
|
for (i = 24; i <= 96; i += 8) {
|
|
sprintf(buf, "%ix%i", i, i);
|
|
WMAddPopUpButtonItem(panel->sizeP, buf);
|
|
}
|
|
|
|
WMMapSubwidgets(panel->sizeF);
|
|
|
|
/***************** Mini-Previews ****************/
|
|
panel->minipreview.frame = WMCreateFrame(panel->box);
|
|
WMResizeWidget(panel->minipreview.frame, 156, 52);
|
|
WMMoveWidget(panel->minipreview.frame, 124, 168);
|
|
WMSetFrameTitle(panel->minipreview.frame, _("Mini-Previews for Icons"));
|
|
|
|
WMSetBalloonTextForView(_("The Mini-Preview provides a small view of the content of the\n"
|
|
"window when the mouse is placed over the icon."),
|
|
WMWidgetView(panel->minipreview.frame));
|
|
|
|
panel->minipreview.slider = WMCreateSlider(panel->minipreview.frame);
|
|
WMResizeWidget(panel->minipreview.slider, 109, 15);
|
|
WMMoveWidget(panel->minipreview.slider, 11, 23);
|
|
WMSetSliderMinValue(panel->minipreview.slider, minipreview_minimum_size);
|
|
WMSetSliderMaxValue(panel->minipreview.slider, minipreview_maximum_size);
|
|
WMSetSliderAction(panel->minipreview.slider, minipreview_slider_changed, panel);
|
|
|
|
panel->minipreview.label = WMCreateLabel(panel->minipreview.frame);
|
|
WMResizeWidget(panel->minipreview.label, 33, 15);
|
|
WMMoveWidget(panel->minipreview.label, 120, 23);
|
|
WMSetLabelText(panel->minipreview.label, _("OFF"));
|
|
|
|
WMMapSubwidgets(panel->minipreview.frame);
|
|
|
|
/***************** Animation ****************/
|
|
panel->animF = WMCreateFrame(panel->box);
|
|
WMResizeWidget(panel->animF, 215, 52);
|
|
WMMoveWidget(panel->animF, 292, 6);
|
|
WMSetFrameTitle(panel->animF, _("Iconification Animation"));
|
|
|
|
panel->animP = WMCreatePopUpButton(panel->animF);
|
|
WMResizeWidget(panel->animP, 195, 20);
|
|
WMMoveWidget(panel->animP, 10, 19);
|
|
for (i = 0; i < wlengthof(icon_animation); i++)
|
|
WMAddPopUpButtonItem(panel->animP, _(icon_animation[i].label));
|
|
|
|
WMMapSubwidgets(panel->animF);
|
|
|
|
/***************** Options ****************/
|
|
panel->optF = WMCreateFrame(panel->box);
|
|
WMResizeWidget(panel->optF, 215, 148);
|
|
WMMoveWidget(panel->optF, 292, 72);
|
|
/* WMSetFrameTitle(panel->optF, _("Icon Display")); */
|
|
starty = 8 + 14; /* the last term centers the checkboxes within the panel; subtract 13 for a new option */
|
|
|
|
panel->arrB = WMCreateSwitchButton(panel->optF);
|
|
WMResizeWidget(panel->arrB, 198, 26);
|
|
WMMoveWidget(panel->arrB, 12, starty);
|
|
starty += 26;
|
|
WMSetButtonText(panel->arrB, _("Auto-arrange icons"));
|
|
|
|
WMSetBalloonTextForView(_("Keep icons and miniwindows arranged all the time."), WMWidgetView(panel->arrB));
|
|
|
|
panel->omnB = WMCreateSwitchButton(panel->optF);
|
|
WMResizeWidget(panel->omnB, 198, 26);
|
|
WMMoveWidget(panel->omnB, 12, starty);
|
|
starty += 26;
|
|
WMSetButtonText(panel->omnB, _("Omnipresent miniwindows"));
|
|
|
|
WMSetBalloonTextForView(_("Make miniwindows be present in all workspaces."), WMWidgetView(panel->omnB));
|
|
|
|
panel->sclB = WMCreateSwitchButton(panel->optF);
|
|
WMResizeWidget(panel->sclB, 198, 26);
|
|
WMMoveWidget(panel->sclB, 12, starty);
|
|
starty += 26;
|
|
WMSetButtonText(panel->sclB, _("Single click activation"));
|
|
|
|
WMSetBalloonTextForView(_("Launch applications and restore windows with a single click."), WMWidgetView(panel->sclB));
|
|
|
|
panel->marginB = WMCreateSwitchButton(panel->optF);
|
|
WMResizeWidget(panel->marginB, 198, 26);
|
|
WMMoveWidget(panel->marginB, 12, starty);
|
|
starty += 26;
|
|
WMSetButtonText(panel->marginB, _("Enforce icon margin"));
|
|
|
|
WMSetBalloonTextForView(_("Make sure that the icon image does not protrude into the icon frame."), WMWidgetView(panel->marginB));
|
|
|
|
WMMapSubwidgets(panel->optF);
|
|
|
|
WMRealizeWidget(panel->box);
|
|
WMMapSubwidgets(panel->box);
|
|
|
|
showData(panel);
|
|
}
|
|
|
|
static void storeData(_Panel * panel)
|
|
{
|
|
int i;
|
|
|
|
SetBoolForKey(WMGetButtonSelected(panel->arrB), "AutoArrangeIcons");
|
|
SetBoolForKey(WMGetButtonSelected(panel->omnB), "StickyIcons");
|
|
SetBoolForKey(WMGetButtonSelected(panel->sclB), "SingleClickLaunch");
|
|
SetBoolForKey(WMGetButtonSelected(panel->marginB), "EnforceIconMargin");
|
|
|
|
SetIntegerForKey(WMGetPopUpButtonSelectedItem(panel->sizeP) * 8 + 24, "IconSize");
|
|
|
|
SetStringForKey(icon_position_dbvalue[panel->iconPos], "IconPosition");
|
|
|
|
i = WMGetSliderValue(panel->minipreview.slider);
|
|
if (i <= minipreview_minimum_size) {
|
|
SetBoolForKey(False, "MiniwindowPreviewBalloons");
|
|
} else {
|
|
SetBoolForKey(True, "MiniwindowPreviewBalloons");
|
|
if (i < minipreview_maximum_size) {
|
|
/*
|
|
* If the value is bigger, it means it was edited by the user manually
|
|
* so we keep as-is. Otherwise, we round it to a multiple of 8 like it
|
|
* was done for display
|
|
*/
|
|
i &= ~7;
|
|
}
|
|
SetIntegerForKey(i, "MiniPreviewSize");
|
|
}
|
|
|
|
SetStringForKey(icon_animation[WMGetPopUpButtonSelectedItem(panel->animP)].db_value, "IconificationStyle");
|
|
}
|
|
|
|
Panel *InitIcons(WMWidget *parent)
|
|
{
|
|
_Panel *panel;
|
|
|
|
panel = wmalloc(sizeof(_Panel));
|
|
|
|
panel->sectionName = _("Icon Preferences");
|
|
|
|
panel->description = _("Icon/Miniwindow handling options. Icon positioning\n"
|
|
"area, sizes of icons, miniaturization animation style.");
|
|
|
|
panel->parent = parent;
|
|
|
|
panel->callbacks.createWidgets = createPanel;
|
|
panel->callbacks.updateDomain = storeData;
|
|
|
|
AddSection(panel, ICON_FILE);
|
|
|
|
return panel;
|
|
}
|