vdr 2.7.4
skinlcars.c
Go to the documentation of this file.
1/*
2 * skinlcars.c: A VDR skin with Star Trek's "LCARS" layout
3 *
4 * See the main source file 'vdr.c' for copyright information and
5 * how to reach the author.
6 *
7 * $Id: skinlcars.c 5.8 2024/12/02 12:40:56 kls Exp $
8 */
9
10// "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
11// registered in the United States Patent and Trademark Office, all rights reserved.
12// The LCARS system is based upon the designs of Michael Okuda and his Okudagrams.
13//
14// "LCARS" is short for "Library Computer Access and Retrieval System".
15// Some resources used for writing this skin can be found at
16// http://www.lcars.org.uk
17// http://www.lcarsdeveloper.com
18// http://www.lcarscom.net
19// http://lds-jedi.deviantart.com/art/LCARS-Swept-Tutorial-213936938
20// http://lds-jedi.deviantart.com/art/LCARS-Button-Tutorial-210783437
21// http://zelldenver.deviantart.com/art/LCARS-Color-Standard-179565780
22// http://www.lcars47.com
23// http://www.bracercom.com/tutorial/content/CoherentLCARSInterface/LCARSCoherentInterface.html
24// http://www.bracercom.com/tutorial/content/lcars_manifesto/the_lcars_manifesto.html
25
26#include "skinlcars.h"
27#include "font.h"
28#include "menu.h"
29#include "osd.h"
30#include "positioner.h"
31#include "themes.h"
32#include "videodir.h"
33
34#include "symbols/arrowdown.xpm"
35#include "symbols/arrowup.xpm"
36#include "symbols/audio.xpm"
37#include "symbols/audioleft.xpm"
38#include "symbols/audioright.xpm"
39#include "symbols/audiostereo.xpm"
40#include "symbols/dolbydigital.xpm"
41#include "symbols/encrypted.xpm"
42#include "symbols/ffwd.xpm"
43#include "symbols/ffwd1.xpm"
44#include "symbols/ffwd2.xpm"
45#include "symbols/ffwd3.xpm"
46#include "symbols/frew.xpm"
47#include "symbols/frew1.xpm"
48#include "symbols/frew2.xpm"
49#include "symbols/frew3.xpm"
50#include "symbols/mute.xpm"
51#include "symbols/pause.xpm"
52#include "symbols/play.xpm"
53#include "symbols/radio.xpm"
54#include "symbols/recording.xpm"
55#include "symbols/sfwd.xpm"
56#include "symbols/sfwd1.xpm"
57#include "symbols/sfwd2.xpm"
58#include "symbols/sfwd3.xpm"
59#include "symbols/srew.xpm"
60#include "symbols/srew1.xpm"
61#include "symbols/srew2.xpm"
62#include "symbols/srew3.xpm"
63#include "symbols/teletext.xpm"
64#include "symbols/volume.xpm"
65
66#define Gap (Setup.FontOsdSize / 5 & ~1) // must be even
67#define TextFrame (Setup.FontOsdSize / TEXT_ALIGN_BORDER)
68#define TextSpacing (2 * TextFrame)
69#define SymbolSpacing TextSpacing
70#define ShowSeenExtent (Setup.FontOsdSize / 5) // pixels by which the "seen" bar extends out of the frame
71
72#define DISKUSAGEALERTLIMIT 95 // percent of disk usage above which the display goes into alert mode
73#define SIGNALDISPLAYDELTA 2 // seconds between subsequent device signal displays
74
76
77// Color domains:
78
79#define CLR_BACKGROUND 0x99000000
80#define CLR_MAIN_FRAME 0xFFFF9966
81#define CLR_CHANNEL_FRAME 0xFF8A9EC9
82#define CLR_REPLAY_FRAME 0xFFCC6666
83#define CLR_DATE 0xFF99CCFF
84#define CLR_MENU_ITEMS 0xFF9999FF
85#define CLR_TIMER 0xFF99CCFF
86#define CLR_DEVICE 0xFFF1B1AF
87#define CLR_CHANNEL_NAME 0xFF99CCFF
88#define CLR_EVENT_TITLE 0xFF99CCFF
89#define CLR_EVENT_TIME 0xFFFFCC66
90#define CLR_EVENT_SHORTTEXT 0xFFFFCC66
91#define CLR_TEXT 0xFF99CCFF
92#define CLR_TRACK 0xFFFFCC66
93#define CLR_SEEN 0xFFCC99CC
94#define CLR_ALERT 0xFFFF0000
95#define CLR_EXPOSED 0xFF990000
96#define CLR_WHITE 0xFFFFFFFF
97#define CLR_RED 0xFFCC6666
98#define CLR_GREEN 0xFFA0FF99
99#define CLR_YELLOW 0xFFF1DF60
100#define CLR_BLUE 0xFF9A99FF
101#define CLR_BLACK 0xFF000000
102
103// General colors:
104
110THEME_CLR(Theme, clrDeviceFg, CLR_BLACK);
112THEME_CLR(Theme, clrSignalValue, CLR_GREEN);
113THEME_CLR(Theme, clrSignalRest, CLR_RED);
115THEME_CLR(Theme, clrTrackName, CLR_TRACK);
122THEME_CLR(Theme, clrEventDescription, CLR_TEXT);
123
124// Buttons:
125
126THEME_CLR(Theme, clrButtonRedFg, CLR_BLACK);
127THEME_CLR(Theme, clrButtonRedBg, CLR_RED);
128THEME_CLR(Theme, clrButtonGreenFg, CLR_BLACK);
129THEME_CLR(Theme, clrButtonGreenBg, CLR_GREEN);
130THEME_CLR(Theme, clrButtonYellowFg, CLR_BLACK);
131THEME_CLR(Theme, clrButtonYellowBg, CLR_YELLOW);
132THEME_CLR(Theme, clrButtonBlueFg, CLR_BLACK);
133THEME_CLR(Theme, clrButtonBlueBg, CLR_BLUE);
134
135// Messages:
136
137THEME_CLR(Theme, clrMessageStatusFg, CLR_BLACK);
138THEME_CLR(Theme, clrMessageStatusBg, CLR_BLUE);
139THEME_CLR(Theme, clrMessageInfoFg, CLR_BLACK);
140THEME_CLR(Theme, clrMessageInfoBg, CLR_GREEN);
141THEME_CLR(Theme, clrMessageWarningFg, CLR_BLACK);
142THEME_CLR(Theme, clrMessageWarningBg, CLR_YELLOW);
143THEME_CLR(Theme, clrMessageErrorFg, CLR_BLACK);
144THEME_CLR(Theme, clrMessageErrorBg, CLR_RED);
145
146// Volume:
147
149THEME_CLR(Theme, clrVolumeSymbol, CLR_BLACK);
150THEME_CLR(Theme, clrVolumeBarUpper, RgbShade(CLR_MAIN_FRAME, -0.2));
151THEME_CLR(Theme, clrVolumeBarLower, CLR_GREEN);
152
153// Channel display:
154
155THEME_CLR(Theme, clrChannelFrameFg, CLR_BLACK);
156THEME_CLR(Theme, clrChannelFrameBg, CLR_CHANNEL_FRAME);
157THEME_CLR(Theme, clrChannelSymbolOn, CLR_BLACK);
158THEME_CLR(Theme, clrChannelSymbolOff, RgbShade(CLR_CHANNEL_FRAME, -0.2));
159THEME_CLR(Theme, clrChannelSymbolRecFg, CLR_WHITE);
160THEME_CLR(Theme, clrChannelSymbolRecBg, CLR_RED);
161
162// Menu:
163
164THEME_CLR(Theme, clrMenuFrameFg, CLR_BLACK);
167THEME_CLR(Theme, clrMenuMainBracket, CLR_MENU_ITEMS);
168THEME_CLR(Theme, clrMenuTimerRecording, CLR_DEVICE);
169THEME_CLR(Theme, clrMenuDeviceRecording, CLR_TIMER);
170THEME_CLR(Theme, clrMenuItemCurrentFg, CLR_MAIN_FRAME);
171THEME_CLR(Theme, clrMenuItemCurrentBg, RgbShade(CLR_MENU_ITEMS, -0.5));
172THEME_CLR(Theme, clrMenuItemSelectable, CLR_MENU_ITEMS);
173THEME_CLR(Theme, clrMenuItemNonSelectable, CLR_TEXT);
174THEME_CLR(Theme, clrMenuScrollbarTotal, RgbShade(CLR_MAIN_FRAME, 0.2));
175THEME_CLR(Theme, clrMenuScrollbarShown, CLR_SEEN);
176THEME_CLR(Theme, clrMenuScrollbarArrow, CLR_BLACK);
177THEME_CLR(Theme, clrMenuText, CLR_TEXT);
178
179// Replay display:
180
181THEME_CLR(Theme, clrReplayFrameFg, CLR_BLACK);
182THEME_CLR(Theme, clrReplayFrameBg, CLR_REPLAY_FRAME);
183THEME_CLR(Theme, clrReplayPosition, CLR_SEEN);
184THEME_CLR(Theme, clrReplayJumpFg, CLR_BLACK);
185THEME_CLR(Theme, clrReplayJumpBg, CLR_SEEN);
186THEME_CLR(Theme, clrReplayProgressSeen, CLR_SEEN);
187THEME_CLR(Theme, clrReplayProgressRest, RgbShade(CLR_WHITE, -0.2));
188THEME_CLR(Theme, clrReplayProgressSelected, CLR_EXPOSED);
189THEME_CLR(Theme, clrReplayProgressMark, CLR_BLACK);
190THEME_CLR(Theme, clrReplayProgressCurrent, CLR_EXPOSED);
191THEME_CLR(Theme, clrReplayProgressError, CLR_BLACK);
192
193// Track display:
194
195THEME_CLR(Theme, clrTrackFrameFg, CLR_BLACK);
196THEME_CLR(Theme, clrTrackFrameBg, CLR_TRACK);
197THEME_CLR(Theme, clrTrackItemFg, CLR_BLACK);
198THEME_CLR(Theme, clrTrackItemBg, RgbShade(CLR_TRACK, 0.5));
199THEME_CLR(Theme, clrTrackItemCurrentFg, CLR_BLACK);
200THEME_CLR(Theme, clrTrackItemCurrentBg, CLR_TRACK);
201
202// --- Helper functions ------------------------------------------------------
203
204static bool TwoColors = false;
205
206static cOsd *CreateOsd(int Left, int Top, int x0, int y0, int x1, int y1)
207{
208 cOsd *Osd = cOsdProvider::NewOsd(Left, Top);
209 int Bpp[] = { 32, 8, 4, 2, 1 };
210 tArea Area = { x0, y0, x1, y1, 0 };
211 for (unsigned int i = 0; i < sizeof(Bpp) / sizeof(int); i++) {
212 Area.bpp = Bpp[i];
213 if (Osd->CanHandleAreas(&Area, 1) == oeOk) {
214 Osd->SetAreas(&Area, 1);
215 Osd->SetAntiAliasGranularity(20, 16);
216 TwoColors = Area.bpp == 1;
217 break;
218 }
219 }
220 return Osd;
221}
222
223static cFont *CreateTinyFont(int LineHeight)
224{
225 // Creates a font that is not higher than half of LineHeight.
226 LineHeight /= 2;
227 int Height = LineHeight;
228 for (;;) {
229 cFont *TinyFont = cFont::CreateFont(Setup.FontOsd, Height);
230 if (Height < 2 || TinyFont->Height() <= LineHeight)
231 return TinyFont;
232 delete TinyFont;
233 Height -= 1;
234 }
235}
236
237static bool DrawDeviceData(cOsd *Osd, const cDevice *Device, int x0, int y0, int x1, int y1, int &xs, const cFont *TinyFont, cString &LastDeviceType, cCamSlot *&LastCamSlot, bool Initial)
238{
239 cString DeviceType = Device->DeviceType();
240 cCamSlot *CamSlot = Device->CamSlot();
241 if (Initial || strcmp(DeviceType, LastDeviceType) || CamSlot != LastCamSlot) {
242 const cFont *font = cFont::GetFont(fontOsd);
243 tColor ColorFg = Theme.Color(clrDeviceFg);
244 tColor ColorBg = Theme.Color(clrDeviceBg);
245 Osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, ColorBg);
246 int x = x0;
247 // Device number:
248 cString Nr = itoa(Device->DeviceNumber() + 1);
249 int w = max(font->Width(Nr), y1 - y0);
250 Osd->DrawText(x, y0, Nr, ColorFg, ColorBg, font, w, y1 - y0, taCenter);
251 x += w;
252 // Device type:
253 Osd->DrawText(x, y0, DeviceType, ColorFg, ColorBg, TinyFont);
254 xs = max(xs, x + TinyFont->Width(DeviceType));
255 LastDeviceType = DeviceType;
256 // CAM:
257 if (CamSlot) {
258 cString s = cString::sprintf("CAM %d", CamSlot->MasterSlotNumber());
259 Osd->DrawText(x, y1 - TinyFont->Height(), s, ColorFg, ColorBg, TinyFont);
260 xs = max(xs, x + TinyFont->Width(s));
261 }
262 LastCamSlot = CamSlot;
263 return true;
264 }
265 return false;
266}
267
268static void DrawDeviceSignal(cOsd *Osd, const cDevice *Device, int x0, int y0, int x1, int y1, int &LastSignalStrength, int &LastSignalQuality, bool Initial)
269{
270 int SignalStrength = Device->SignalStrength();
271 int SignalQuality = Device->SignalQuality();
272 int d = max((y1 - y0) / 10, 1);
273 int x00 = x0 + d;
274 int x01 = x1 - d;
275 int h = (y1 - y0 - 3 * d) / 2;
276 int w = x01 - x00;
277 int y00 = y0 + d;
278 int y01 = y00 + h;
279 int y03 = y1 - d;
280 int y02 = y03 - h;
281 tColor ColorSignalValue, ColorSignalRest;
282 if (TwoColors) {
283 ColorSignalValue = Theme.Color(clrBackground);
284 ColorSignalRest = Theme.Color(clrMenuFrameBg);
285 }
286 else {
287 ColorSignalValue = Theme.Color(clrSignalValue);
288 ColorSignalRest = Theme.Color(clrSignalRest);
289 }
290 if (SignalStrength >= 0 && (Initial || SignalStrength != LastSignalStrength)) {
291 int s = SignalStrength * w / 100;
292 Osd->DrawRectangle(x00, y00, x00 + s - 1, y01 - 1, ColorSignalValue);
293 Osd->DrawRectangle(x00 + s, y00, x01 - 1, y01 - 1, ColorSignalRest);
294 LastSignalStrength = SignalStrength;
295 }
296 if (SignalQuality >= 0 && (Initial || SignalQuality != LastSignalQuality)) {
297 int q = SignalQuality * w / 100;
298 Osd->DrawRectangle(x00, y02, x00 + q - 1, y03 - 1, ColorSignalValue);
299 Osd->DrawRectangle(x00 + q, y02, x01 - 1, y03 - 1, ColorSignalRest);
300 LastSignalQuality = SignalQuality;
301 }
302}
303
304static void DrawDevicePosition(cOsd *Osd, const cPositioner *Positioner, int x0, int y0, int x1, int y1, int &LastCurrent)
305{
306 int HorizonLeft = Positioner->HorizonLongitude(cPositioner::pdLeft);
307 int HorizonRight = Positioner->HorizonLongitude(cPositioner::pdRight);
308 int HardLimitLeft = cPositioner::NormalizeAngle(HorizonLeft - Positioner->HardLimitLongitude(cPositioner::pdLeft));
309 int HardLimitRight = cPositioner::NormalizeAngle(Positioner->HardLimitLongitude(cPositioner::pdRight) - HorizonRight);
310 int HorizonDelta = cPositioner::NormalizeAngle(HorizonLeft - HorizonRight);
311 int Current = cPositioner::NormalizeAngle(HorizonLeft - Positioner->CurrentLongitude());
312 int Target = cPositioner::NormalizeAngle(HorizonLeft - Positioner->TargetLongitude());
313 int d = (y1 - y0) / 2;
314 int w = x1 - x0 - 2 * d;
315 int l = max(x0 + d, x0 + d + w * HardLimitLeft / HorizonDelta);
316 int r = min(x1 - d, x1 - d - w * HardLimitRight / HorizonDelta) - 1;
317 int c = constrain(x0 + d + w * Current / HorizonDelta, l, r);
318 int t = constrain(x0 + d + w * Target / HorizonDelta, l, r);
319 if (c == LastCurrent)
320 return;
321 if (c > t)
322 swap(c, t);
323 tColor ColorRange, ColorMove;
324 if (TwoColors) {
325 ColorRange = Theme.Color(clrChannelFrameBg);
326 ColorMove = Theme.Color(clrBackground);
327 }
328 else {
329 ColorRange = Theme.Color(clrChannelFrameBg);
330 ColorMove = Theme.Color(clrDeviceBg);
331 }
332 Osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, Theme.Color(clrBackground));
333 Osd->DrawEllipse(l - d, y0, l, y1 - 1, ColorRange, 7);
334 Osd->DrawRectangle(l, y0, r, y1 - 1, ColorRange);
335 Osd->DrawEllipse(r, y0, r + d, y1 - 1, ColorRange, 5);
336 Osd->DrawEllipse(c - d, y0, c, y1 - 1, ColorMove, 7);
337 Osd->DrawRectangle(c, y0, t, y1 - 1, ColorMove);
338 Osd->DrawEllipse(t, y0, t + d, y1 - 1, ColorMove, 5);
339 LastCurrent = c;
340}
341
342// --- cSkinLCARSDisplayChannel ----------------------------------------------
343
345private:
349 int xs; // starting column for signal display
369 void DrawDate(void);
370 void DrawTrack(void);
371 void DrawSeen(int Current, int Total);
372 void DrawDevice(void);
373 void DrawSignal(void);
374public:
375 cSkinLCARSDisplayChannel(bool WithInfo);
377 virtual void SetChannel(const cChannel *Channel, int Number);
378 virtual void SetEvents(const cEvent *Present, const cEvent *Following);
379 virtual void SetMessage(eMessageType Type, const char *Text);
380 virtual void SetPositioner(const cPositioner *Positioner);
381 virtual void Flush(void);
382 };
383
390
392{
393 tallFont = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize * 1.8);
394 initial = true;
395 present = NULL;
396 lastSeen = -1;
398 lastDeviceNumber = -1;
399 lastCamSlot = NULL;
403 memset(&lastTrackId, 0, sizeof(lastTrackId));
404 const cFont *font = cFont::GetFont(fontOsd);
405 withInfo = WithInfo;
406 lineHeight = font->Height();
408 frameColor = Theme.Color(clrChannelFrameBg);
409 message = false;
410 int d = 5 * lineHeight;
411 xc00 = 0;
412 xc01 = xc00 + d / 2;
413 xc02 = xc00 + d;
414 xc03 = xc02 + lineHeight;
415 xc04 = xc02 + d / 4;
416 xc05 = xc02 + d;
417 xc06 = xc05 + Gap;
419 xc14 = xc15 - lineHeight;
420 xc13 = xc14 - Gap;
421 xc07 = (xc15 + xc00) / 2;
422 xc08 = xc07 + Gap;
423 xc09 = xc08 + lineHeight;
424 xc10 = xc09 + Gap;
425 xc11 = (xc10 + xc13 + Gap) / 2;
426 xc12 = xc11 + Gap;
427
428 yc00 = 0;
429 yc01 = yc00 + lineHeight;
430 yc02 = yc01 + lineHeight;
431 yc03 = yc02 + Gap;
432 yc04 = yc03 + 2 * lineHeight;
433 yc05 = yc04 + Gap;
434 yc06 = yc05 + 2 * lineHeight;
435
436 yc07 = yc06 + Gap;
437 yc12 = yc07 + 3 * lineHeight + Gap / 2;
438 yc11 = yc12 - lineHeight;
439 yc10 = yc11 - lineHeight;
440 yc09 = yc11 - d / 4;
441 yc08 = yc12 - d / 2;
442
443 xs = 0;
444
445 int y1 = withInfo ? yc12 : yc02;
446 int y0 = cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y1);
447 osd = CreateOsd(cOsd::OsdLeft(), y0, xc00, yc00, xc15 - 1, y1 - 1);
448 osd->DrawRectangle(xc00, yc00, xc15 - 1, y1 - 1, Theme.Color(clrBackground));
449 // Rectangles:
450 osd->DrawRectangle(xc00, yc00, xc02 - 1, yc02 - 1, frameColor);
451 if (withInfo) {
452 osd->DrawRectangle(xc00, yc03, xc02 - 1, yc04 - 1, frameColor);
453 osd->DrawRectangle(xc00, yc05, xc02 - 1, yc06 - 1, frameColor);
454 // Elbow:
455 osd->DrawRectangle(xc00, yc07, xc01 - 1, yc08 - 1, frameColor);
456 osd->DrawRectangle(xc00, yc08, xc01 - 1, yc12 - 1, clrTransparent);
457 osd->DrawEllipse (xc00, yc08, xc01 - 1, yc12 - 1, frameColor, 3);
458 osd->DrawRectangle(xc01, yc07, xc02 - 1, yc12 - 1, frameColor);
459 osd->DrawEllipse (xc02, yc09, xc04 - 1, yc11 - 1, frameColor, -3);
460 osd->DrawRectangle(xc02, yc11, xc05 - 1, yc12 - 1, frameColor);
461 // Status area:
462 osd->DrawRectangle(xc06, yc11 + lineHeight / 2, xc07 - 1, yc12 - 1, frameColor);
463 osd->DrawRectangle(xc08, yc11, xc09 - 1, yc12 - 1, frameColor);
464 osd->DrawRectangle(xc10, yc11, xc11 - 1, yc12 - 1, Theme.Color(clrDeviceBg));
465 osd->DrawRectangle(xc12, yc11, xc13 - 1, yc12 - 1, Theme.Color(clrDateBg));
466 osd->DrawRectangle(xc14, yc11, xc14 + lineHeight / 2 - 1, yc12 - 1, frameColor);
467 osd->DrawRectangle(xc14 + lineHeight / 2, yc11 + lineHeight / 2, xc15 - 1, yc12 - 1, clrTransparent);
468 osd->DrawEllipse (xc14 + lineHeight / 2, yc11, xc15 - 1, yc12 - 1, frameColor, 5);
469 }
470 // Icons:
471 osd->DrawRectangle(xc14, yc00, xc14 + lineHeight / 2 - 1, yc01 - 1, frameColor);
472 osd->DrawRectangle(xc14 + lineHeight / 2, yc00, xc15 - 1, yc00 + lineHeight / 2 - 1, clrTransparent);
473 osd->DrawEllipse (xc14 + lineHeight / 2, yc00, xc15 - 1, yc01 - 1, frameColor, 5);
474}
475
477{
478 delete tallFont;
479 delete tinyFont;
480 delete osd;
481}
482
484{
485 cString s = DayDateTime();
486 if (initial || !*lastDate || strcmp(s, lastDate)) {
487 osd->DrawText(xc12, yc11, s, Theme.Color(clrDateFg), Theme.Color(clrDateBg), cFont::GetFont(fontOsd), xc13 - xc12, lineHeight, taRight | taBorder);
488 lastDate = s;
489 }
490}
491
493{
495 const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
496 if (Track ? strcmp(lastTrackId.description, Track->description) : *lastTrackId.description) {
497 osd->DrawText(xc03, yc07, Track ? Track->description : "", Theme.Color(clrTrackName), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xc07 - xc03);
498 strn0cpy(lastTrackId.description, Track ? Track->description : "", sizeof(lastTrackId.description));
499 }
500}
501
503{
504 if (lastCurrentPosition >= 0)
505 return; // to not interfere with SetPositioner()
506 int Seen = (Total > 0) ? min(xc07 - xc06, int((xc07 - xc06) * double(Current) / Total)) : 0;
507 if (initial || Seen != lastSeen) {
508 int y0 = yc11 - ShowSeenExtent;
509 int y1 = yc11 + lineHeight / 2 - Gap / 2;
510 osd->DrawRectangle(xc06, y0, xc06 + Seen - 1, y1 - 1, Theme.Color(clrSeen));
511 osd->DrawRectangle(xc06 + Seen, y0, xc07 - 1, y1 - 1, Theme.Color(clrBackground));
512 lastSeen = Seen;
513 }
514}
515
517{
518 const cDevice *Device = cDevice::ActualDevice();
520 lastDeviceNumber = Device->DeviceNumber();
521 // Make sure signal meters are redrawn:
525 }
526}
527
529{
530 time_t Now = time(NULL);
531 if (Now != lastSignalDisplay) {
533 lastSignalDisplay = Now;
534 }
535}
536
537void cSkinLCARSDisplayChannel::SetChannel(const cChannel *Channel, int Number)
538{
539 int x = xc13;
540 int xi = x - SymbolSpacing -
541 bmRecording.Width() - SymbolSpacing -
542 bmEncrypted.Width() - SymbolSpacing -
543 bmDolbyDigital.Width() - SymbolSpacing -
544 bmAudio.Width() - SymbolSpacing -
545 max(bmTeletext.Width(), bmRadio.Width()) - SymbolSpacing;
546 osd->DrawRectangle(xi, yc00, xc13 - 1, yc01 - 1, frameColor);
547 if (Channel && !Channel->GroupSep()) {
548 bool rec = cRecordControls::Active();
549 x -= bmRecording.Width() + SymbolSpacing;
550 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : frameColor);
551 x -= bmEncrypted.Width() + SymbolSpacing;
552 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
553 x -= bmDolbyDigital.Width() + SymbolSpacing;
554 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid(0) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
555 x -= bmAudio.Width() + SymbolSpacing;
556 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid(1) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
557 if (Channel->Vpid()) {
558 x -= bmTeletext.Width() + SymbolSpacing;
559 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
560 }
561 else if (Channel->Apid(0)) {
562 x -= bmRadio.Width() + SymbolSpacing;
563 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmRadio.Height()) / 2, bmRadio, Theme.Color(clrChannelSymbolOn), frameColor);
564 }
565 }
566 cString ChNumber("");
567 cString ChName("");
568 if (Channel) {
569 ChName = Channel->Name();
570 if (!Channel->GroupSep())
571 ChNumber = cString::sprintf("%d%s", Channel->Number(), Number ? "-" : "");
572 }
573 else if (Number)
574 ChNumber = cString::sprintf("%d-", Number);
575 else
576 ChName = ChannelString(NULL, 0);
577 osd->DrawText(xc00, yc00, ChNumber, Theme.Color(clrChannelFrameFg), frameColor, tallFont, xc02 - xc00, yc02 - yc00, taTop | taRight | taBorder);
578 osd->DrawText(xc03, yc00, ChName, Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xi - xc03 - lineHeight, 0, taTop | taLeft);
580 if (withInfo) {
581 if (Channel) {
582 int x = xc00 + (yc10 - yc09); // compensate for the arc
583 osd->DrawText(x, yc07, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), frameColor, cFont::GetFont(fontOsd), xc02 - x, yc10 - yc07, taTop | taRight | taBorder);
584 }
585 DrawDevice();
586 }
587}
588
589void cSkinLCARSDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
590{
591 if (!withInfo)
592 return;
593 if (present != Present)
594 lastSeen = -1;
595 present = Present;
596 for (int i = 0; i < 2; i++) {
597 const cEvent *e = !i ? Present : Following;
598 int y = !i ? yc03 : yc05;
599 if (e) {
600 osd->DrawText(xc00, y, e->GetTimeString(), Theme.Color(clrChannelFrameFg), frameColor, cFont::GetFont(fontOsd), xc02 - xc00, 0, taRight | taBorder);
601 osd->DrawText(xc03, y, e->Title(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xc13 - xc03);
602 osd->DrawText(xc03, y + lineHeight, e->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xc13 - xc03);
603 }
604 else {
605 osd->DrawRectangle(xc00, y, xc02 - 1, y + lineHeight, frameColor);
606 osd->DrawRectangle(xc02, y, xc13 - 1, y + 2 * lineHeight, Theme.Color(clrBackground));
607 }
608 }
609}
610
612{
613 if (Text) {
614 int x0, x1, y0, y1, y2;
615 if (withInfo) {
616 x0 = xc06;
617 x1 = xc13;
618 y0 = yc11 - ShowSeenExtent;
619 y1 = yc11;
620 y2 = yc12;
621 }
622 else {
623 x0 = xc03;
624 x1 = xc13;
625 y0 = y1 = yc00;
626 y2 = yc02;
627 }
628 osd->SaveRegion(x0, y0, x1 - 1, y2 - 1);
629 if (withInfo)
630 osd->DrawRectangle(xc06, y0, xc07, y1 - 1, Theme.Color(clrBackground)); // clears the "seen" bar
631 osd->DrawText(x0, y1, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), x1 - x0, y2 - y1, taCenter);
632 message = true;
633 }
634 else {
635 osd->RestoreRegion();
636 message = false;
637 }
638}
639
641{
642 if (Positioner) {
643 int y0 = yc11 - ShowSeenExtent;
644 int y1 = yc11 + lineHeight / 2 - Gap / 2;
645 DrawDevicePosition(osd, Positioner, xc06, y0, xc07, y1, lastCurrentPosition);
646 }
647 else {
649 initial = true; // to have DrawSeen() refresh the progress bar
650 }
651 return;
652}
653
655{
656 if (withInfo) {
657 if (!message) {
658 DrawDate();
659 DrawTrack();
660 DrawDevice();
661 DrawSignal();
662 int Current = 0;
663 int Total = 0;
664 if (present) {
665 time_t t = time(NULL);
666 if (t > present->StartTime())
667 Current = t - present->StartTime();
668 Total = present->Duration();
669 }
670 DrawSeen(Current, Total);
671 }
672 }
673 osd->Flush();
674 initial = false;
675}
676
677// --- cSkinLCARSDisplayMenu -------------------------------------------------
678
680private:
691 int yi00, yi01;
695 int xs; // starting column for signal display
725 void DrawMainFrameUpper(tColor Color);
726 void DrawMainFrameLower(void);
727 void DrawMainButton(const char *Text, int x0, int x1, int x2, int x3, int y0, int y1, tColor ColorFg, tColor ColorBg, const cFont *Font);
728 void DrawMenuFrame(void);
729 void DrawMainBracket(void);
730 void DrawStatusElbows(void);
731 void DrawDate(void);
732 void DrawDisk(void);
733 void DrawLoad(void);
734 void DrawFrameDisplay(void);
735 void DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown);
736 void DrawTimer(const cTimer *Timer, int y, bool MultiRec);
737 void DrawTimers(void);
738 void DrawDevice(const cDevice *Device);
739 void DrawDevices(void);
740 void DrawLiveIndicator(void);
741 void DrawSignals(void);
742 void DrawLive(const cChannel *Channel);
743 void DrawPlay(cControl *Control);
744 void DrawInfo(const cEvent *Event, bool WithTime);
745 void DrawSeen(int Current, int Total);
746 void DrawTextScrollbar(void);
747public:
749 virtual ~cSkinLCARSDisplayMenu();
750 virtual void Scroll(bool Up, bool Page);
751 virtual int MaxItems(void);
752 virtual void Clear(void);
754 virtual void SetTitle(const char *Title);
755 virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
756 virtual void SetMessage(eMessageType Type, const char *Text);
757 virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
758 virtual void SetScrollbar(int Total, int Offset);
759 virtual void SetEvent(const cEvent *Event);
760 virtual void SetRecording(const cRecording *Recording);
761 virtual void SetText(const char *Text, bool FixedFont);
762 virtual int GetTextAreaWidth(void) const;
763 virtual const cFont *GetTextAreaFont(bool FixedFont) const;
764 virtual void Flush(void);
765 };
766
770
772{
773 tallFont = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize * 1.8);
774 initial = true;
776 lastChannel = NULL;
777 lastEvent = NULL;
778 lastRecording = NULL;
779 lastSeen = -1;
784 lastDiskAlert = false;
785 lastSystemLoad = -1;
786 const cFont *font = cFont::GetFont(fontOsd);
787 lineHeight = font->Height();
789 frameColor = Theme.Color(clrMenuFrameBg);
790 currentIndex = -1;
791 // The outer frame:
792 int d = 5 * lineHeight;
793 xa00 = 0;
794 xa01 = xa00 + d / 2;
795 xa02 = xa00 + d;
796 xa03 = xa02 + lineHeight;
797 xa04 = xa02 + d / 4;
798 xa05 = xa02 + d;
799 xa06 = xa05 + Gap;
801 xa08 = xa09 - lineHeight;
802 xa07 = xa08 - Gap;
803
804 yt00 = 0;
805 yt01 = yt00 + lineHeight;
806 yt02 = yt01 + lineHeight;
807 yt03 = yt01 + d / 4;
808 yt04 = yt02 + Gap;
809 yt05 = yt00 + d / 2;
810 yt06 = yt04 + 2 * lineHeight;
811
812 yc00 = yt06 + Gap;
813 yc05 = yc00 + 3 * lineHeight + Gap / 2;
814 yc04 = yc05 - lineHeight;
815 yc03 = yc04 - lineHeight;
816 yc02 = yc04 - d / 4;
817 yc01 = yc05 - d / 2;
818
819 yc06 = yc05 + Gap;
820 yc07 = yc06 + lineHeight;
821 yc08 = yc07 + lineHeight;
822 yc09 = yc07 + d / 4;
823 yc10 = yc06 + d / 2;
824 yc11 = yc06 + 3 * lineHeight + Gap / 2;
825
826 yb00 = yc11 + Gap;
827 yb01 = yb00 + 2 * lineHeight;
828 yb02 = yb01 + Gap;
829 yb03 = yb02 + 2 * lineHeight;
830 yb04 = yb03 + Gap;
831 yb05 = yb04 + 2 * lineHeight;
832 yb06 = yb05 + Gap;
833 yb07 = yb06 + 2 * lineHeight;
834 yb08 = yb07 + Gap;
835
837 yb14 = yb15 - lineHeight;
838 yb13 = yb14 - lineHeight;
839 yb12 = yb14 - d / 4;
840 yb11 = yb15 - d / 2;
841 yb10 = yb13 - Gap - 2 * lineHeight;
842 yb09 = yb10 - Gap;
843
844 // Compensate for large font size:
845 if (yb09 - yb08 < 2 * lineHeight) {
846 yb08 = yb06;
847 yb06 = 0; // drop empty rectangle
848 }
849 if (yb09 - yb08 < 2 * lineHeight) {
850 yb05 = yb09;
851 yb08 = 0; // drop "LCARS" display
852 }
853 if (yb05 - yb04 < 2 * lineHeight) {
854 yb03 = yb09;
855 yb04 = 0; // drop "LOAD" display
856 }
857 if (yb03 - yb02 < 2 * lineHeight) {
858 yb01 = yb09;
859 yb02 = 0; // drop "DISK" display
860 }
861 // Anything else is just insanely large...
862
863 // The main command menu:
864 xm00 = xa03;
865 xm01 = xa05;
866 xm02 = xa06;
867 xm08 = (xa09 + xa00) / 2;
868 xm07 = xm08 - lineHeight;
869 xm06 = xm07 - lineHeight / 2;
870 xm05 = xm06 - lineHeight / 2;
871 xm04 = xm05 - lineHeight;
872 xm03 = xm04 - Gap;
873 ym00 = yc08;
874 ym01 = ym00 + lineHeight / 2;
875 ym02 = ym01 + lineHeight / 2;
876 ym03 = ym02 + Gap;
877 ym07 = yb15;
878 ym06 = ym07 - lineHeight / 2;
879 ym05 = ym06 - lineHeight / 2;
880 ym04 = ym05 - Gap;
881
882 // The status area:
883 xs00 = xm08 + Gap + lineHeight + Gap;
884 xs13 = xa09;
885 xs12 = xa08;
886 xs11 = xa07;
887 xs05 = (xs00 + xs11 + Gap) / 2;
888 xs04 = xs05 - lineHeight / 2;
889 xs03 = xs04 - lineHeight / 2;
890 xs02 = xs03 - 2 * lineHeight;
891 xs01 = xs02 - Gap;
892 xs06 = xs05 + Gap;
893 xs07 = xs06 + lineHeight / 2;
894 xs08 = xs07 + lineHeight / 2;
895 xs09 = xs08 + 2 * lineHeight;
896 xs10 = xs09 + Gap;
897 ys00 = yc06;
898 ys01 = ys00 + lineHeight;
899 ys02 = ys01 + lineHeight / 2;
900 ys04 = ys01 + lineHeight;
901 ys03 = ys04 - Gap;
902 ys05 = yb15;
903
904 // The item area (just to have them initialized, actual setting will be done in SetMenuCategory():
905
906 xi00 = 0;
907 xi01 = 0;
908 xi02 = 0;
909 xi03 = 1;
910 yi00 = 0;
911 yi01 = 1;
912
913 // The color buttons in submenus:
914 xb00 = xa06;
915 xb15 = xa07;
916 int w = (xa08 - xa06) / 4;
917 xb01 = xb00 + lineHeight / 2;
918 xb02 = xb01 + Gap;
919 xb04 = xb00 + w;
920 xb03 = xb04 - Gap;
921 xb05 = xb04 + lineHeight / 2;
922 xb06 = xb05 + Gap;
923 xb08 = xb04 + w;
924 xb07 = xb08 - Gap;
925 xb09 = xb08 + lineHeight / 2;
926 xb10 = xb09 + Gap;
927 xb12 = xb08 + w;
928 xb11 = xb12 - Gap;
929 xb13 = xb12 + lineHeight / 2;
930 xb14 = xb13 + Gap;
931
932 // The color buttons in the main menu:
933 int r = lineHeight;
934 xd07 = xa09;
935 xd06 = xd07 - r;
936 xd05 = xd06 - 4 * r;
937 xd04 = xd05 - r;
938 xd03 = xd04 - Gap;
939 xd02 = xd03 - r;
940 xd01 = xd02 - 4 * r;
941 xd00 = xd01 - r;
942 yd00 = yt00;
943 yd05 = yc04 - Gap;
944 yd04 = yd05 - 2 * r;
945 yd03 = yd04 - Gap;
946 yd02 = yd03 - 2 * r;
947 yd01 = yd02 - Gap;
948
949 xs = 0;
950
952}
953
955{
956 delete tallFont;
957 delete tinyFont;
958 delete osd;
959}
960
962{
965 initial = true;
966 osd->DrawRectangle(xa00, yt00, xa09 - 1, yb15 - 1, Theme.Color(clrBackground));
967 if (MenuCategory == mcMain) {
968 yi00 = ym03;
969 yi01 = ym04;
970 xi00 = xm00;
971 xi01 = xm03;
972 xi02 = xm04;
973 xi03 = xm05;
974 timersStateKey.Reset();
978 }
979 else {
980 yi00 = yt02;
981 yi01 = yb13;
982 xi00 = xa03;
983 xi01 = xa07;
984 xi02 = xa08;
985 xi03 = xa09;
987 }
988 }
989}
990
992{
993 // Top left rectangles:
994 osd->DrawRectangle(xa00, yt00, xa02 - 1, yt02 - 1, Color);
995 osd->DrawRectangle(xa00, yt04, xa02 - 1, yt06 - 1, Color);
996 // Upper elbow:
997 osd->DrawRectangle(xa00, yc00, xa01 - 1, yc01 - 1, Color);
998 osd->DrawEllipse (xa00, yc01, xa01 - 1, yc05 - 1, Color, 3);
999 osd->DrawRectangle(xa01, yc00, xa02 - 1, yc05 - 1, Color);
1000 osd->DrawEllipse (xa02, yc02, xa04 - 1, yc04 - 1, Color, -3);
1001 osd->DrawRectangle(xa02, yc04, xa05 - 1, yc05 - 1, Color);
1002 // Upper delimiter:
1003 osd->DrawRectangle(xa06, yc04 + lineHeight / 2, xm08 - 1, yc05 - 1, Color);
1004 osd->DrawRectangle(xm08 + Gap, yc04, xs00 - Gap - 1, yc05 - 1, Color);
1005 osd->DrawRectangle(xs00, yc04, xs05 - 1, yc05 - 1, Color);
1006 osd->DrawRectangle(xs06, yc04, xa07 - 1, yc05 - 1, Color);
1007 osd->DrawRectangle(xa08, yc04, xa09 - 1, yc05 - 1, Color);
1008}
1009
1011{
1012 const cFont *font = cFont::GetFont(fontOsd);
1013 // Lower elbow:
1014 osd->DrawRectangle(xa00, yc10, xa01 - 1, yc11 - 1, frameColor);
1015 osd->DrawEllipse (xa00, yc06, xa01 - 1, yc10 - 1, frameColor, 2);
1016 osd->DrawRectangle(xa01, yc06, xa02 - 1, yc11 - 1, frameColor);
1017 osd->DrawEllipse (xa02, yc07, xa04 - 1, yc09 - 1, frameColor, -2);
1018 osd->DrawRectangle(xa02, yc06, xa05 - 1, yc07 - 1, frameColor);
1019 // Lower delimiter:
1020 osd->DrawRectangle(xa06, yc06, xm08 - 1, yc07 - lineHeight / 2 - 1, frameColor);
1021 osd->DrawRectangle(xm08 + Gap, yc06, xs00 - Gap - 1, yc07 - 1, frameColor);
1022 osd->DrawRectangle(xa08, yc06, xa09 - 1, yc07 - 1, frameColor);
1023 // VDR version:
1024 osd->DrawRectangle(xa00, yb10, xa02 - 1, yb15 - 1, frameColor);
1025 osd->DrawText(xa00, yb10, "VDR", Theme.Color(clrMenuFrameFg), frameColor, tallFont, xa02 - xa00, yb11 - yb10, taTop | taRight | taBorder);
1026 osd->DrawText(xa00, yb15 - lineHeight, VDRVERSION, Theme.Color(clrMenuFrameFg), frameColor, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1027}
1028
1029void cSkinLCARSDisplayMenu::DrawMainButton(const char *Text, int x0, int x1, int x2, int x3, int y0, int y1, tColor ColorFg, tColor ColorBg, const cFont *Font)
1030{
1031 int h = y1 - y0;
1032 osd->DrawEllipse(x0, y0, x1 - 1, y1 - 1, ColorBg, 7);
1033 osd->DrawText(x1, y0, Text, ColorFg, ColorBg, Font, x2 - x1, h, taBottom | taRight);
1034 osd->DrawEllipse(x2, y0, x3 - 1, y1 - 1, ColorBg, 5);
1035}
1036
1038{
1039 // Upper elbow:
1040 osd->DrawRectangle(xa00, yt05, xa01 - 1, yt06 - 1, frameColor);
1041 osd->DrawRectangle(xa00, yt00, xa01 - 1, yt05 - 1, clrTransparent);
1042 osd->DrawEllipse (xa00, yt00, xa01 - 1, yt05 - 1, frameColor, 2);
1043 osd->DrawRectangle(xa01, yt00, xa02 - 1, yt06 - 1, frameColor);
1044 osd->DrawEllipse (xa02, yt01, xa04 - 1, yt03 - 1, frameColor, -2);
1045 osd->DrawRectangle(xa02, yt00, xa05 - 1, yt01 - 1, frameColor);
1046 osd->DrawRectangle(xa06, yt00, xa07 - 1, yt01 - 1, frameColor);
1047 osd->DrawRectangle(xa08, yt00, xa08 + lineHeight / 2 - 1, yt01 - 1, frameColor);
1048 osd->DrawRectangle(xa08 + lineHeight / 2, yt00, xa09 - 1, yt00 + lineHeight / 2 - 1, clrTransparent);
1049 osd->DrawEllipse (xa08 + lineHeight / 2, yt00, xa09 - 1, yt01 - 1, frameColor, 5);
1050 // Center part:
1051 osd->DrawRectangle(xa00, yc00, xa02 - 1, yc11 - 1, frameColor);
1052 // Lower elbow:
1053 osd->DrawRectangle(xa00, yb10, xa02 - 1, yb11 - 1, frameColor);
1054 osd->DrawRectangle(xa00, yb11, xa01 - 1, yb15 - 1, clrTransparent);
1055 osd->DrawEllipse (xa00, yb11, xa01 - 1, yb15 - 1, frameColor, 3);
1056 osd->DrawRectangle(xa01, yb11, xa02 - 1, yb15 - 1, frameColor);
1057 osd->DrawEllipse (xa02, yb12, xa04 - 1, yb14 - 1, frameColor, -3);
1058 osd->DrawRectangle(xa02, yb14, xa05 - 1, yb15 - 1, frameColor);
1059 osd->DrawRectangle(xa08, yb14, xa08 + lineHeight / 2 - 1, yb15 - 1, frameColor);
1060 osd->DrawRectangle(xa08 + lineHeight / 2, yb14 + lineHeight / 2, xa09 - 1, yb15 - 1, clrTransparent);
1061 osd->DrawEllipse (xa08 + lineHeight / 2, yb14, xa09 - 1, yb15 - 1, frameColor, 5);
1062 osd->DrawText(xa00, yb10, "VDR", Theme.Color(clrMenuFrameFg), frameColor, tallFont, xa02 - xa00, yb11 - yb10, taTop | taRight | taBorder);
1063 // Color buttons:
1064 tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
1065 osd->DrawRectangle(xb00, yb14, xb01 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey0]));
1066 osd->DrawRectangle(xb04, yb14, xb05 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey1]));
1067 osd->DrawRectangle(xb08, yb14, xb09 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey2]));
1068 osd->DrawRectangle(xb12, yb14, xb13 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey3]));
1069}
1070
1072{
1073 cString s = DayDateTime();
1074 if (initial || !*lastDate || strcmp(s, lastDate)) {
1075 const cFont *font = cFont::GetFont(fontOsd);
1076 tColor ColorFg = Theme.Color(clrDateFg);
1077 tColor ColorBg = Theme.Color(clrDateBg);
1078 lastDate = s;
1079 const char *t = strrchr(s, ' ');
1080 osd->DrawText(xa00, yb01 - lineHeight, t, ColorFg, ColorBg, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1081 s.Truncate(t - s);
1082 osd->DrawText(xa00, yb00, s, ColorFg, ColorBg, font, xa02 - xa00, yb01 - yb00 - lineHeight, taTop | taRight | taBorder);
1083 }
1084}
1085
1087{
1088 if (yb02) {
1089 if (cVideoDiskUsage::HasChanged(lastDiskUsageState) || initial) { // must call HasChanged() first, or it shows an outdated value in the 'initial' case!
1090 const cFont *font = cFont::GetFont(fontOsd);
1091 int DiskUsage = cVideoDiskUsage::UsedPercent();
1092 bool DiskAlert = DiskUsage > DISKUSAGEALERTLIMIT;
1093 tColor ColorFg = DiskAlert ? Theme.Color(clrAlertFg) : Theme.Color(clrMenuFrameFg);
1094 tColor ColorBg = DiskAlert ? Theme.Color(clrAlertBg) : frameColor;
1095 if (initial || DiskAlert != lastDiskAlert)
1096 osd->DrawText(xa00, yb02, tr("DISK"), ColorFg, ColorBg, tinyFont, xa02 - xa00, yb03 - yb02, taTop | taLeft | taBorder);
1097 osd->DrawText(xa01, yb02, itoa(DiskUsage), ColorFg, ColorBg, font, xa02 - xa01, lineHeight, taBottom | taRight | taBorder);
1098 osd->DrawText(xa00, yb03 - lineHeight, cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60), ColorFg, ColorBg, font, xa02 - xa00, 0, taBottom | taRight | taBorder);
1099 lastDiskAlert = DiskAlert;
1100 }
1101 }
1102}
1103
1105{
1106 if (yb04) {
1107 tColor ColorFg = Theme.Color(clrMenuFrameFg);
1108 tColor ColorBg = frameColor;
1109 if (initial)
1110 osd->DrawText(xa00, yb04, tr("LOAD"), ColorFg, ColorBg, tinyFont, xa02 - xa00, yb05 - yb04, taTop | taLeft | taBorder);
1111 double SystemLoad;
1112 if (getloadavg(&SystemLoad, 1) > 0) {
1113 if (initial || SystemLoad != lastSystemLoad) {
1114 osd->DrawText(xa00, yb05 - lineHeight, cString::sprintf("%.1f", SystemLoad), ColorFg, ColorBg, cFont::GetFont(fontOsd), xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1115 lastSystemLoad = SystemLoad;
1116 }
1117 }
1118 }
1119}
1120
1122{
1123 tColor Color = Theme.Color(clrMenuMainBracket);
1124 osd->DrawRectangle(xm00, ym00, xm01 - 1, ym01 - 1, Color);
1125 osd->DrawRectangle(xm02, ym00, xm07 - 1, ym01 - 1, Color);
1126 osd->DrawEllipse (xm07, ym00, xm08 - 1, ym02 - 1, Color, 1);
1127 osd->DrawEllipse (xm06, ym01, xm07 - 1, ym02 - 1, Color, -1);
1128 osd->DrawRectangle(xm07, ym03, xm08 - 1, ym04 - 1, Color);
1129 osd->DrawEllipse (xm06, ym05, xm07 - 1, ym06 - 1, Color, -4);
1130 osd->DrawEllipse (xm07, ym05, xm08 - 1, ym07 - 1, Color, 4);
1131 osd->DrawRectangle(xm02, ym06, xm07 - 1, ym07 - 1, Color);
1132 osd->DrawRectangle(xm00, ym06, xm01 - 1, ym07 - 1, Color);
1133}
1134
1136{
1137 const cFont *font = cFont::GetFont(fontOsd);
1138 osd->DrawText (xs00, ys00, tr("TIMERS"), Theme.Color(clrMenuFrameFg), frameColor, font, xs01 - xs00, lineHeight, taBottom | taLeft | taBorder);
1139 osd->DrawRectangle(xs02, ys00, xs03 - 1, ys01 - 1, frameColor);
1140 osd->DrawEllipse (xs03, ys00, xs05 - 1, ys01 - 1, frameColor, 1);
1141 osd->DrawEllipse (xs03, ys01, xs04 - 1, ys02 - 1, frameColor, -1);
1142 osd->DrawRectangle(xs04, ys01, xs05 - 1, ys03 - 1, frameColor);
1143 osd->DrawRectangle(xs04, ys04, xs05 - 1, ys05 - 1, frameColor);
1144 osd->DrawText (xs10, ys00, tr("DEVICES"), Theme.Color(clrMenuFrameFg), frameColor, font, xs11 - xs10, lineHeight, taBottom | taRight | taBorder);
1145 osd->DrawRectangle(xs08, ys00, xs09 - 1, ys01 - 1, frameColor);
1146 osd->DrawEllipse (xs06, ys00, xs08 - 1, ys01 - 1, frameColor, 2);
1147 osd->DrawEllipse (xs07, ys01, xs08 - 1, ys02 - 1, frameColor, -2);
1148 osd->DrawRectangle(xs06, ys01, xs07 - 1, ys03 - 1, frameColor);
1149 osd->DrawRectangle(xs06, ys04, xs07 - 1, ys05 - 1, frameColor);
1150 osd->DrawRectangle(xs12, ys00, xs13 - 1, ys01 - 1, frameColor);
1151}
1152
1154{
1155 DrawDate();
1156 DrawDisk();
1157 DrawLoad();
1158 if (initial) {
1159 if (yb06)
1160 osd->DrawRectangle(xa00, yb06, xa02 - 1, yb07 - 1, frameColor);
1161 if (yb08) {
1162 const cFont *font = cFont::GetFont(fontOsd);
1163 osd->DrawRectangle(xa00, yb08, xa02 - 1, yb09 - 1, frameColor);
1164 osd->DrawText(xa00, yb09 - lineHeight, "LCARS", Theme.Color(clrMenuFrameFg), frameColor, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1165 }
1166 }
1167}
1168
1169void cSkinLCARSDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown)
1170{
1171 int x0, x1, tt, tb;
1172 tColor ClearColor;
1173 if (MenuCategory() == mcMain) {
1174 x0 = xm07;
1175 x1 = xm08;
1176 tt = ym03;
1177 tb = ym04;
1178 ClearColor = Theme.Color(clrMenuMainBracket);
1179 }
1180 else {
1181 x0 = xa02 + Gap;
1182 x1 = x0 + lineHeight / 2;
1183 tt = yc00;
1184 tb = yc11;
1185 ClearColor = Theme.Color(clrBackground);
1186 int d = TextFrame;
1187 if (CanScrollUp)
1188 osd->DrawBitmap(xa02 - bmArrowUp.Width() - d, yc00 + d, bmArrowUp, Theme.Color(clrMenuScrollbarArrow), frameColor);
1189 else
1190 osd->DrawRectangle(xa02 - bmArrowUp.Width() - d, yc00 + d, xa02 - d - 1, yc00 + d + bmArrowUp.Height() - 1, frameColor);
1191 if (CanScrollDown)
1192 osd->DrawBitmap(xa02 - bmArrowDown.Width() - d, yc11 - d - bmArrowDown.Height(), bmArrowDown, Theme.Color(clrMenuScrollbarArrow), frameColor);
1193 else
1194 osd->DrawRectangle(xa02 - bmArrowDown.Width() - d, yc11 - d - bmArrowDown.Height(), xa02 - d - 1, yc11 - d - 1, frameColor);
1195 }
1196 if (Total > 0 && Total > Shown) {
1197 int sw = x1 - x0;
1198 int sh = max(int((tb - tt) * double(Shown) / Total + 0.5), sw);
1199 int st = min(int(tt + (tb - tt) * double(Offset) / Total + 0.5), tb - sh);
1200 int sb = min(st + sh, tb);
1201 osd->DrawRectangle(x0, tt, x1 - 1, tb - 1, Theme.Color(clrMenuScrollbarTotal));
1202 osd->DrawRectangle(x0, st, x1 - 1, sb - 1, Theme.Color(clrMenuScrollbarShown));
1203 }
1204 else if (MenuCategory() != mcMain)
1205 osd->DrawRectangle(x0, tt, x1 - 1, tb - 1, ClearColor);
1206}
1207
1208void cSkinLCARSDisplayMenu::DrawTimer(const cTimer *Timer, int y, bool MultiRec)
1209{
1210 // The timer data:
1211 bool Alert = !Timer->Recording() && Timer->Pending();
1212 tColor ColorFg = Alert ? Theme.Color(clrAlertFg) : Theme.Color(clrTimerFg);
1213 tColor ColorBg = Alert ? Theme.Color(clrAlertBg) : Theme.Color(clrTimerBg);
1214 osd->DrawRectangle(xs00, y, xs03 - 1, y + lineHeight - 1, ColorBg);
1215 cString Date;
1216 if (Timer->Recording())
1217 Date = cString::sprintf("-%s", *TimeString(Timer->StopTimeEvent()));
1218 else {
1219 time_t Now = time(NULL);
1220 time_t StartTime = Timer->StartTimeEvent();
1221 cString Today = WeekDayName(Now);
1222 cString Time = TimeString(StartTime);
1223 cString Day = WeekDayName(StartTime);
1224 if (StartTime > Now + 6 * SECSINDAY)
1225 Date = DayDateTime(StartTime);
1226 else if (strcmp(Day, Today) != 0)
1227 Date = cString::sprintf("%s %s", *Day, *Time);
1228 else
1229 Date = Time;
1230 }
1231 if (Timer->Flags() & tfVps)
1232 Date = cString::sprintf("VPS %s", *Date);
1233 const cChannel *Channel = Timer->Channel();
1234 const cEvent *Event = Timer->Event();
1235 int d = max(TextFrame / 2, 1);
1236 if (Channel) {
1237 osd->DrawText(xs00 + d, y, Channel->Name(), ColorFg, ColorBg, tinyFont, xs03 - xs00 - d);
1238 osd->DrawText(xs03 - tinyFont->Width(Date) - d, y, Date, ColorFg, ColorBg, tinyFont);
1239 }
1240 if (Event)
1241 osd->DrawText(xs00 + d, y + lineHeight - tinyFont->Height(), Event->Title(), ColorFg, ColorBg, tinyFont, xs03 - xs00 - 2 * d);
1242 // The remote timer indicator:
1243 if (Timer->Remote())
1244 osd->DrawRectangle(xs00 - (lineHeight - Gap) / 2, y, xs00 - Gap - 1, y + lineHeight - 1, Timer->Recording() ? Theme.Color(clrMenuTimerRecording) : ColorBg);
1245 // The timer recording indicator:
1246 else if (Timer->Recording())
1247 osd->DrawRectangle(xs03 + Gap, y - (MultiRec ? Gap : 0), xs04 - Gap / 2 - 1, y + lineHeight - 1, Theme.Color(clrMenuTimerRecording));
1248}
1249
1251{
1252 if (const cTimers *Timers = cTimers::GetTimersRead(timersStateKey)) {
1253 deviceRecording.Clear();
1254 const cFont *font = cFont::GetFont(fontOsd);
1255 osd->DrawRectangle(xs00 - (lineHeight - Gap) / 2, ys04, xs04 - 1, ys05 - 1, Theme.Color(clrBackground));
1256 osd->DrawRectangle(xs07, ys04, xs13 - 1, ys05 - 1, Theme.Color(clrBackground));
1257 cSortedTimers SortedTimers(Timers);
1258 cVector<int> FreeDeviceSlots;
1259 int NumDevices = 0;
1260 int y = ys04;
1261 // Timers and recording devices:
1263 while (1) {
1264 int NumTimers = 0;
1265 const cDevice *Device = NULL;
1266 for (int i = 0; i < SortedTimers.Size(); i++) {
1267 if (y + lineHeight > ys05)
1268 break;
1269 if (const cTimer *Timer = SortedTimers[i]) {
1270 if (Timer->IsPatternTimer())
1271 SortedTimers[i] = NULL;
1272 else if (Timer->Recording()) {
1273 if (Timer->Remote()) {
1274 if (!Device && Timer->HasFlags(tfActive)) {
1275 DrawTimer(Timer, y, false);
1276 FreeDeviceSlots.Append(y);
1277 y += lineHeight + Gap;
1278 }
1279 else
1280 continue;
1281 }
1282 else if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(Timer)) {
1283 if (!Device || Device == RecordControl->Device()) {
1284 DrawTimer(Timer, y, NumTimers > 0);
1285 NumTimers++;
1286 if (!Device) {
1287 Device = RecordControl->Device();
1288 deviceOffset[Device->DeviceNumber()] = y;
1289 deviceRecording[Device->DeviceNumber()] = true;
1290 NumDevices++;
1291 }
1292 else
1293 FreeDeviceSlots.Append(y);
1294 y += lineHeight + Gap;
1295 }
1296 else
1297 continue;
1298 }
1299 SortedTimers[i] = NULL;
1300 }
1301 else if (!Device && Timer->HasFlags(tfActive)) {
1302 DrawTimer(Timer, y, false);
1303 FreeDeviceSlots.Append(y);
1304 y += lineHeight + Gap;
1305 SortedTimers[i] = NULL;
1306 }
1307 }
1308 }
1309 if (!Device)
1310 break;
1311 }
1312 // Devices currently not recording:
1313 int Slot = 0;
1314 for (int i = 0; i < cDevice::NumDevices(); i++) {
1315 if (const cDevice *Device = cDevice::GetDevice(i)) {
1316 if (Device->NumProvidedSystems()) {
1317 if (!deviceRecording[Device->DeviceNumber()]) {
1318 if (Slot < FreeDeviceSlots.Size()) {
1319 y = FreeDeviceSlots[Slot];
1320 Slot++;
1321 }
1322 if (y + lineHeight > ys05)
1323 break;
1324 deviceOffset[Device->DeviceNumber()] = y;
1325 y += lineHeight + Gap;
1326 NumDevices++;
1327 }
1328 }
1329 }
1330 }
1331 // Total number of active timers:
1332 int NumTimers = 0;
1333 for (const cTimer *Timer = Timers->First(); Timer; Timer = Timers->Next(Timer)) {
1334 if (Timer->HasFlags(tfActive))
1335 NumTimers++;
1336 }
1337 osd->DrawText(xs02, ys00, itoa(NumTimers), Theme.Color(clrMenuFrameFg), frameColor, font, xs03 - xs02, ys01 - ys00, taBottom | taLeft | taBorder);
1338 osd->DrawText(xs08, ys00, itoa(NumDevices), Theme.Color(clrMenuFrameFg), frameColor, font, xs09 - xs08, ys01 - ys00, taBottom | taRight | taBorder);
1340 initial = true; // forces redrawing of devices
1341 timersStateKey.Remove();
1342 }
1343}
1344
1346{
1347 int dn = Device->DeviceNumber();
1348 int y = deviceOffset[dn];
1349 if (y + lineHeight <= ys05) {
1350 if (DrawDeviceData(osd, Device, xs08, y, xs11, y + lineHeight, xs, tinyFont, lastDeviceType[dn], lastCamSlot[dn], initial)) {
1351 // Make sure signal meters are redrawn:
1352 lastSignalStrength[dn] = -1;
1353 lastSignalQuality[dn] = -1;
1355 }
1356 // The device recording indicator:
1357 if (deviceRecording[dn])
1358 osd->DrawRectangle(xs07 + Gap / 2, y, xs08 - Gap - 1, y + lineHeight - 1, Theme.Color(clrMenuDeviceRecording));
1359 }
1360}
1361
1363{
1364 for (int i = 0; i < cDevice::NumDevices(); i++) {
1365 if (const cDevice *Device = cDevice::GetDevice(i)) {
1366 if (Device->NumProvidedSystems())
1367 DrawDevice(Device);
1368 }
1369 }
1370}
1371
1373{
1374 cDevice *Device = cDevice::PrimaryDevice();
1375 int y = -1;
1376 bool Transferring = Device->Transferring();
1377 if (!Device->Replaying() || Transferring)
1379 if (initial || y != lastLiveIndicatorY || Transferring != lastLiveIndicatorTransferring) {
1380 if (lastLiveIndicatorY >= 0)
1381 osd->DrawRectangle(xs12, lastLiveIndicatorY, xs13 - 1, lastLiveIndicatorY + lineHeight - 1, Theme.Color(clrBackground));
1382 if (y > 0) {
1383 tColor ColorBg = Theme.Color(clrChannelFrameBg);
1384 osd->DrawRectangle(xs12, y, xs12 + lineHeight / 2 - 1, y + lineHeight - 1, ColorBg);
1385 osd->DrawEllipse (xs12 + lineHeight / 2, y, xs13 - 1, y + lineHeight - 1, ColorBg, 5);
1386 if (Transferring) {
1387 int w = bmTransferMode.Width();
1388 int h = bmTransferMode.Height();
1389 int b = w * w + h * h; // the diagonal of the bitmap (squared)
1390 int c = lineHeight * lineHeight; // the diameter of the circle (squared)
1391 const cBitmap *bm = &bmTransferMode;
1392 if (b > c) {
1393 // the bitmap doesn't fit, so scale it down:
1394 double f = sqrt(double(c) / (2 * b));
1395 bm = bmTransferMode.Scaled(f, f);
1396 }
1397 osd->DrawBitmap((xs12 + xs13 - bm->Width()) / 2, y + (lineHeight - bm->Height()) / 2, *bm, Theme.Color(clrChannelFrameFg), ColorBg);
1398 if (bm != &bmTransferMode)
1399 delete bm;
1400 }
1401 }
1403 lastLiveIndicatorTransferring = Transferring;
1404 }
1405}
1406
1408{
1409 time_t Now = time(NULL);
1411 for (int i = 0; i < cDevice::NumDevices(); i++) {
1412 if (const cDevice *Device = cDevice::GetDevice(i)) {
1413 if (Device->NumProvidedSystems()) {
1414 if (int y = deviceOffset[i])
1416 }
1417 }
1418 }
1419 lastSignalDisplay = Now;
1420 }
1421}
1422
1424{
1425 if (lastMode != cmLive) {
1426 initial = true;
1427 lastMode = cmLive;
1428 }
1429 if (initial) {
1430 DrawMainFrameUpper(Theme.Color(clrChannelFrameBg));
1431 osd->DrawText(xd00, yd00, tr("LIVE"), Theme.Color(clrChannelFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder);
1432 }
1433 if (!Channel)
1434 return;
1435 if (initial || Channel != lastChannel || strcmp(Channel->Name(), lastChannelName)) {
1436 osd->DrawText(xa00, yt00, itoa(Channel->Number()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), tallFont, xa02 - xa00, yt02 - yt00, taTop | taRight | taBorder);
1437 osd->DrawText(xa03, yt00, Channel->Name(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
1438 int x = xa00 + (yc03 - yc02); // compensate for the arc
1439 osd->DrawText(x, yc00, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), cFont::GetFont(fontOsd), xa02 - x, yc03 - yc00, taTop | taRight | taBorder);
1440 lastChannel = Channel;
1441 lastChannelName = Channel->Name();
1442 DrawSeen(0, 0);
1443 }
1444 // The current programme:
1446 if (const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
1447 const cEvent *Event = Schedule->GetPresentEvent();
1448 if (initial || Event != lastEvent) {
1449 DrawInfo(Event, true);
1450 lastEvent = Event;
1451 lastSeen = -1;
1452 }
1453 int Current = 0;
1454 int Total = 0;
1455 if (Event) {
1456 time_t t = time(NULL);
1457 if (t > Event->StartTime())
1458 Current = t - Event->StartTime();
1459 Total = Event->Duration();
1460 }
1461 DrawSeen(Current, Total);
1462 }
1463}
1464
1466{
1467 if (lastMode != cmPlay) {
1468 initial = true;
1469 lastMode = cmPlay;
1470 }
1471 if (initial) {
1472 DrawMainFrameUpper(Theme.Color(clrReplayFrameBg));
1473 osd->DrawText(xd00, yd00, tr("PLAY"), Theme.Color(clrReplayFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder);
1474 }
1475 // The current progress:
1476 int Current = 0;
1477 int Total = 0;
1478 if (Control->GetIndex(Current, Total))
1479 DrawSeen(Current, Total);
1480 // The current programme:
1481 if (const cRecording *Recording = Control->GetRecording()) {
1482 if (initial || Recording != lastRecording) {
1483 const cFont *font = cFont::GetFont(fontOsd);
1484 if (const cRecordingInfo *Info = Recording->Info()) {
1485 osd->DrawText(xa03, yt00, Info->ChannelName(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
1486 DrawInfo(Info->GetEvent(), false);
1487 }
1488 else
1489 osd->DrawText(xa03, yt04, Recording->Name(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), font, xd00 - xa03, 0, taTop | taLeft);
1490 osd->DrawText(xa00, yt04, ShortDateString(Recording->Start()), Theme.Color(clrReplayFrameFg), Theme.Color(clrReplayFrameBg), font, xa02 - xa00, 0, taTop | taRight | taBorder);
1491 osd->DrawText(xa00, yt06 - lineHeight, TimeString(Recording->Start()), Theme.Color(clrReplayFrameFg), Theme.Color(clrReplayFrameBg), font, xa02 - xa00, 0, taBottom | taRight | taBorder);
1492 lastRecording = Recording;
1493 }
1494 }
1495 else {
1496 cString Header = Control->GetHeader();
1497 if (!*lastHeader || strcmp(Header, lastHeader)) {
1498 osd->DrawText(xa03, yt00, Header, Theme.Color(clrMenuText), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
1499 lastHeader = Header;
1500 }
1501 }
1502}
1503
1504void cSkinLCARSDisplayMenu::DrawInfo(const cEvent *Event, bool WithTime)
1505{
1506 if (Event) {
1507 const cFont *font = cFont::GetFont(fontOsd);
1508 int y = yt04;
1509 osd->DrawText(xa03, y, Event->Title(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), font, xd00 - xa03 - lineHeight, lineHeight, taBottom | taLeft);
1510 y += lineHeight;
1511 osd->DrawText(xa03, y, Event->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xd00 - xa03 - lineHeight, lineHeight, taTop | taLeft);
1512 if (WithTime) {
1513 osd->DrawText(xa00, yt04, Event->GetTimeString(), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), font, xa02 - xa00, lineHeight, taTop | taRight | taBorder);
1514 osd->DrawText(xa00, yt06 - lineHeight, cString::sprintf("-%s", *Event->GetEndTimeString()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1515 }
1516 }
1517}
1518
1520{
1521 int Seen = (Total > 0) ? min(xm08 - xm02, int((xm08 - xm02) * double(Current) / Total)) : 0;
1522 if (initial || Seen != lastSeen) {
1523 int y0 = yc04 - ShowSeenExtent;
1524 int y1 = yc04 + lineHeight / 2 - Gap / 2;
1525 osd->DrawRectangle(xm02, y0, xm02 + Seen - 1, y1 - 1, Theme.Color(clrSeen));
1526 osd->DrawRectangle(xm02 + Seen, y0, xm08 - 1, y1 - 1, Theme.Color(clrBackground));
1527 lastSeen = Seen;
1528 }
1529}
1530
1532{
1533 if (textScroller.CanScroll())
1534 DrawScrollbar(textScroller.Total(), textScroller.Offset(), textScroller.Shown(), textScroller.CanScrollUp(), textScroller.CanScrollDown());
1535}
1536
1537void cSkinLCARSDisplayMenu::Scroll(bool Up, bool Page)
1538{
1539 cSkinDisplayMenu::Scroll(Up, Page);
1541}
1542
1544{
1545 if (MenuCategory() == mcMain)
1546 return (ym04 - ym03) / lineHeight;
1547 else
1548 return (yb13 - yt02) / lineHeight;
1549}
1550
1552{
1553 textScroller.Reset();
1554 osd->DrawRectangle(xi00, yi00, xi03 - 1, yi01 - 1, Theme.Color(clrBackground));
1555}
1556
1557void cSkinLCARSDisplayMenu::SetTitle(const char *Title)
1558{
1559 if (MenuCategory() != mcMain) {
1560 const cFont *font = cFont::GetFont(fontOsd);
1561 int w = min(font->Width(Title), xa07 - xa06 - Gap);
1562 osd->DrawRectangle(xa06, yt00, xa07 - w - Gap - 1, yt01 - 1, frameColor);
1563 osd->DrawText(xa07 - w - Gap, yt00, Title, Theme.Color(clrMenuTitle), Theme.Color(clrBackground), font, w + Gap, yt01 - yt00, taRight);
1564 }
1565}
1566
1567void cSkinLCARSDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
1568{
1569 const char *lutText[] = { Red, Green, Yellow, Blue };
1570 tColor lutFg[] = { clrButtonRedFg, clrButtonGreenFg, clrButtonYellowFg, clrButtonBlueFg };
1571 tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
1572 const cFont *font = cFont::GetFont(fontSml);
1573 if (MenuCategory() == mcMain) {
1574 DrawMainButton(lutText[Setup.ColorKey0], xd00, xd01, xd02, xd03, yd02, yd03, Theme.Color(lutFg[Setup.ColorKey0]), Theme.Color(lutBg[Setup.ColorKey0]), font);
1575 DrawMainButton(lutText[Setup.ColorKey1], xd04, xd05, xd06, xd07, yd02, yd03, Theme.Color(lutFg[Setup.ColorKey1]), Theme.Color(lutBg[Setup.ColorKey1]), font);
1576 DrawMainButton(lutText[Setup.ColorKey2], xd00, xd01, xd02, xd03, yd04, yd05, Theme.Color(lutFg[Setup.ColorKey2]), Theme.Color(lutBg[Setup.ColorKey2]), font);
1577 DrawMainButton(lutText[Setup.ColorKey3], xd04, xd05, xd06, xd07, yd04, yd05, Theme.Color(lutFg[Setup.ColorKey3]), Theme.Color(lutBg[Setup.ColorKey3]), font);
1578 }
1579 else {
1580 int h = yb15 - yb14;
1581 osd->DrawText(xb02, yb14, lutText[Setup.ColorKey0], Theme.Color(lutFg[Setup.ColorKey0]), Theme.Color(lutBg[Setup.ColorKey0]), font, xb03 - xb02, h, taLeft | taBorder);
1582 osd->DrawText(xb06, yb14, lutText[Setup.ColorKey1], Theme.Color(lutFg[Setup.ColorKey1]), Theme.Color(lutBg[Setup.ColorKey1]), font, xb07 - xb06, h, taLeft | taBorder);
1583 osd->DrawText(xb10, yb14, lutText[Setup.ColorKey2], Theme.Color(lutFg[Setup.ColorKey2]), Theme.Color(lutBg[Setup.ColorKey2]), font, xb11 - xb10, h, taLeft | taBorder);
1584 osd->DrawText(xb14, yb14, lutText[Setup.ColorKey3], Theme.Color(lutFg[Setup.ColorKey3]), Theme.Color(lutBg[Setup.ColorKey3]), font, xb15 - xb14, h, taLeft | taBorder);
1585 }
1586}
1587
1589{
1590 if (Text) {
1591 osd->SaveRegion(xb00, yb14, xb15 - 1, yb15 - 1);
1592 osd->DrawText(xb00, yb14, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), xb15 - xb00, yb15 - yb14, taCenter);
1593 }
1594 else
1595 osd->RestoreRegion();
1596}
1597
1598void cSkinLCARSDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
1599{
1600 int y = yi00 + Index * lineHeight;
1601 tColor ColorFg, ColorBg;
1602 if (Current) {
1603 if (TwoColors) {
1604 ColorFg = Theme.Color(clrBackground);
1605 ColorBg = Theme.Color(clrMenuFrameBg);
1606 }
1607 else {
1608 ColorFg = Theme.Color(clrMenuItemCurrentFg);
1609 ColorBg = Theme.Color(clrMenuItemCurrentBg);
1610 }
1611 osd->DrawRectangle(xi00, y, xi01 - 1, y + lineHeight - 1, ColorBg);
1612 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, y + lineHeight - 1, ColorBg);
1613 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, y + lineHeight - 1, ColorBg, 5);
1614 currentIndex = Index;
1615 }
1616 else {
1617 ColorFg = Theme.Color(Selectable ? clrMenuItemSelectable : clrMenuItemNonSelectable);
1618 ColorBg = Theme.Color(clrBackground);
1619 if (currentIndex == Index)
1620 osd->DrawRectangle(xi00, y, xi03 - 1, y + lineHeight - 1, Theme.Color(clrBackground));
1621 }
1622 const cFont *font = cFont::GetFont(fontOsd);
1623 for (int i = 0; i < MaxTabs; i++) {
1624 const char *s = GetTabbedText(Text, i);
1625 if (s) {
1626 int xt = xi00 + TextSpacing + Tab(i);
1627 osd->DrawText(xt, y, s, ColorFg, ColorBg, font, xi01 - xt);
1628 }
1629 if (!Tab(i + 1))
1630 break;
1631 }
1633}
1634
1635void cSkinLCARSDisplayMenu::SetScrollbar(int Total, int Offset)
1636{
1637 DrawScrollbar(Total, Offset, MaxItems(), Offset > 0, Offset + MaxItems() < Total);
1638}
1639
1641{
1642 if (!Event)
1643 return;
1644 const cFont *font = cFont::GetFont(fontOsd);
1645 int xl = xi00;
1646 int y = yi00;
1647 cTextScroller ts;
1648 cString t = cString::sprintf("%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
1649 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, t, font, Theme.Color(clrEventTime), Theme.Color(clrBackground));
1650 if (Event->Vps() && Event->Vps() != Event->StartTime()) {
1651 cString buffer = cString::sprintf(" VPS: %s ", *Event->GetVpsString());
1652 const cFont *font = cFont::GetFont(fontSml);
1653 int w = font->Width(buffer);
1654 osd->DrawText(xi01 - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1655 int yb = y + font->Height();
1656 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor);
1657 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5);
1658 }
1659 y += ts.Height();
1660 if (Event->ParentalRating()) {
1661 cString buffer = cString::sprintf(" %s ", *Event->GetParentalRatingString());
1662 const cFont *font = cFont::GetFont(fontSml);
1663 int w = font->Width(buffer);
1664 osd->DrawText(xi01 - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1665 int yb = y + font->Height();
1666 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor);
1667 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5);
1668 }
1669 y += font->Height();
1670 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Event->Title(), font, Theme.Color(clrEventTitle), Theme.Color(clrBackground));
1671 y += ts.Height();
1672 if (!isempty(Event->ShortText())) {
1673 const cFont *font = cFont::GetFont(fontSml);
1674 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Event->ShortText(), font, Theme.Color(clrEventShortText), Theme.Color(clrBackground));
1675 y += ts.Height();
1676 }
1677 y += font->Height();
1678 if (!isempty(Event->Description())) {
1679 int yt = y;
1680 int yb = yi01;
1681 textScroller.Set(osd, xl, yt, xi01 - xl, yb - yt, Event->Description(), font, Theme.Color(clrEventDescription), Theme.Color(clrBackground));
1683 }
1684}
1685
1687{
1688 if (!Recording)
1689 return;
1690 const cRecordingInfo *Info = Recording->Info();
1691 const cFont *font = cFont::GetFont(fontOsd);
1692 int xl = xi00;
1693 int y = yi00;
1694 cTextScroller ts;
1695 cString t = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), Info->ChannelName() ? Info->ChannelName() : "");
1696 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, t, font, Theme.Color(clrEventTime), Theme.Color(clrBackground));
1697 y += ts.Height();
1698 int xt = xi01;
1699 if (Info->GetEvent()->ParentalRating()) {
1700 cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString());
1701 const cFont *font = cFont::GetFont(fontSml);
1702 int w = font->Width(buffer);
1703 osd->DrawText(xt - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1704 xt -= w + xi02 - xi01;
1705 }
1706 if (Info->Errors() > 0) {
1707 // TRANSLATORS: note the plural/singular!
1708 cString buffer = cString::sprintf(" %d %s ", Info->Errors(), Info->Errors() > 1 ? tr("errors") : tr("error"));
1709 const cFont *font = cFont::GetFont(fontSml);
1710 int w = font->Width(buffer);
1711 osd->DrawText(xt - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1712 xt -= w + xi02 - xi01;
1713 }
1714 if (xt != xi01) {
1715 const cFont *font = cFont::GetFont(fontSml);
1716 int yb = y + font->Height();
1717 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor);
1718 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5);
1719 }
1720 y += font->Height();
1721 const char *Title = Info->Title();
1722 if (isempty(Title))
1723 Title = Recording->Name();
1724 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Title, font, Theme.Color(clrEventTitle), Theme.Color(clrBackground));
1725 y += ts.Height();
1726 if (!isempty(Info->ShortText())) {
1727 const cFont *font = cFont::GetFont(fontSml);
1728 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Info->ShortText(), font, Theme.Color(clrEventShortText), Theme.Color(clrBackground));
1729 y += ts.Height();
1730 }
1731 y += font->Height();
1732 if (!isempty(Info->Description())) {
1733 int yt = y;
1734 int yb = yi01;
1735 cString d = Info->Description();
1736 cString f = Info->FrameParams();
1737 if (*f) {
1738 d.Append("\n\n");
1739 d.Append(f);
1740 }
1741 textScroller.Set(osd, xl, yt, xi01 - xl, yb - yt, d, font, Theme.Color(clrEventDescription), Theme.Color(clrBackground));
1743 }
1744}
1745
1746void cSkinLCARSDisplayMenu::SetText(const char *Text, bool FixedFont)
1747{
1748 textScroller.Set(osd, xi00, yi00, GetTextAreaWidth(), yi01 - yi00, Text, GetTextAreaFont(FixedFont), Theme.Color(clrMenuText), Theme.Color(clrBackground));
1750}
1751
1753{
1754 return xi01 - xi00;
1755}
1756
1758{
1759 const cFont *font = cFont::GetFont(FixedFont ? fontFix : fontOsd);
1760 //XXX -> make a way to let the text define which font to use
1761 return font;
1762}
1763
1765{
1766 if (MenuCategory() == mcMain) {
1767 cDevice *Device = cDevice::PrimaryDevice();
1768 cMutexLock ControlMutexLock;
1769 if (!Device->Replaying() || Device->Transferring()) {
1771 const cChannel *Channel = Channels->GetByNumber(cDevice::PrimaryDevice()->CurrentChannel());
1772 DrawLive(Channel);
1773 }
1774 else if (cControl *Control = cControl::Control(ControlMutexLock, true))
1775 DrawPlay(Control);
1776 DrawTimers();
1777 DrawDevices();
1779 DrawSignals();
1780 }
1782 osd->Flush();
1783 initial = false;
1784}
1785
1786// --- cSkinLCARSDisplayReplay -----------------------------------------------
1787
1789private:
1800 void DrawDate(void);
1801 void DrawTrack(void);
1802public:
1803 cSkinLCARSDisplayReplay(bool ModeOnly);
1804 virtual ~cSkinLCARSDisplayReplay();
1805 virtual void SetRecording(const cRecording *Recording);
1806 virtual void SetTitle(const char *Title);
1807 virtual void SetMode(bool Play, bool Forward, int Speed);
1808 virtual void SetProgress(int Current, int Total);
1809 virtual void SetCurrent(const char *Current);
1810 virtual void SetTotal(const char *Total);
1811 virtual void SetJump(const char *Jump);
1812 virtual void SetMessage(eMessageType Type, const char *Text);
1813 virtual void Flush(void);
1814 };
1815
1817{
1818 const cFont *font = cFont::GetFont(fontOsd);
1819 modeOnly = ModeOnly;
1820 lineHeight = font->Height();
1821 frameColor = Theme.Color(clrReplayFrameBg);
1822 lastCurrentWidth = 0;
1823 lastTotalWidth = 0;
1824 memset(&lastTrackId, 0, sizeof(lastTrackId));
1825 int d = 5 * lineHeight;
1826 xp00 = 0;
1827 xp01 = xp00 + d / 2;
1828 xp02 = xp00 + d;
1829 xp03 = xp02 + lineHeight;
1830 xp04 = xp02 + d / 4;
1831 xp05 = xp02 + d;
1832 xp06 = xp05 + Gap;
1833 xp15 = cOsd::OsdWidth();
1834 xp14 = xp15 - lineHeight;
1835 xp13 = xp14 - Gap;
1836 xp07 = (xp15 + xp00) / 2;
1837 xp08 = xp07 + Gap;
1838 xp09 = xp08 + lineHeight;
1839 xp10 = xp09 + Gap;
1840 xp11 = (xp10 + xp13 + Gap) / 2;
1841 xp12 = xp11 + Gap;
1842
1843 yp00 = 0;
1844 yp01 = yp00 + 2 * lineHeight;
1845 yp02 = yp01 + Gap;
1846 yp03 = yp02 + 2 * lineHeight;
1847
1848 yp04 = yp03 + Gap;
1849 yp09 = yp04 + 3 * lineHeight + Gap / 2;
1850 yp08 = yp09 - lineHeight;
1851 yp07 = yp08 - lineHeight;
1852 yp06 = yp08 - d / 4;
1853 yp05 = yp09 - d / 2;
1854
1856 osd->DrawRectangle(xp00, yp00, xp15 - 1, yp09 - 1, modeOnly ? clrTransparent : Theme.Color(clrBackground));
1857 // Rectangles:
1858 if (!modeOnly)
1859 osd->DrawRectangle(xp00, yp00, xp02 - 1, yp01 - 1, frameColor);
1860 osd->DrawRectangle(xp00, yp02, xp02 - 1, yp03 - 1, frameColor);
1861 if (!modeOnly) {
1862 // Elbow:
1863 osd->DrawRectangle(xp00, yp04, xp01 - 1, yp05 - 1, frameColor);
1864 osd->DrawRectangle(xp00, yp05, xp01 - 1, yp09 - 1, clrTransparent);
1865 osd->DrawEllipse (xp00, yp05, xp01 - 1, yp09 - 1, frameColor, 3);
1866 osd->DrawRectangle(xp01, yp04, xp02 - 1, yp09 - 1, frameColor);
1867 osd->DrawEllipse (xp02, yp06, xp04 - 1, yp08 - 1, frameColor, -3);
1868 osd->DrawRectangle(xp02, yp08, xp05 - 1, yp09 - 1, frameColor);
1869 // Status area:
1870 osd->DrawRectangle(xp06, yp08, xp07 - 1, yp09 - 1, frameColor);
1871 osd->DrawRectangle(xp08, yp08, xp09 - 1, yp09 - 1, frameColor);
1872 osd->DrawRectangle(xp10, yp08, xp11 - 1, yp09 - 1, frameColor);
1873 osd->DrawRectangle(xp12, yp08, xp13 - 1, yp09 - 1, Theme.Color(clrDateBg));
1874 osd->DrawRectangle(xp14, yp08, xp14 + lineHeight / 2 - 1, yp09 - 1, frameColor);
1875 osd->DrawRectangle(xp14 + lineHeight / 2, yp08 + lineHeight / 2, xp15 - 1, yp09 - 1, clrTransparent);
1876 osd->DrawEllipse (xp14 + lineHeight / 2, yp08, xp15 - 1, yp09 - 1, frameColor, 5);
1877 }
1878}
1879
1884
1886{
1887 cString s = DayDateTime();
1888 if (!*lastDate || strcmp(s, lastDate)) {
1889 osd->DrawText(xp12, yp08, s, Theme.Color(clrDateFg), Theme.Color(clrDateBg), cFont::GetFont(fontOsd), xp13 - xp12, lineHeight, taRight | taBorder);
1890 lastDate = s;
1891 }
1892}
1893
1895{
1896 cDevice *Device = cDevice::PrimaryDevice();
1897 const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
1898 if (Track ? strcmp(lastTrackId.description, Track->description) : *lastTrackId.description) {
1899 osd->DrawText(xp03, yp04, Track ? Track->description : "", Theme.Color(clrTrackName), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xp07 - xp03);
1900 strn0cpy(lastTrackId.description, Track ? Track->description : "", sizeof(lastTrackId.description));
1901 }
1902}
1903
1905{
1906 const cRecordingInfo *RecordingInfo = Recording->Info();
1907 SetTitle(RecordingInfo->Title());
1908 osd->DrawText(xp03, yp01 - lineHeight, RecordingInfo->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xp13 - xp03);
1909 osd->DrawText(xp00, yp00, ShortDateString(Recording->Start()), Theme.Color(clrReplayFrameFg), frameColor, cFont::GetFont(fontOsd), xp02 - xp00, 0, taTop | taRight | taBorder);
1910 osd->DrawText(xp00, yp01 - lineHeight, TimeString(Recording->Start()), Theme.Color(clrReplayFrameFg), frameColor, cFont::GetFont(fontOsd), xp02 - xp00, 0, taBottom | taRight | taBorder);
1911}
1912
1914{
1915 osd->DrawText(xp03, yp00, Title, Theme.Color(clrEventTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xp13 - xp03);
1916}
1917
1918static const char *const *ReplaySymbols[2][2][5] = {
1919 { { pause_xpm, srew_xpm, srew1_xpm, srew2_xpm, srew3_xpm },
1920 { pause_xpm, sfwd_xpm, sfwd1_xpm, sfwd2_xpm, sfwd3_xpm }, },
1921 { { play_xpm, frew_xpm, frew1_xpm, frew2_xpm, frew3_xpm },
1922 { play_xpm, ffwd_xpm, ffwd1_xpm, ffwd2_xpm, ffwd3_xpm } }
1923 };
1924
1925void cSkinLCARSDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
1926{
1927 Speed = constrain(Speed, -1, 3);
1928 cBitmap bm(ReplaySymbols[Play][Forward][Speed + 1]);
1929 osd->DrawBitmap(xp01 - bm.Width() / 2, (yp02 + yp03 - bm.Height()) / 2, bm, Theme.Color(clrReplayFrameFg), frameColor);
1930}
1931
1933{
1934 cProgressBar pb(xp13 - xp03, lineHeight, Current, Total, marks, errors, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent), Theme.Color(clrReplayProgressError));
1935 osd->DrawBitmap(xp03, yp02, pb);
1936}
1937
1939{
1940 const cFont *font = cFont::GetFont(fontOsd);
1941 int w = font->Width(Current);
1942 osd->DrawText(xp03, yp03 - lineHeight, Current, Theme.Color(clrReplayPosition), Theme.Color(clrBackground), font, max(lastCurrentWidth, w), 0, taLeft);
1943 lastCurrentWidth = w;
1944}
1945
1947{
1948 const cFont *font = cFont::GetFont(fontOsd);
1949 int w = font->Width(Total);
1950 osd->DrawText(xp13 - w, yp03 - lineHeight, Total, Theme.Color(clrReplayPosition), Theme.Color(clrBackground), font, max(lastTotalWidth, w), 0, taRight);
1951 lastTotalWidth = w;
1952}
1953
1955{
1956 osd->DrawText(xp06, yp08, Jump, Theme.Color(clrReplayJumpFg), Jump ? Theme.Color(clrReplayJumpBg) : frameColor, cFont::GetFont(fontOsd), xp07 - xp06, 0, taCenter);
1957}
1958
1960{
1961 if (Text) {
1962 osd->SaveRegion(xp06, yp08, xp13 - 1, yp09 - 1);
1963 osd->DrawText(xp06, yp08, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), xp13 - xp06, yp09 - yp08, taCenter);
1964 }
1965 else
1966 osd->RestoreRegion();
1967}
1968
1970{
1971 if (!modeOnly) {
1972 DrawDate();
1973 DrawTrack();
1974 }
1975 osd->Flush();
1976}
1977
1978// --- cSkinLCARSDisplayVolume -----------------------------------------------
1979
1981private:
1983 int x0, x1, x2, x3, x4, x5, x6, x7;
1984 int y0, y1;
1986 int mute;
1987public:
1989 virtual ~cSkinLCARSDisplayVolume();
1990 virtual void SetVolume(int Current, int Total, bool Mute);
1991 virtual void Flush(void);
1992 };
1993
1995{
1996 const cFont *font = cFont::GetFont(fontOsd);
1997 int lineHeight = font->Height();
1998 frameColor = Theme.Color(clrVolumeFrame);
1999 mute = -1;
2000 x0 = 0;
2001 x1 = lineHeight / 2;
2002 x2 = lineHeight;
2003 x3 = x2 + Gap;
2004 x7 = cOsd::OsdWidth();
2005 x6 = x7 - lineHeight / 2;
2006 x5 = x6 - lineHeight / 2;
2007 x4 = x5 - Gap;
2008 y0 = 0;
2009 y1 = lineHeight;
2010 osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1, x0, y0, x7 - 1, y1 - 1);
2011 osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, Theme.Color(clrBackground));
2012 osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
2013 osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
2014 osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
2015 osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
2016 osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
2017 osd->DrawRectangle(x6, y0, x7 - 1, y1 - 1, clrTransparent);
2018 osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
2019}
2020
2025
2026void cSkinLCARSDisplayVolume::SetVolume(int Current, int Total, bool Mute)
2027{
2028 int xl = x3 + TextSpacing;
2029 int xr = x4 - TextSpacing;
2030 int yt = y0 + TextFrame;
2031 int yb = y1 - TextFrame;
2032 if (mute != Mute) {
2033 osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
2034 mute = Mute;
2035 }
2036 cBitmap bm(Mute ? mute_xpm : volume_xpm);
2037 osd->DrawBitmap(xl, y0 + (y1 - y0 - bm.Height()) / 2, bm, Theme.Color(clrVolumeSymbol), frameColor);
2038 if (!Mute) {
2039 xl += bm.Width() + TextSpacing;
2040 int w = (y1 - y0) / 3;
2041 int d = TextFrame;
2042 int n = (xr - xl + d) / (w + d);
2043 int x = xr - n * (w + d);
2044 tColor Color = Theme.Color(clrVolumeBarLower);
2045 for (int i = 0; i < n; i++) {
2046 if (Total * i >= Current * n)
2047 Color = Theme.Color(clrVolumeBarUpper);
2048 osd->DrawRectangle(x, yt, x + w - 1, yb - 1, Color);
2049 x += w + d;
2050 }
2051 }
2052}
2053
2055{
2056 osd->Flush();
2057}
2058
2059// --- cSkinLCARSDisplayTracks -----------------------------------------------
2060
2062private:
2070 void SetItem(const char *Text, int Index, bool Current);
2071public:
2072 cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
2073 virtual ~cSkinLCARSDisplayTracks();
2074 virtual void SetTrack(int Index, const char * const *Tracks);
2075 virtual void SetAudioChannel(int AudioChannel);
2076 virtual void Flush(void);
2077 };
2078
2082
2083cSkinLCARSDisplayTracks::cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
2084{
2085 const cFont *font = cFont::GetFont(fontOsd);
2086 lineHeight = font->Height();
2087 frameColor = Theme.Color(clrTrackFrameBg);
2088 currentIndex = -1;
2089 xt00 = 0;
2090 xt01 = xt00 + lineHeight / 2;
2091 xt02 = xt01 + Gap;
2092 xt03 = xt00 + 2 * lineHeight;
2093 int ItemsWidth = font->Width(Title) + xt03 - xt02;
2094 for (int i = 0; i < NumTracks; i++)
2095 ItemsWidth = max(ItemsWidth, font->Width(Tracks[i]) + 2 * TextFrame);
2096 xt04 = xt02 + ItemsWidth;
2097 xt05 = xt04 + Gap;
2098 xt06 = xt04 + lineHeight;
2099 xt07 = xt05 + lineHeight;
2100 xt08 = xt07 + lineHeight;
2101 xt09 = xt08 + Gap;
2102 xt10 = xt09 + lineHeight / 2;
2103 xt11 = xt10 + Gap;
2104 xt12 = xt11 + lineHeight;
2105 yt00 = 0;
2106 yt01 = yt00 + lineHeight;
2107 yt02 = yt01 + lineHeight;
2108 yt03 = yt02 + Gap;
2109 yt04 = yt03 + NumTracks * lineHeight + (NumTracks - 1) * Gap;
2110 yt05 = yt04 + Gap;
2111 yt06 = yt05 + lineHeight;
2112 yt07 = yt06 + lineHeight;
2113 while (yt07 > cOsd::OsdHeight()) {
2114 yt04 -= lineHeight + Gap;
2115 yt05 = yt04 + Gap;
2116 yt06 = yt05 + lineHeight;
2117 yt07 = yt06 + lineHeight;
2118 }
2120 // The upper elbow:
2121 osd->DrawRectangle(xt00, yt00, xt12 - 1, yt07 - 1, Theme.Color(clrBackground));
2122 osd->DrawRectangle(xt00, yt00, xt03 - 1, yt02 - 1, clrTransparent);
2123 osd->DrawEllipse (xt00, yt00, xt03 - 1, yt02 - 1, frameColor, 2);
2124 osd->DrawRectangle(xt03, yt00, xt04 - 1, yt02 - 1, frameColor);
2125 osd->DrawRectangle(xt04, yt00, xt08 - 1, yt01 - 1, frameColor);
2126 osd->DrawEllipse (xt04, yt01, xt06 - 1, yt02 - 1, frameColor, -2);
2127 osd->DrawRectangle(xt09, yt00, xt10 - 1, yt01 - 1, frameColor);
2128 osd->DrawRectangle(xt11, yt00, xt11 + lineHeight / 2 - 1, yt01 - 1, frameColor);
2129 osd->DrawRectangle(xt11 + lineHeight / 2, yt00, xt12 - 1, yt00 + lineHeight / 2 - 1, clrTransparent);
2130 osd->DrawEllipse (xt11 + lineHeight / 2, yt00, xt12 - 1, yt01 - 1, frameColor, 5);
2131 osd->DrawText(xt03, yt00, Title, Theme.Color(clrTrackFrameFg), frameColor, font, xt04 - xt03, 0, taTop | taRight);
2132 // The items:
2133 for (int i = 0; i < NumTracks; i++)
2134 SetItem(Tracks[i], i, false);
2135 // The lower elbow:
2136 osd->DrawRectangle(xt00, yt05, xt03 - 1, yt07 - 1, clrTransparent);
2137 osd->DrawEllipse (xt00, yt05, xt03 - 1, yt07 - 1, frameColor, 3);
2138 osd->DrawRectangle(xt03, yt05, xt04 - 1, yt07 - 1, frameColor);
2139 osd->DrawRectangle(xt04, yt06, xt08 - 1, yt07 - 1, frameColor);
2140 osd->DrawEllipse (xt04, yt05, xt06 - 1, yt06 - 1, frameColor, -3);
2141 osd->DrawRectangle(xt09, yt06, xt10 - 1, yt07 - 1, frameColor);
2142 osd->DrawRectangle(xt11, yt06, xt11 + lineHeight / 2 - 1, yt07 - 1, frameColor);
2143 osd->DrawRectangle(xt11 + lineHeight / 2, yt06 + lineHeight / 2, xt12 - 1, yt07 - 1, clrTransparent);
2144 osd->DrawEllipse (xt11 + lineHeight / 2, yt06, xt12 - 1, yt07 - 1, frameColor, 5);
2145}
2146
2151
2152void cSkinLCARSDisplayTracks::SetItem(const char *Text, int Index, bool Current)
2153{
2154 int y0 = yt03 + Index * (lineHeight + Gap);
2155 int y1 = y0 + lineHeight;
2156 if (y1 > yt04)
2157 return;
2158 tColor ColorFg, ColorBg;
2159 if (Current) {
2160 ColorFg = Theme.Color(clrTrackItemCurrentFg);
2161 ColorBg = Theme.Color(clrTrackItemCurrentBg);
2162 osd->DrawRectangle(xt00, y0, xt01 - 1, y1 - 1, frameColor);
2163 osd->DrawRectangle(xt02, y0, xt04 - 1, y1 - 1, ColorBg);
2164 osd->DrawRectangle(xt05, y0, xt05 + lineHeight / 2 - 1, y1 - 1, ColorBg);
2165 osd->DrawEllipse (xt05 + lineHeight / 2, y0, xt07 - 1, y1 - 1, ColorBg, 5);
2166 currentIndex = Index;
2167 }
2168 else {
2169 ColorFg = Theme.Color(clrTrackItemFg);
2170 ColorBg = Theme.Color(clrTrackItemBg);
2171 osd->DrawRectangle(xt00, y0, xt01 - 1, y1 - 1, frameColor);
2172 osd->DrawRectangle(xt02, y0, xt04 - 1, y1 - 1, ColorBg);
2173 if (currentIndex == Index)
2174 osd->DrawRectangle(xt05, y0, xt07 - 1, y1 - 1, Theme.Color(clrBackground));
2175 }
2176 const cFont *font = cFont::GetFont(fontOsd);
2177 osd->DrawText(xt02, y0, Text, ColorFg, ColorBg, font, xt04 - xt02, y1 - y0, taTop | taLeft | taBorder);
2178}
2179
2180void cSkinLCARSDisplayTracks::SetTrack(int Index, const char * const *Tracks)
2181{
2182 if (currentIndex >= 0)
2183 SetItem(Tracks[currentIndex], currentIndex, false);
2184 SetItem(Tracks[Index], Index, true);
2185}
2186
2188{
2189 cBitmap *bm = NULL;
2190 switch (AudioChannel) {
2191 case 0: bm = &bmAudioStereo; break;
2192 case 1: bm = &bmAudioLeft; break;
2193 case 2: bm = &bmAudioRight; break;
2194 default: ;
2195 }
2196 if (bm)
2197 osd->DrawBitmap(xt04 - bm->Width(), (yt06 + yt07 - bm->Height()) / 2, *bm, Theme.Color(clrTrackFrameFg), frameColor);
2198 else
2199 osd->DrawRectangle(xt03, yt06, xt04 - 1, yt07 - 1, frameColor);
2200}
2201
2203{
2204 osd->Flush();
2205}
2206
2207// --- cSkinLCARSDisplayMessage ----------------------------------------------
2208
2210private:
2212 int x0, x1, x2, x3, x4, x5, x6, x7;
2213 int y0, y1;
2214public:
2216 virtual ~cSkinLCARSDisplayMessage();
2217 virtual void SetMessage(eMessageType Type, const char *Text);
2218 virtual void Flush(void);
2219 };
2220
2222{
2223 const cFont *font = cFont::GetFont(fontOsd);
2224 int lineHeight = font->Height();
2225 x0 = 0;
2226 x1 = lineHeight / 2;
2227 x2 = lineHeight;
2228 x3 = x2 + Gap;
2229 x7 = cOsd::OsdWidth();
2230 x6 = x7 - lineHeight / 2;
2231 x5 = x6 - lineHeight / 2;
2232 x4 = x5 - Gap;
2233 y0 = 0;
2234 y1 = lineHeight;
2235 osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1, x0, y0, x7 - 1, y1 - 1);
2236}
2237
2242
2244{
2245 tColor ColorFg = Theme.Color(clrMessageStatusFg + 2 * Type);
2246 tColor ColorBg = Theme.Color(clrMessageStatusBg + 2 * Type);
2247 osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, Theme.Color(clrBackground));
2248 osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
2249 osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, ColorBg, 7);
2250 osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, ColorBg);
2251 osd->DrawText(x3, y0, Text, ColorFg, ColorBg, cFont::GetFont(fontSml), x4 - x3, y1 - y0, taCenter);
2252 osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, ColorBg);
2253 osd->DrawRectangle(x6, y0, x7 - 1, y1 - 1, clrTransparent);
2254 osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, ColorBg, 5);
2255}
2256
2258{
2259 osd->Flush();
2260}
2261
2262// --- cSkinLCARS ------------------------------------------------------------
2263
2265:cSkin("lcars", &::Theme)
2266{
2267}
2268
2270{
2271 return "LCARS";
2272}
2273
2275{
2276 return new cSkinLCARSDisplayChannel(WithInfo);
2277}
2278
2283
2285{
2286 return new cSkinLCARSDisplayReplay(ModeOnly);
2287}
2288
2293
2294cSkinDisplayTracks *cSkinLCARS::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
2295{
2296 return new cSkinLCARSDisplayTracks(Title, NumTracks, Tracks);
2297}
2298
cString ChannelString(const cChannel *Channel, int Number)
Definition channels.c:1140
#define LOCK_CHANNELS_READ
Definition channels.h:270
Definition osd.h:169
int Height(void) const
Definition osd.h:189
int Width(void) const
Definition osd.h:188
Definition ci.h:232
int MasterSlotNumber(void)
Returns the number of this CAM's master slot within the whole system.
Definition ci.h:347
int Tpid(void) const
Definition channels.h:171
int Vpid(void) const
Definition channels.h:154
int Source(void) const
Definition channels.h:152
int Number(void) const
Definition channels.h:179
const char * Name(void) const
Definition channels.c:121
int Dpid(int i) const
Definition channels.h:161
int Apid(int i) const
Definition channels.h:160
bool GroupSep(void) const
Definition channels.h:181
int Ca(int Index=0) const
Definition channels.h:173
static cControl * Control(cMutexLock &MutexLock, bool Hidden=false)
Returns the current replay control (if any) in case it is currently visible.
Definition player.c:73
virtual cString GetHeader(void)
This can be used by players that don't play a cRecording, but rather do something completely differen...
Definition player.c:68
bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false) const
Definition player.h:114
virtual const cRecording * GetRecording(void)
Returns the cRecording that is currently being replayed, or NULL if this player is not playing a cRec...
Definition player.c:63
bool Replaying(void) const
Returns true if we are currently replaying.
Definition device.c:1373
static cDevice * ActualDevice(void)
Returns the actual receiving device in case of Transfer Mode, or the primary device otherwise.
Definition device.c:222
static cDevice * PrimaryDevice(void)
Returns the primary device.
Definition device.h:148
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
Definition device.c:230
eTrackType GetCurrentAudioTrack(void) const
Definition device.h:593
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
Definition device.c:167
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
Definition device.c:1378
virtual int SignalQuality(void) const
Returns the "quality" of the currently received signal.
Definition device.c:795
virtual int SignalStrength(void) const
Returns the "strength" of the currently received signal.
Definition device.c:790
const tTrackId * GetTrack(eTrackType Type)
Returns a pointer to the given track id, or NULL if Type is not less than ttMaxTrackTypes.
Definition device.c:1143
virtual cString DeviceType(void) const
Returns a string identifying the type of this device (like "DVB-S").
Definition device.c:176
static int NumDevices(void)
Returns the total number of devices.
Definition device.h:129
cCamSlot * CamSlot(void) const
Returns the CAM slot that is currently used with this device, or NULL if no CAM slot is in use.
Definition device.h:493
Definition epg.h:73
const char * ShortText(void) const
Definition epg.h:106
time_t Vps(void) const
Definition epg.h:114
cString GetDateString(void) const
Definition epg.c:431
const char * Description(void) const
Definition epg.h:107
int ParentalRating(void) const
Definition epg.h:110
time_t StartTime(void) const
Definition epg.h:111
cString GetTimeString(void) const
Definition epg.c:436
const char * Title(void) const
Definition epg.h:105
cString GetEndTimeString(void) const
Definition epg.c:441
int Duration(void) const
Definition epg.h:113
cString GetVpsString(void) const
Definition epg.c:446
cString GetParentalRatingString(void) const
Definition epg.c:424
Definition font.h:37
virtual int Width(void) const =0
Returns the original character width as requested when the font was created, or 0 if the default widt...
static cFont * CreateFont(const char *Name, int CharHeight, int CharWidth=0)
Creates a new font object with the given Name and makes its characters CharHeight pixels high.
Definition font.c:429
virtual int Height(void) const =0
Returns the height of this font in pixel (all characters have the same height).
static const cFont * GetFont(eDvbFont Font)
Gets the given Font, which was previously set by a call to SetFont().
Definition font.c:412
cListObject * Next(void) const
Definition tools.h:547
static cOsd * NewOsd(int Left, int Top, uint Level=OSD_LEVEL_DEFAULT)
Returns a pointer to a newly created cOsd object, which will be located at the given coordinates.
Definition osd.c:2290
The cOsd class is the interface to the "On Screen Display".
Definition osd.h:753
static int OsdHeight(void)
Definition osd.h:831
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas)
Sets the sub-areas to the given areas.
Definition osd.c:2092
virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants=0)
Draws a filled ellipse defined by the upper left (x1, y1) and lower right (x2, y2) corners with the g...
Definition osd.c:2246
void SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
Allows the system to optimize utilization of the limited color palette entries when generating blende...
Definition osd.c:1959
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas)
Checks whether the OSD can display the given set of sub-areas.
Definition osd.c:2070
static int OsdTop(void)
Definition osd.h:829
virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
Draws a filled rectangle defined by the upper left (x1, y1) and lower right (x2, y2) corners with the...
Definition osd.c:2236
static int OsdLeft(void)
Definition osd.h:828
static int OsdWidth(void)
Definition osd.h:830
virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width=0, int Height=0, int Alignment=taDefault)
Draws the given string at coordinates (x, y) with the given foreground and background color and font.
Definition osd.c:2226
A steerable satellite dish generally points to the south on the northern hemisphere,...
Definition positioner.h:31
static int NormalizeAngle(int Angle)
Normalizes the given Angle into the range -1800...1800.
Definition positioner.c:42
virtual int CurrentLongitude(void) const
Returns the longitude the dish currently points to.
Definition positioner.c:114
int HardLimitLongitude(ePositionerDirection Direction) const
Returns the longitude of the positioner's hard limit in the given Direction.
Definition positioner.c:81
static int HorizonLongitude(ePositionerDirection Direction)
Returns the longitude of the satellite position that is just at the horizon when looking in the given...
Definition positioner.c:69
int TargetLongitude(void) const
Returns the longitude the dish is supposed to be moved to.
Definition positioner.h:105
static bool Active(void)
Definition menu.c:5726
static cRecordControl * GetRecordControl(const char *FileName)
Definition menu.c:5674
const char * ChannelName(void) const
Definition recording.h:88
const cEvent * GetEvent(void) const
Definition recording.h:89
int Errors(void) const
Definition recording.h:106
const char * ShortText(void) const
Definition recording.h:91
const char * Title(void) const
Definition recording.h:90
cString FrameParams(void) const
Definition recording.c:637
const char * Description(void) const
Definition recording.h:92
const char * Name(void) const
Returns the full name of the recording (without the video directory).
Definition recording.h:163
time_t Start(void) const
Definition recording.h:148
cRecordingInfo * Info(void) const
Definition recording.h:170
cSkinDisplayChannel(void)
Definition skins.c:68
virtual void Scroll(bool Up, bool Page)
If this menu contains a text area that can be scrolled, this function will be called to actually scro...
Definition skins.c:107
cTextScroller textScroller
Definition skins.h:173
int Tab(int n)
Returns the offset of the given tab from the left border of the item display area.
Definition skins.h:174
eMenuCategory MenuCategory(void) const
Returns the menu category, set by a previous call to SetMenuCategory().
Definition skins.h:183
cSkinDisplayMenu(void)
Definition skins.c:84
const char * GetTabbedText(const char *s, int Tab)
Returns the part of the given string that follows the given Tab (where 0 indicates the beginning of t...
Definition skins.c:112
virtual void SetMenuCategory(eMenuCategory MenuCategory)
Sets the current menu category.
Definition skins.c:90
const cErrors * errors
Definition skins.h:314
cSkinDisplayReplay(void)
Definition skins.c:214
const cMarks * marks
< This class implements the progress display used during replay of a recording.
Definition skins.h:313
static cSkinDisplay * Current(void)
Returns the currently active cSkinDisplay.
Definition skins.h:61
void SetEditableWidth(int Width)
If an item is set through a call to cSkinDisplayMenu::SetItem(), this function shall be called to set...
Definition skins.h:49
const cEvent * present
Definition skinlcars.c:356
static cBitmap bmTeletext
Definition skinlcars.c:368
virtual void SetChannel(const cChannel *Channel, int Number)
Sets the current channel to Channel.
Definition skinlcars.c:537
virtual void SetPositioner(const cPositioner *Positioner)
Sets the Positioner used to move the satellite dish.
Definition skinlcars.c:640
virtual void SetEvents(const cEvent *Present, const cEvent *Following)
Sets the Present and Following EPG events.
Definition skinlcars.c:589
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition skinlcars.c:654
void DrawSeen(int Current, int Total)
Definition skinlcars.c:502
static cBitmap bmEncrypted
Definition skinlcars.c:368
static cBitmap bmAudio
Definition skinlcars.c:368
virtual ~cSkinLCARSDisplayChannel()
Definition skinlcars.c:476
virtual void SetMessage(eMessageType Type, const char *Text)
Sets a one line message Text, with the given Type.
Definition skinlcars.c:611
static cBitmap bmRecording
Definition skinlcars.c:368
cSkinLCARSDisplayChannel(bool WithInfo)
Definition skinlcars.c:391
static cBitmap bmDolbyDigital
Definition skinlcars.c:368
static cBitmap bmRadio
Definition skinlcars.c:368
eCurrentMode lastMode
Definition skinlcars.c:709
virtual ~cSkinLCARSDisplayMenu()
Definition skinlcars.c:954
cVector< bool > deviceRecording
Definition skinlcars.c:702
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable)
Sets the item at the given Index to Text.
Definition skinlcars.c:1598
virtual void SetScrollbar(int Total, int Offset)
Sets the Total number of items in the currently displayed list, and the Offset of the first item that...
Definition skinlcars.c:1635
virtual void SetButtons(const char *Red, const char *Green=NULL, const char *Yellow=NULL, const char *Blue=NULL)
Sets the color buttons to the given strings.
Definition skinlcars.c:1567
virtual void SetTitle(const char *Title)
Sets the title of this menu to Title.
Definition skinlcars.c:1557
void DrawTextScrollbar(void)
Definition skinlcars.c:1531
bool lastLiveIndicatorTransferring
Definition skinlcars.c:717
void DrawStatusElbows(void)
Definition skinlcars.c:1135
void DrawMenuFrame(void)
Definition skinlcars.c:1037
void DrawLiveIndicator(void)
Definition skinlcars.c:1372
void DrawDevice(const cDevice *Device)
Definition skinlcars.c:1345
virtual void Scroll(bool Up, bool Page)
If this menu contains a text area that can be scrolled, this function will be called to actually scro...
Definition skinlcars.c:1537
virtual const cFont * GetTextAreaFont(bool FixedFont) const
Returns a pointer to the font which is used to display text with SetText().
Definition skinlcars.c:1757
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition skinlcars.c:1764
virtual void SetEvent(const cEvent *Event)
Sets the Event that shall be displayed, using the entire central area of the menu.
Definition skinlcars.c:1640
cVector< cCamSlot * > lastCamSlot
Definition skinlcars.c:704
virtual int MaxItems(void)
Returns the maximum number of items the menu can display.
Definition skinlcars.c:1543
static cBitmap bmArrowDown
Definition skinlcars.c:724
virtual int GetTextAreaWidth(void) const
Returns the width in pixel of the area which is used to display text with SetText().
Definition skinlcars.c:1752
void DrawMainButton(const char *Text, int x0, int x1, int x2, int x3, int y0, int y1, tColor ColorFg, tColor ColorBg, const cFont *Font)
Definition skinlcars.c:1029
const cRecording * lastRecording
Definition skinlcars.c:721
cString lastDeviceType[MAXDEVICES]
Definition skinlcars.c:703
void DrawLive(const cChannel *Channel)
Definition skinlcars.c:1423
const cChannel * lastChannel
Definition skinlcars.c:718
void DrawPlay(cControl *Control)
Definition skinlcars.c:1465
void DrawMainFrameLower(void)
Definition skinlcars.c:1010
void DrawSeen(int Current, int Total)
Definition skinlcars.c:1519
cVector< int > lastSignalStrength
Definition skinlcars.c:705
void DrawTimer(const cTimer *Timer, int y, bool MultiRec)
Definition skinlcars.c:1208
static cBitmap bmTransferMode
Definition skinlcars.c:724
void DrawInfo(const cEvent *Event, bool WithTime)
Definition skinlcars.c:1504
cStateKey timersStateKey
Definition skinlcars.c:714
void DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown)
Definition skinlcars.c:1169
virtual void SetRecording(const cRecording *Recording)
Sets the Recording that shall be displayed, using the entire central area of the menu.
Definition skinlcars.c:1686
cVector< int > lastSignalQuality
Definition skinlcars.c:706
virtual void Clear(void)
Clears the entire central area of the menu.
Definition skinlcars.c:1551
void DrawMainBracket(void)
Definition skinlcars.c:1121
const cEvent * lastEvent
Definition skinlcars.c:720
virtual void SetMenuCategory(eMenuCategory MenuCategory)
Sets the current menu category.
Definition skinlcars.c:961
void DrawMainFrameUpper(tColor Color)
Definition skinlcars.c:991
void DrawFrameDisplay(void)
Definition skinlcars.c:1153
virtual void SetText(const char *Text, bool FixedFont)
Sets the Text that shall be displayed, using the entire central area of the menu.
Definition skinlcars.c:1746
static cBitmap bmArrowUp
Definition skinlcars.c:724
cVector< int > deviceOffset
Definition skinlcars.c:701
virtual void SetMessage(eMessageType Type, const char *Text)
Sets a one line message Text, with the given Type.
Definition skinlcars.c:1588
virtual ~cSkinLCARSDisplayMessage()
Definition skinlcars.c:2238
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition skinlcars.c:2257
virtual void SetMessage(eMessageType Type, const char *Text)
< This class implements a simple message display.
Definition skinlcars.c:2243
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition skinlcars.c:1969
virtual void SetCurrent(const char *Current)
Sets the current position within the recording, as a user readable string in the form "h:mm:ss....
Definition skinlcars.c:1938
virtual void SetMessage(eMessageType Type, const char *Text)
Sets a one line message Text, with the given Type.
Definition skinlcars.c:1959
virtual void SetProgress(int Current, int Total)
This function will be called whenever the position in or the total length of the recording has change...
Definition skinlcars.c:1932
virtual void SetMode(bool Play, bool Forward, int Speed)
Sets the current replay mode, which can be used to display some indicator, showing the user whether w...
Definition skinlcars.c:1925
cSkinLCARSDisplayReplay(bool ModeOnly)
Definition skinlcars.c:1816
virtual void SetRecording(const cRecording *Recording)
Sets the recording that is currently being played.
Definition skinlcars.c:1904
virtual void SetTotal(const char *Total)
Sets the total length of the recording, as a user readable string in the form "h:mm:ss".
Definition skinlcars.c:1946
virtual void SetTitle(const char *Title)
Sets the title of the recording.
Definition skinlcars.c:1913
virtual void SetJump(const char *Jump)
Sets the prompt that allows the user to enter a jump point.
Definition skinlcars.c:1954
virtual ~cSkinLCARSDisplayReplay()
Definition skinlcars.c:1880
static cBitmap bmAudioLeft
Definition skinlcars.c:2069
static cBitmap bmAudioRight
Definition skinlcars.c:2069
cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char *const *Tracks)
Definition skinlcars.c:2083
static cBitmap bmAudioStereo
Definition skinlcars.c:2069
virtual void SetAudioChannel(int AudioChannel)
Sets the audio channel indicator.
Definition skinlcars.c:2187
void SetItem(const char *Text, int Index, bool Current)
Definition skinlcars.c:2152
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition skinlcars.c:2202
virtual ~cSkinLCARSDisplayTracks()
Definition skinlcars.c:2147
virtual void SetTrack(int Index, const char *const *Tracks)
< This class implements the track display.
Definition skinlcars.c:2180
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition skinlcars.c:2054
virtual ~cSkinLCARSDisplayVolume()
Definition skinlcars.c:2021
virtual void SetVolume(int Current, int Total, bool Mute)
< This class implements the volume/mute display.
Definition skinlcars.c:2026
virtual cSkinDisplayMenu * DisplayMenu(void)
Creates and returns a new object for displaying a menu.
Definition skinlcars.c:2279
virtual cSkinDisplayMessage * DisplayMessage(void)
Creates and returns a new object for displaying a message.
Definition skinlcars.c:2299
cSkinLCARS(void)
Definition skinlcars.c:2264
virtual cSkinDisplayVolume * DisplayVolume(void)
Creates and returns a new object for displaying the current volume.
Definition skinlcars.c:2289
virtual cSkinDisplayTracks * DisplayTracks(const char *Title, int NumTracks, const char *const *Tracks)
Creates and returns a new object for displaying the available tracks.
Definition skinlcars.c:2294
virtual const char * Description(void)
Returns a user visible, single line description of this skin, which may consist of arbitrary text and...
Definition skinlcars.c:2269
virtual cSkinDisplayReplay * DisplayReplay(bool ModeOnly)
Creates and returns a new object for displaying replay progress.
Definition skinlcars.c:2284
virtual cSkinDisplayChannel * DisplayChannel(bool WithInfo)
Creates and returns a new object for displaying the current channel.
Definition skinlcars.c:2274
cTheme * Theme(void)
Definition skins.h:418
cSkin(const char *Name, cTheme *Theme=NULL)
Creates a new skin class, with the given Name and Theme.
Definition skins.c:237
static cString ToString(int Code)
Definition sources.c:52
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition tools.c:1195
cString & Append(const char *String)
Definition tools.c:1148
cString & Truncate(int Index)
Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
Definition tools.c:1179
int Height(void)
Definition osd.h:1088
void Set(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg)
Definition osd.c:2421
bool Recording(void) const
Definition timers.h:65
time_t StopTimeEvent(void) const
or by the user (for normal timers)
Definition timers.c:796
const cEvent * Event(void) const
Definition timers.h:86
uint Flags(void) const
Definition timers.h:68
const cChannel * Channel(void) const
Definition timers.h:69
bool Pending(void) const
Definition timers.h:66
time_t StartTimeEvent(void) const
the start/stop times as given by the event (for VPS timers), by event plus margins (for spawned non-V...
Definition timers.c:785
const char * Remote(void) const
Definition timers.h:80
static const cTimers * GetTimersRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for read access.
Definition timers.c:1234
int Size(void) const
Definition tools.h:754
virtual void Append(T Data)
Definition tools.h:774
static int FreeMinutes(void)
Returns the number of minutes that can still be recorded on the video disk.
Definition videodir.h:118
static bool HasChanged(int &State)
Returns true if the usage of the video disk space has changed since the last call to this function wi...
Definition videodir.c:210
static int UsedPercent(void)
Returns the used space of the video disk in percent.
Definition videodir.h:112
cSetup Setup
Definition config.c:372
#define VDRVERSION
Definition config.h:25
#define MAXDEVICES
Definition device.h:29
#define LOCK_SCHEDULES_READ
Definition epg.h:228
@ fontOsd
Definition font.h:22
@ fontFix
Definition font.h:23
uint32_t tColor
Definition font.h:30
#define tr(s)
Definition i18n.h:85
tColor RgbShade(tColor Color, double Factor)
Returns a brighter (Factor > 0) or darker (Factor < 0) version of the given Color.
Definition osd.c:43
@ taCenter
Definition osd.h:158
@ taBorder
Definition osd.h:163
@ taTop
Definition osd.h:161
@ taBottom
Definition osd.h:162
@ taRight
Definition osd.h:160
@ taLeft
Definition osd.h:159
@ oeOk
Definition osd.h:44
static cTheme Theme
Definition skinclassic.c:21
#define clrTransparent
Definition skincurses.c:36
#define clrBackground
Definition skincurses.c:35
static const cCursesFont Font
Definition skincurses.c:31
#define CLR_SEEN
Definition skinlcars.c:93
#define CLR_BACKGROUND
Definition skinlcars.c:79
static cTheme Theme
Definition skinlcars.c:75
#define CLR_EVENT_TITLE
Definition skinlcars.c:88
#define CLR_GREEN
Definition skinlcars.c:98
#define CLR_BLUE
Definition skinlcars.c:100
#define ShowSeenExtent
Definition skinlcars.c:70
static const char *const * ReplaySymbols[2][2][5]
Definition skinlcars.c:1918
#define CLR_EXPOSED
Definition skinlcars.c:95
#define CLR_WHITE
Definition skinlcars.c:96
#define CLR_REPLAY_FRAME
Definition skinlcars.c:82
static cFont * CreateTinyFont(int LineHeight)
Definition skinlcars.c:223
static bool DrawDeviceData(cOsd *Osd, const cDevice *Device, int x0, int y0, int x1, int y1, int &xs, const cFont *TinyFont, cString &LastDeviceType, cCamSlot *&LastCamSlot, bool Initial)
Definition skinlcars.c:237
#define CLR_EVENT_TIME
Definition skinlcars.c:89
#define CLR_RED
Definition skinlcars.c:97
#define CLR_MENU_ITEMS
Definition skinlcars.c:84
static void DrawDevicePosition(cOsd *Osd, const cPositioner *Positioner, int x0, int y0, int x1, int y1, int &LastCurrent)
Definition skinlcars.c:304
static cOsd * CreateOsd(int Left, int Top, int x0, int y0, int x1, int y1)
Definition skinlcars.c:206
#define TextFrame
Definition skinlcars.c:67
#define CLR_ALERT
Definition skinlcars.c:94
#define CLR_CHANNEL_FRAME
Definition skinlcars.c:81
#define CLR_CHANNEL_NAME
Definition skinlcars.c:87
static void DrawDeviceSignal(cOsd *Osd, const cDevice *Device, int x0, int y0, int x1, int y1, int &LastSignalStrength, int &LastSignalQuality, bool Initial)
Definition skinlcars.c:268
#define DISKUSAGEALERTLIMIT
Definition skinlcars.c:72
#define CLR_TRACK
Definition skinlcars.c:92
#define CLR_MAIN_FRAME
Definition skinlcars.c:80
#define SymbolSpacing
Definition skinlcars.c:69
#define CLR_DEVICE
Definition skinlcars.c:86
#define SIGNALDISPLAYDELTA
Definition skinlcars.c:73
#define TextSpacing
Definition skinlcars.c:68
#define Gap
Definition skinlcars.c:66
static bool TwoColors
Definition skinlcars.c:204
#define CLR_EVENT_SHORTTEXT
Definition skinlcars.c:90
#define CLR_TIMER
Definition skinlcars.c:85
#define CLR_TEXT
Definition skinlcars.c:91
#define CLR_DATE
Definition skinlcars.c:83
#define CLR_BLACK
Definition skinlcars.c:101
#define CLR_YELLOW
Definition skinlcars.c:99
eMenuCategory
Definition skins.h:104
@ mcMain
Definition skins.h:107
eMessageType
Definition skins.h:37
Definition osd.h:298
int bpp
Definition osd.h:300
char description[32]
Definition device.h:83
#define THEME_CLR(Theme, Subject, Color)
Definition themes.h:59
@ tfActive
Definition timers.h:19
@ tfVps
Definition timers.h:21
cString TimeString(time_t t)
Converts the given time to a string of the form "hh:mm".
Definition tools.c:1301
bool isempty(const char *s)
Definition tools.c:357
cString WeekDayName(int WeekDay)
Converts the given WeekDay (0=Sunday, 1=Monday, ...) to a three letter day name.
Definition tools.c:1218
cString ShortDateString(time_t t)
Converts the given time to a string of the form "dd.mm.yy".
Definition tools.c:1292
cString DateString(time_t t)
Converts the given time to a string of the form "www dd.mm.yyyy".
Definition tools.c:1281
cString DayDateTime(time_t t)
Converts the given time to a string of the form "www dd.mm. hh:mm".
Definition tools.c:1260
char * strn0cpy(char *dest, const char *src, size_t n)
Definition tools.c:131
cString itoa(int n)
Definition tools.c:450
T constrain(T v, T l, T h)
Definition tools.h:70
#define SECSINDAY
Definition tools.h:42
T min(T a, T b)
Definition tools.h:63
void swap(T &a, T &b)
Definition tools.h:65
T max(T a, T b)
Definition tools.h:64