blob: 3056f283cbf94e2e46f33d634627d5bc5006de03 [file] [log] [blame]
Constantin Kaplinsky729598c2006-05-25 05:12:25 +00001/* Copyright (C) 2005 TightVNC Team. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19// -=- PlayerToolBar.cxx
20
21#include <rfbplayer/rfbplayer.h>
22#include <rfbplayer/resource.h>
23
24PlayerToolBar::PlayerToolBar()
25: ToolBar(), hFont(0), timeStatic(0), speedEdit(0), posTrackBar(0),
26 speedUpDown(0), sliderDragging(false), sliderStepMs(0)
27{
28}
29
30void PlayerToolBar::create(RfbPlayer *player_, HWND parentHwnd_) {
31 HDC hdc;
32 SIZE sz;
33 RECT tRect;
34 NONCLIENTMETRICS nonClientMetrics;
35
36 player = player_;
37
38 // Get the default font for the main menu
39 nonClientMetrics.cbSize = sizeof(NONCLIENTMETRICS);
40 if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &nonClientMetrics, 0))
41 MessageBox(0, "Can't access to the system font.",
42 "RfbPlayer", MB_OK | MB_ICONERROR);
43 nonClientMetrics.lfMenuFont.lfHeight = 16;
44 hFont = CreateFontIndirect(&nonClientMetrics.lfMenuFont);
45
46 // Create the toolbar panel
47 ToolBar::create(ID_TOOLBAR, parentHwnd_,
48 WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | CCS_NORESIZE);
49 addBitmap(4, IDB_TOOLBAR);
50
51 // Create the control buttons
52 addButton(0, ID_PLAY);
53 addButton(1, ID_PAUSE);
54 addButton(2, ID_STOP);
55 addButton(0, 0, TBSTATE_ENABLED, TBSTYLE_SEP);
56
57 // Create the static control for the time output
58 timeStatic = CreateWindowEx(0, "Static", "00m:00s (00m:00s)",
59 WS_CHILD | WS_VISIBLE, 0, 0, 20, 20, getHandle(), (HMENU)ID_TIME_STATIC,
60 GetModuleHandle(0), 0);
61 SendMessage(timeStatic, WM_SETFONT,(WPARAM) hFont, TRUE);
62 hdc = GetDC(timeStatic);
63 SelectObject(hdc, hFont);
64 GetTextExtentPoint32(hdc, "00m:00s (00m:00s)", 16, &sz);
65 addButton(sz.cx + 10, 0, TBSTATE_ENABLED, TBSTYLE_SEP);
66 addButton(0, 10, TBSTATE_ENABLED, TBSTYLE_SEP);
67 getButtonRect(4, &tRect);
68 MoveWindow(timeStatic, tRect.left, tRect.top+2, tRect.right-tRect.left,
69 tRect.bottom-tRect.top, FALSE);
70
71 // Create the trackbar control for the time position
72 addButton(200, 0, TBSTATE_ENABLED, TBSTYLE_SEP);
73 getButtonRect(6, &tRect);
74 posTrackBar = CreateWindowEx(0, TRACKBAR_CLASS, "Trackbar Control",
75 WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS | TBS_ENABLESELRANGE,
76 tRect.left, tRect.top, tRect.right-tRect.left, tRect.bottom-tRect.top,
77 parentHwnd, (HMENU)ID_POS_TRACKBAR, GetModuleHandle(0), 0);
78 // It's need to send notify messages to toolbar parent window
79 SetParent(posTrackBar, getHandle());
80 addButton(0, 10, TBSTATE_ENABLED, TBSTYLE_SEP);
81
82 // Create the label with "Speed:" caption
83 HWND speedStatic = CreateWindowEx(0, "Static", "Speed:", WS_CHILD | WS_VISIBLE,
84 0, 0, 5, 5, getHandle(), (HMENU)ID_SPEED_STATIC, GetModuleHandle(0), 0);
85 SendMessage(speedStatic, WM_SETFONT,(WPARAM) hFont, TRUE);
86 hdc = GetDC(speedStatic);
87 SelectObject(hdc, hFont);
88 GetTextExtentPoint32(hdc, "Speed:", 6, &sz);
89 addButton(sz.cx + 10, 0, TBSTATE_ENABLED, TBSTYLE_SEP);
90 getButtonRect(8, &tRect);
91 MoveWindow(speedStatic, tRect.left, tRect.top+2, tRect.right-tRect.left,
92 tRect.bottom-tRect.top, FALSE);
93
94 // Create the edit control and the spin for the speed managing
95 addButton(60, 0, TBSTATE_ENABLED, TBSTYLE_SEP);
96 getButtonRect(9, &tRect);
97 speedEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", "1.00",
98 WS_CHILD | WS_VISIBLE | ES_RIGHT, tRect.left, tRect.top,
99 tRect.right-tRect.left, tRect.bottom-tRect.top, parentHwnd,
100 (HMENU)ID_SPEED_EDIT, GetModuleHandle(0), 0);
101 SendMessage(speedEdit, WM_SETFONT,(WPARAM) hFont, TRUE);
102 // It's need to send notify messages to toolbar parent window
103 SetParent(speedEdit, getHandle());
104
105 speedUpDown = CreateUpDownControl(WS_CHILD | WS_VISIBLE
106 | WS_BORDER | UDS_ALIGNRIGHT, 0, 0, 0, 0, getHandle(),
107 ID_SPEED_UPDOWN, GetModuleHandle(0), speedEdit, 20, 1, 2);
108
109 // Resize the toolbar window
110 autoSize();
111}
112
113void PlayerToolBar::init(long sessionTimeMs_) {
114 sessionTimeMs = sessionTimeMs_;
115
116 setSessionTimeStr(sessionTimeMs);
117 SendMessage(posTrackBar, TBM_SETRANGE,
118 TRUE, MAKELONG(0, min(sessionTimeMs / 1000, MAX_POS_TRACKBAR_RANGE)));
119 if (sessionTimeMs == 0) {
120 sliderStepMs = 1;
121 } else {
122 sliderStepMs = sessionTimeMs / SendMessage(posTrackBar, TBM_GETRANGEMAX, 0, 0);
123 }
124 updatePos(0);
125}
126
127void PlayerToolBar::enable() {
128 enableButton(ID_PLAY, true);
129 enableButton(ID_PAUSE, true);
130 enableButton(ID_STOP, true);
131 enableButton(ID_FULLSCREEN, true);
132 EnableWindow(posTrackBar, true);
133 EnableWindow(speedEdit, true);
134 EnableWindow(speedUpDown, true);
135}
136
137void PlayerToolBar::disable() {
138 enableButton(ID_PLAY, false);
139 enableButton(ID_PAUSE, false);
140 enableButton(ID_STOP, false);
141 enableButton(ID_FULLSCREEN, false);
142 EnableWindow(posTrackBar, false);
143 EnableWindow(speedEdit, false);
144 EnableWindow(speedUpDown, false);
145}
146
147LRESULT PlayerToolBar::processWM_COMMAND(WPARAM wParam, LPARAM lParam) {
148 switch (LOWORD(wParam)) {
149
150 case ID_RETURN:
151 // Update the speed if return pressed in speedEdit
152 if (getSpeedEditHwnd() == GetFocus()) {
153 char speedStr[20], *stopStr;
154 GetWindowText(getSpeedEditHwnd(), speedStr, sizeof(speedStr));
155 double speed = strtod(speedStr, &stopStr);
156 if (speed > 0) {
157 speed = min(MAX_SPEED, speed);
158 } else {
159 speed = player->getSpeed();
160 }
161 player->setSpeed(speed);
162 return FALSE;
163 }
164 }
165
166 return TRUE;
167}
168
169LRESULT PlayerToolBar::processWM_HSCROLL(WPARAM wParam, LPARAM lParam) {
170 long Pos = SendMessage(posTrackBar, TBM_GETPOS, 0, 0);
171 Pos *= sliderStepMs;
172
173 switch (LOWORD(wParam)) {
174 case TB_PAGEUP:
175 case TB_PAGEDOWN:
176 case TB_LINEUP:
177 case TB_LINEDOWN:
178 case TB_THUMBTRACK:
179 sliderDragging = true;
180 updatePos(Pos);
181 return FALSE;
182 case TB_THUMBPOSITION:
183 case TB_ENDTRACK:
184 player->setPos(Pos);
185 player->setPaused(player->isPaused());;
186 updatePos(Pos);
187 sliderDragging = false;
188 return FALSE;
189 default:
190 break;
191 }
192
193 return TRUE;
194}
195
196LRESULT PlayerToolBar::processWM_NOTIFY(WPARAM wParam, LPARAM lParam) {
197 switch (((NMHDR*)lParam)->code) {
198 case UDN_DELTAPOS:
199 if ((int)wParam == ID_SPEED_UPDOWN) {
200 char speedStr[20] = "\0";
201 DWORD speedRange = SendMessage(speedUpDown, UDM_GETRANGE, 0, 0);
202 LPNM_UPDOWN upDown = (LPNM_UPDOWN)lParam;
203 double speed;
204
205 // The out of range checking
206 if (upDown->iDelta > 0) {
207 speed = min(upDown->iPos + upDown->iDelta, LOWORD(speedRange)) * 0.5;
208 } else {
209 // It's need to round the UpDown position
210 if ((upDown->iPos * 0.5) != player->getSpeed()) {
211 upDown->iDelta = 0;
212 }
213 speed = max(upDown->iPos + upDown->iDelta, HIWORD(speedRange)) * 0.5;
214 }
215 player->setSpeed(speed);
216 }
217 }
218
219 // We always return TRUE to prevent the change in the updown contol
220 // position. The control's position changes in the RfbPlayer::setSpeed().
221 return TRUE;
222}
223
224void PlayerToolBar::updatePos(long newPos) {
225 // Update time pos in static control
226 char timePos[30] = "\0";
227 long time = newPos / 1000;
228 sprintf(timePos, "%.2um:%.2us (%s)", time/60, time%60, fullSessionTimeStr);
229 SetWindowText(timeStatic, timePos);
230
231 // Update the position of slider
232 if (!sliderDragging) {
233 double error = SendMessage(posTrackBar, TBM_GETPOS, 0, 0) *
234 sliderStepMs / double(newPos);
235 if (!((error > 1 - CALCULATION_ERROR) && (error <= 1 + CALCULATION_ERROR))) {
236 SendMessage(posTrackBar, TBM_SETPOS, TRUE, newPos / sliderStepMs);
237 }
238 }
239}
240
241void PlayerToolBar::setSessionTimeStr(long sessionTimeMs) {
242 sprintf(fullSessionTimeStr, "%.2um:%.2us",
243 sessionTimeMs / 1000 / 60, sessionTimeMs / 1000 % 60);
244}
245
246void PlayerToolBar::setTimePos(long pos) {
247 SendMessage(posTrackBar, TBM_SETPOS, TRUE, pos);
248}