1
// TimeBar.cpp --- Time bar
3
// Copyright (C) 2004, 2005, 2006, 2007 Raymond Penners <raymond@dotsphinx.com>
4
// All rights reserved.
6
// This program is free software: you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation, either version 3 of the License, or
9
// (at your option) any later version.
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// 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/>.
26
#include "PaintHelper.h"
28
const int BORDER_SIZE = 2;
29
const int MARGINX = 4;
30
const int MARGINY = 0;
31
const int MINIMAL_HEIGHT = 16;
33
#define TIME_BAR_CLASS_NAME "WorkraveTimeBar"
34
#define GDK_TO_COLORREF(r, g, b) (((r)>>8) | (((g)>>8) <<8) | (((b)>>8) << 16))
36
HBRUSH TimeBar::bar_colors[ITimeBar::COLOR_ID_SIZEOF];
37
HFONT TimeBar::bar_font = NULL;
39
TimeBar::TimeBar(HWND parent, HINSTANCE hinst, CDeskBand *deskband)
47
secondary_bar_max_value = 0;
48
secondary_bar_value = 100;
49
secondary_bar_color = ITimeBar::COLOR_ID_INACTIVE;
50
bar_color = ITimeBar::COLOR_ID_ACTIVE;
52
hwnd = CreateWindowEx(0, TIME_BAR_CLASS_NAME, "",
53
WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 56, 16, parent, NULL, hinst, (LPVOID)this );
55
paint_helper = new PaintHelper(hwnd);
56
compute_size(width, height);
57
SetWindowPos(hwnd, NULL, 0, 0, width, height, SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
66
TimeBar::wnd_proc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
68
TimeBar *pThis = (TimeBar*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
74
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
75
pThis = (TimeBar *)( lpcs->lpCreateParams );
76
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pThis);
77
SetWindowPos(hWnd, NULL, 0, 0, 0, 0,
78
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
83
return pThis->on_paint();
86
SendMessage(pThis->deskband->get_command_window(), WM_USER + 1, 0, NULL);
89
return DefWindowProc(hWnd, uMessage, wParam, lParam);
93
TimeBar::get_size(int &w, int &h)
100
TimeBar::compute_size(int &w, int &h)
102
TRACE_ENTER("TimeBar::compute_size");
103
HDC dc = GetDC(hwnd);
104
SelectObject(dc, (HGDIOBJ) bar_font);
107
time_to_string(-(59+59*60+9*60*60), buf, sizeof(buf));
114
h= DrawText(dc, buf, (int)strlen( buf ), &rect, DT_CALCRECT);
125
w += 2*MARGINX + 2*BORDER_SIZE;
126
h += 2*MARGINY + 2*BORDER_SIZE;
127
if (h < MINIMAL_HEIGHT)
131
TRACE_MSG(w << " " << h);
138
TRACE_ENTER("TimeBar::on_paint");
141
HDC dc = paint_helper->BeginPaint();
143
GetClientRect(hwnd, &rc);
147
int winx = rc.left, winy = rc.top, winw = rc.right-rc.left, winh = rc.bottom-rc.top;
149
SelectObject(dc, (HGDIOBJ) bar_font);
150
r.left = r.top = r.bottom = r.right = 0;
152
TRACE_MSG("1" << winx << " " << winy << " " << winw << " " << winh);
155
int border_size = BORDER_SIZE;
156
if (bar_max_value > 0)
158
bar_width = (bar_value * (winw - 2 * border_size)) / bar_max_value;
163
if (secondary_bar_max_value > 0)
165
sbar_width = (secondary_bar_value * (winw - 2 * border_size)) / secondary_bar_max_value;
168
int bar_h = winh - 2 * border_size;
174
//assert(secondary_bar_color == COLOR_ID_INACTIVE);
175
ITimeBar::ColorId overlap_color;
178
case ITimeBar::COLOR_ID_ACTIVE:
179
overlap_color = ITimeBar::COLOR_ID_INACTIVE_OVER_ACTIVE;
181
case ITimeBar::COLOR_ID_OVERDUE:
182
overlap_color = ITimeBar::COLOR_ID_INACTIVE_OVER_OVERDUE;
185
overlap_color = ITimeBar::COLOR_ID_BG;
188
if (sbar_width >= bar_width)
192
r.left = winx+ border_size ;
193
r.top = winy+ border_size ;
194
r.right = r.left + bar_width;
195
r.bottom = r.top + bar_h;
196
FillRect(dc, &r, bar_colors[overlap_color]);
198
if (sbar_width > bar_width)
200
r.left = winx + bar_width+ border_size ;
201
r.top = winy+ border_size ;
202
r.right = r.left + sbar_width - bar_width;
203
r.bottom = r.top + bar_h;
204
FillRect(dc, &r, bar_colors[secondary_bar_color]);
211
r.left = winx+ border_size ;
212
r.top = winy+ border_size ;
213
r.right = r.left + sbar_width;
214
r.bottom = r.top + bar_h;
215
FillRect(dc, &r, bar_colors[overlap_color]);
217
r.left = winx + border_size + sbar_width;
218
r.top = winy + border_size ;
219
r.right = r.left + bar_width - sbar_width;
220
r.bottom = r.top + bar_h;
221
FillRect(dc, &r, bar_colors[bar_color]);
227
r.left = winx + border_size;
228
r.top = winy + border_size;
229
r.right = r.left + bar_width;
230
r.bottom = r.top + bar_h;
231
FillRect(dc, &r, bar_colors[bar_color]);
235
r.left = winx + border_size + __max(bar_width, sbar_width);
236
r.top = winy + border_size;
237
r.right = winx + winw - border_size;
238
r.bottom = r.top + bar_h;
239
FillRect(dc, &r, bar_colors[ITimeBar::COLOR_ID_BG]);
243
r.bottom = r.top + winh;
244
r.right = r.left + winw;
245
DrawEdge(dc, &r, BF_ADJUST|EDGE_SUNKEN,BF_RECT);
247
SetBkMode(dc, TRANSPARENT);
248
r.right -= border_size + MARGINX;
249
r.left += border_size + MARGINX;
250
DrawText(dc, bar_text, (int)strlen( bar_text ), &r, DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
254
paint_helper->EndPaint();
261
TimeBar::init(HINSTANCE hinst)
263
TRACE_ENTER("TimeBar::init");
265
//If the window class has not been registered, then do so.
267
if (!GetClassInfo(hinst, TIME_BAR_CLASS_NAME, &wc))
269
ZeroMemory(&wc, sizeof(wc));
270
wc.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
271
wc.lpfnWndProc = (WNDPROC)wnd_proc;
274
wc.hInstance = hinst;
276
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
277
wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(192, 0, 0));
278
wc.lpszMenuName = NULL;
279
wc.lpszClassName = TIME_BAR_CLASS_NAME;
283
HBRUSH green_mix_blue = CreateSolidBrush(0x00b2d400);
284
HBRUSH light_green = CreateSolidBrush(GDK_TO_COLORREF(37008,61166,37008));
285
HBRUSH orange = CreateSolidBrush(GDK_TO_COLORREF(65535, 42405, 0));
286
HBRUSH light_blue = CreateSolidBrush(GDK_TO_COLORREF(44461, 55512, 59110));
287
HBRUSH bg = CreateSolidBrush(GetSysColor(COLOR_3DLIGHT));
289
bar_colors[ITimeBar::COLOR_ID_ACTIVE] = light_blue;
290
bar_colors[ITimeBar::COLOR_ID_INACTIVE] = light_green;
291
bar_colors[ITimeBar::COLOR_ID_OVERDUE] = orange;
292
bar_colors[ITimeBar::COLOR_ID_INACTIVE_OVER_ACTIVE] = green_mix_blue;
293
bar_colors[ITimeBar::COLOR_ID_INACTIVE_OVER_OVERDUE] = light_green;
294
bar_colors[ITimeBar::COLOR_ID_BG] = bg;
296
NONCLIENTMETRICS_PRE_VISTA_STRUCT ncm;
298
// the default status font info on my system:
300
-12, 0, 0, 0, 400, 0, 0, 0, '\1', 0, 0, 0, 0, TEXT( "Tahoma" )
301
//0, 0x00146218, 0, 0x001461F0, 0, '@', 0, 0, 0, 0, 0, 0, 0, TEXT( "�~" )
304
ZeroMemory( &ncm, sizeof( ncm ) );
305
ncm.cbSize = sizeof( ncm );
306
ncm.lfStatusFont = lfDefault;
308
if (!SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( ncm ), &ncm, 0 ))
309
// If SystemParametersInfo fails, use my default.
310
// Now that we're filling a pre-vista NCM struct, there
311
// shouldn't be any problem though, regardless of target.
313
ncm.lfStatusFont = lfDefault;
316
bar_font = CreateFontIndirect(&ncm.lfStatusFont);
322
//! Converts the specified time to a string
324
TimeBar::time_to_string(time_t time, char *buf, int len)
338
int hrs = (int)( time / 3600 );
339
int min = (int)( (time / 60) % 60 );
340
int sec = (int)( time % 60 );
344
_snprintf_s( buf, len, _TRUNCATE, "%s%d:%02d:%02d", t, hrs, min, sec );
348
_snprintf_s( buf, len, _TRUNCATE, "%s%d:%02d", t, min, sec );
354
TimeBar::set_progress(int value, int max_value)
357
bar_max_value = max_value;
361
TimeBar::set_secondary_progress(int value, int max_value)
363
secondary_bar_value = value;
364
secondary_bar_max_value = max_value;
368
TimeBar::set_text(const char *text)
370
TRACE_ENTER("TimeBar::set_text");
371
strncpy_s(bar_text, APPLET_BAR_TEXT_MAX_LENGTH, text, _TRUNCATE);
378
TRACE_ENTER("TimeBar::update");
379
InvalidateRect(hwnd, NULL, FALSE);
384
TimeBar::set_bar_color(ITimeBar::ColorId color)
390
TimeBar::set_secondary_bar_color(ITimeBar::ColorId color)
392
secondary_bar_color = color;