2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (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.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include <sys/types.h>
26
#include "applet-struct.h"
27
#include "applet-item.h"
28
#include "applet-draw.h"
31
static void cd_satus_notifier_compute_grid (void)
33
if (myData.pItems == NULL)
36
// on compte les items actifs.
38
CDStatusNotifierItem *pItem;
40
for (it = myData.pItems; it != NULL; it = it->next)
43
if (_item_is_visible (pItem))
49
CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
50
cd_debug ("=== icon: %dx%d", iWidth, iHeight);
52
// on calcule la meilleure grille.
53
int iNbLines, iNbItemsByLine;
54
int iSize, iSizeMax = 0;
55
for (iNbLines = 1; iNbLines <= iNbItems; iNbLines ++)
57
iNbItemsByLine = ceil ((float)iNbItems / iNbLines);
58
iSize = MIN (iWidth / iNbItemsByLine, iHeight / iNbLines);
62
myData.iNbLines = iNbLines;
63
myData.iNbColumns = iNbItemsByLine;
64
myData.iItemSize = iSize;
67
//g_print ("=== satus_notifier : %dx%d\n", myData.iNbLines, myData.iNbColumns);
70
static void cd_satus_notifier_compute_icon_size (void)
72
// count the active items.
74
CDStatusNotifierItem *pItem;
76
for (it = myData.pItems; it != NULL; it = it->next)
79
if (_item_is_visible (pItem))
83
int w0, h0; // default icon size, as set in the config.
84
w0 = myData.iDefaultWidth;
85
h0 = myData.iDefaultHeight;
86
// current available icon size.
88
CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
89
cd_debug ("=== icon: %dx%d", iWidth, iHeight);
90
if (!myContainer->bIsHorizontal)
97
// compute the required width and the grid.
99
if (myContainer->bIsHorizontal)
101
myData.iNbLines = myConfig.iNbLines;
102
myData.iItemSize = MAX (1, iHeight / myConfig.iNbLines);
103
myData.iNbColumns = ceil ((float)iNbItems / myConfig.iNbLines); // nb items by line.
104
w = MAX (w0, myData.iItemSize * myData.iNbColumns + myIconsParam.iIconGap * (myData.iNbColumns - 1));
108
myData.iNbColumns = myConfig.iNbLines;
109
myData.iItemSize = MAX (1, iHeight / myConfig.iNbLines);
110
myData.iNbLines = ceil ((float)iNbItems / myConfig.iNbLines); // nb items by line.
111
w = MAX (h0, myData.iItemSize * myData.iNbLines + myIconsParam.iIconGap * (myData.iNbLines - 1));
113
cd_debug ("=== required width: %d (now: %d)", w, iWidth);
115
// if width has changed, update the icon size.
118
if (myContainer->bIsHorizontal)
119
cairo_dock_resize_applet (myApplet, w, h0);
121
cairo_dock_resize_applet (myApplet, w0, w);
126
static void cd_satus_notifier_draw_compact_icon (void)
129
CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
131
CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN_CAIRO ();
134
if (myConfig.bResizeIcon)
135
iIconGap = myIconsParam.iIconGap;
138
int x_pad = (iWidth - myData.iItemSize * myData.iNbColumns - iIconGap * (myData.iNbColumns - 1)) / 2; // pad to center the drawing.
139
int y_pad = (iHeight - myData.iItemSize * myData.iNbLines) / 2;
140
cd_debug ("pad: %d;%d; grid: %dx%d, icon: %dx%d", x_pad, y_pad, myData.iNbLines, myData.iNbColumns, iWidth, iHeight);
142
// draw each active item, in lines, from left to right.
143
int i = 0, j = 0; // ligne, colonne
144
CDStatusNotifierItem *pItem;
146
for (it = myData.pItems; it != NULL; it = it->next)
149
if (pItem->pSurface != NULL && _item_is_visible (pItem))
151
cd_debug ("=== draw %s (%d)", pItem->cId, pItem->iPosition);
152
cairo_set_source_surface (myDrawContext,
154
x_pad + j * (myData.iItemSize + iIconGap),
155
y_pad + i * myData.iItemSize);
156
cairo_paint (myDrawContext);
159
if (j == myData.iNbColumns) // ligne suivante.
167
CD_APPLET_FINISH_DRAWING_MY_ICON_CAIRO;
171
void cd_satus_notifier_reload_compact_mode (void)
173
cd_debug ("=== %s ()", __func__);
174
// re-compute the grid.
175
int iPrevSize = myData.iItemSize;
176
if (myConfig.bResizeIcon)
177
cd_satus_notifier_compute_icon_size ();
179
cd_satus_notifier_compute_grid ();
181
// load surfaces, or reload them if their size has changed.
182
cd_debug ("=== item size: %d -> %d, icon size: %dx%d", iPrevSize, myData.iItemSize, myIcon->image.iWidth, myIcon->image.iHeight);
183
CDStatusNotifierItem *pItem;
185
for (it = myData.pItems; it != NULL; it = it->next)
188
if (_item_is_visible (pItem))
190
if (iPrevSize != myData.iItemSize || pItem->pSurface == NULL)
192
gchar *cIconPath = cd_satus_notifier_search_item_icon_s_path (pItem, myData.iItemSize);
193
if (cIconPath != NULL)
195
if (pItem->pSurface != NULL)
196
cairo_surface_destroy (pItem->pSurface);
197
pItem->pSurface = cairo_dock_create_surface_from_icon (cIconPath, myData.iItemSize, myData.iItemSize);
205
cd_satus_notifier_draw_compact_icon ();
209
CDStatusNotifierItem *cd_satus_notifier_find_item_from_coord (void)
211
if (myData.pItems == NULL)
214
//g_print ("=== %s (%d;%d)\n", __func__, iMouseX, iMouseY);
217
CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
219
// get coordinates on the grid.
220
double fSizeX, fSizeY;
221
cairo_dock_get_current_icon_size (myIcon, myContainer, &fSizeX, &fSizeY);
223
int iMouseX, iMouseY; // coordinates on the icon (taking into account the zoom).
224
iMouseX = myContainer->iMouseX - myIcon->fDrawX;
225
iMouseY = myContainer->iMouseY - myIcon->fDrawY;
227
if (myContainer->bIsHorizontal)
229
iMouseX = iMouseX / fSizeX * iWidth; // transform to the grid.
230
iMouseY = iMouseY / fSizeY * iHeight;
235
iMouseX = iMouseY / fSizeX * iWidth; // transform to the grid.
236
iMouseY = tmp / fSizeY * iHeight;
239
// get index on the grid.
241
if (myConfig.bResizeIcon)
242
iIconGap = myIconsParam.iIconGap;
245
int x_pad = (iWidth - myData.iItemSize * myData.iNbColumns - iIconGap * (myData.iNbColumns - 1)) / 2;
246
int y_pad = (iHeight - myData.iItemSize * myData.iNbLines) / 2;
248
int line, col; // line, column
249
col = (iMouseX - x_pad) / (myData.iItemSize + iIconGap);
250
line = (iMouseY - y_pad) / myData.iItemSize;
252
// get item from index.
253
CDStatusNotifierItem *pItem, *pFoundItem = NULL;
255
int i=0, j=0; // line, column
256
for (it = myData.pItems; it != NULL; it = it->next)
259
if (pItem->pSurface != NULL && _item_is_visible (pItem))
261
if (i == line && j == col)
267
if (j == myData.iNbColumns) // next line.
279
void cd_satus_notifier_update_item_image (CDStatusNotifierItem *pItem)
281
if (myConfig.bCompactMode)
283
gchar *cIconPath = cd_satus_notifier_search_item_icon_s_path (pItem, myData.iItemSize);
284
if (cIconPath != NULL)
286
if (pItem->pSurface != NULL)
287
cairo_surface_destroy (pItem->pSurface);
288
pItem->pSurface = cairo_dock_create_surface_from_icon (cIconPath, myData.iItemSize, myData.iItemSize);
291
cd_satus_notifier_draw_compact_icon ();
295
Icon *pIcon = cd_satus_notifier_get_icon_from_item (pItem);
296
if (pIcon != NULL && pIcon->image.pSurface != NULL)
298
cairo_t *pIconContext = cairo_create (pIcon->image.pSurface);
299
cairo_dock_set_image_on_icon (pIconContext,
300
pItem->iStatus == CD_STATUS_NEEDS_ATTENTION ? pItem->cAttentionIconName : pItem->cIconName,
301
pIcon, CD_APPLET_MY_ICONS_LIST_CONTAINER);
302
cairo_destroy (pIconContext);