vdr 2.8.3
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.13 2026/08/30 10:02:00 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);
376 virtual ~cSkinLCARSDisplayChannel() override;
377 virtual void SetChannel(const cChannel *Channel, int Number) override;
378 virtual void SetEvents(const cEvent *Present, const cEvent *Following) override;
379 virtual void SetMessage(eMessageType Type, const char *Text) override;
380 virtual void SetPositioner(const cPositioner *Positioner) override;
381 virtual void Flush(void) override;
382 };
383
390
392{
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);
449 // Rectangles:
451 if (withInfo) {
454 // Elbow:
457 osd->DrawEllipse (xc00, yc08, xc01 - 1, yc12 - 1, frameColor, 3);
459 osd->DrawEllipse (xc02, yc09, xc04 - 1, yc11 - 1, frameColor, -3);
461 // Status area:
464 osd->DrawRectangle(xc10, yc11, xc11 - 1, yc12 - 1, Theme.Color(clrDeviceBg));
465 osd->DrawRectangle(xc12, yc11, xc13 - 1, yc12 - 1, Theme.Color(clrDateBg));
468 osd->DrawEllipse (xc14 + lineHeight / 2, yc11, xc15 - 1, yc12 - 1, frameColor, 5);
469 }
470 // Icons:
473 osd->DrawEllipse (xc14 + lineHeight / 2, yc00, xc15 - 1, yc01 - 1, frameColor, 5);
474}
475
482
484{
485 cString s = DayDateTime();
486 if (initial || !*lastDate || strcmp(s, lastDate)) {
488 lastDate = s;
489 }
490}
491
493{
495 tTrackId TrackId;
496 bool Track = Device->GetTrackId(Device->GetCurrentAudioTrack(), TrackId);
497 if (Track ? strcmp(lastTrackId.description, TrackId.description) : *lastTrackId.description) {
498 osd->DrawText(xc03, yc07, Track ? TrackId.description : "", Theme.Color(clrTrackName), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xc07 - xc03);
499 strn0cpy(lastTrackId.description, Track ? TrackId.description : "", sizeof(lastTrackId.description));
500 }
501}
502
504{
505 if (lastCurrentPosition >= 0)
506 return; // to not interfere with SetPositioner()
507 int Seen = (Total > 0) ? min(xc07 - xc06, int((xc07 - xc06) * double(Current) / Total)) : 0;
508 if (initial || Seen != lastSeen) {
509 int y0 = yc11 - ShowSeenExtent;
510 int y1 = yc11 + lineHeight / 2 - Gap / 2;
511 osd->DrawRectangle(xc06, y0, xc06 + Seen - 1, y1 - 1, Theme.Color(clrSeen));
512 osd->DrawRectangle(xc06 + Seen, y0, xc07 - 1, y1 - 1, Theme.Color(clrBackground));
513 lastSeen = Seen;
514 }
515}
516
518{
519 const cDevice *Device = cDevice::ActualDevice();
521 lastDeviceNumber = Device->DeviceNumber();
522 // Make sure signal meters are redrawn:
526 }
527}
528
530{
531 time_t Now = time(NULL);
532 if (Now != lastSignalDisplay) {
534 lastSignalDisplay = Now;
535 }
536}
537
538void cSkinLCARSDisplayChannel::SetChannel(const cChannel *Channel, int Number)
539{
540 int x = xc13;
541 int xi = x - SymbolSpacing -
547 osd->DrawRectangle(xi, yc00, xc13 - 1, yc01 - 1, frameColor);
548 if (Channel && !Channel->GroupSep()) {
549 bool rec = cRecordControls::Active();
551 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : frameColor);
553 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
555 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid(0) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
556 x -= bmAudio.Width() + SymbolSpacing;
557 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid(1) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
558 if (Channel->Vpid()) {
560 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
561 }
562 else if (Channel->Apid(0)) {
563 x -= bmRadio.Width() + SymbolSpacing;
564 osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmRadio.Height()) / 2, bmRadio, Theme.Color(clrChannelSymbolOn), frameColor);
565 }
566 }
567 cString ChNumber("");
568 cString ChName("");
569 if (Channel) {
570 ChName = Channel->Name();
571 if (!Channel->GroupSep())
572 ChNumber = cString::sprintf("%d%s", Channel->Number(), Number ? "-" : "");
573 }
574 else if (Number)
575 ChNumber = cString::sprintf("%d-", Number);
576 else
577 ChName = ChannelString(NULL, 0);
578 osd->DrawText(xc00, yc00, ChNumber, Theme.Color(clrChannelFrameFg), frameColor, tallFont, xc02 - xc00, yc02 - yc00, taTop | taRight | taBorder);
579 osd->DrawText(xc03, yc00, ChName, Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xi - xc03 - lineHeight, 0, taTop | taLeft);
581 if (withInfo) {
582 if (Channel) {
583 int x = xc00 + (yc10 - yc09); // compensate for the arc
584 osd->DrawText(x, yc07, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), frameColor, cFont::GetFont(fontOsd), xc02 - x, yc10 - yc07, taTop | taRight | taBorder);
585 }
586 DrawDevice();
587 }
588}
589
590void cSkinLCARSDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
591{
592 if (!withInfo)
593 return;
594 if (present != Present)
595 lastSeen = -1;
596 present = Present;
597 for (int i = 0; i < 2; i++) {
598 const cEvent *e = !i ? Present : Following;
599 int y = !i ? yc03 : yc05;
600 if (e) {
603 osd->DrawText(xc03, y + lineHeight, e->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xc13 - xc03);
604 }
605 else {
608 }
609 }
610}
611
613{
614 if (Text) {
615 int x0, x1, y0, y1, y2;
616 if (withInfo) {
617 x0 = xc06;
618 x1 = xc13;
619 y0 = yc11 - ShowSeenExtent;
620 y1 = yc11;
621 y2 = yc12;
622 }
623 else {
624 x0 = xc03;
625 x1 = xc13;
626 y0 = y1 = yc00;
627 y2 = yc02;
628 }
629 osd->SaveRegion(x0, y0, x1 - 1, y2 - 1);
630 if (withInfo)
631 osd->DrawRectangle(xc06, y0, xc07, y1 - 1, Theme.Color(clrBackground)); // clears the "seen" bar
632 osd->DrawText(x0, y1, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), x1 - x0, y2 - y1, taCenter);
633 message = true;
634 }
635 else {
637 message = false;
638 }
639}
640
642{
643 if (Positioner) {
644 int y0 = yc11 - ShowSeenExtent;
645 int y1 = yc11 + lineHeight / 2 - Gap / 2;
646 DrawDevicePosition(osd, Positioner, xc06, y0, xc07, y1, lastCurrentPosition);
647 }
648 else {
650 initial = true; // to have DrawSeen() refresh the progress bar
651 }
652 return;
653}
654
656{
657 if (withInfo) {
658 if (!message) {
659 DrawDate();
660 DrawTrack();
661 DrawDevice();
662 DrawSignal();
663 int Current = 0;
664 int Total = 0;
665 if (present) {
667 time_t t = time(NULL);
668 if (t > present->StartTime())
669 Current = t - present->StartTime();
670 Total = present->Duration();
671 }
672 DrawSeen(Current, Total);
673 }
674 }
675 osd->Flush();
676 initial = false;
677}
678
679// --- cSkinLCARSDisplayMenu -------------------------------------------------
680
682private:
693 int yi00, yi01;
697 int xs; // starting column for signal display
727 void DrawMainFrameUpper(tColor Color);
728 void DrawMainFrameLower(void);
729 void DrawMainButton(const char *Text, int x0, int x1, int x2, int x3, int y0, int y1, tColor ColorFg, tColor ColorBg, const cFont *Font);
730 void DrawMenuFrame(void);
731 void DrawMainBracket(void);
732 void DrawStatusElbows(void);
733 void DrawDate(void);
734 void DrawDisk(void);
735 void DrawLoad(void);
736 void DrawFrameDisplay(void);
737 void DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown);
738 void DrawTimer(const cTimer *Timer, int y, bool MultiRec);
739 void DrawTimers(void);
740 void DrawDevice(const cDevice *Device);
741 void DrawDevices(void);
742 void DrawLiveIndicator(void);
743 void DrawSignals(void);
744 void DrawLive(const cChannel *Channel);
745 void DrawPlay(cControl *Control);
746 void DrawInfo(const cEvent *Event, bool WithTime);
747 void DrawSeen(int Current, int Total);
748 void DrawTextScrollbar(void);
749public:
751 virtual ~cSkinLCARSDisplayMenu() override;
752 virtual void Scroll(bool Up, bool Page) override;
753 virtual int MaxItems(void) override;
754 virtual void Clear(void) override;
755 virtual void SetMenuCategory(eMenuCategory MenuCategory) override;
756 virtual void SetTitle(const char *Title) override;
757 virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL) override;
758 virtual void SetMessage(eMessageType Type, const char *Text) override;
759 virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable) override;
760 virtual void SetScrollbar(int Total, int Offset) override;
761 virtual void SetEvent(const cEvent *Event) override;
762 virtual void SetRecording(const cRecording *Recording) override;
763 virtual void SetText(const char *Text, bool FixedFont) override;
764 virtual int GetTextAreaWidth(void) const override;
765 virtual const cFont *GetTextAreaFont(bool FixedFont) const override;
766 virtual void Flush(void) override;
767 };
768
772
774{
776 initial = true;
778 lastChannel = NULL;
779 lastEvent = NULL;
780 lastRecording = NULL;
781 lastSeen = -1;
786 lastDiskAlert = false;
787 lastSystemLoad = -1;
788 const cFont *font = cFont::GetFont(fontOsd);
789 lineHeight = font->Height();
791 frameColor = Theme.Color(clrMenuFrameBg);
792 currentIndex = -1;
793 // The outer frame:
794 int d = 5 * lineHeight;
795 xa00 = 0;
796 xa01 = xa00 + d / 2;
797 xa02 = xa00 + d;
798 xa03 = xa02 + lineHeight;
799 xa04 = xa02 + d / 4;
800 xa05 = xa02 + d;
801 xa06 = xa05 + Gap;
803 xa08 = xa09 - lineHeight;
804 xa07 = xa08 - Gap;
805
806 yt00 = 0;
807 yt01 = yt00 + lineHeight;
808 yt02 = yt01 + lineHeight;
809 yt03 = yt01 + d / 4;
810 yt04 = yt02 + Gap;
811 yt05 = yt00 + d / 2;
812 yt06 = yt04 + 2 * lineHeight;
813
814 yc00 = yt06 + Gap;
815 yc05 = yc00 + 3 * lineHeight + Gap / 2;
816 yc04 = yc05 - lineHeight;
817 yc03 = yc04 - lineHeight;
818 yc02 = yc04 - d / 4;
819 yc01 = yc05 - d / 2;
820
821 yc06 = yc05 + Gap;
822 yc07 = yc06 + lineHeight;
823 yc08 = yc07 + lineHeight;
824 yc09 = yc07 + d / 4;
825 yc10 = yc06 + d / 2;
826 yc11 = yc06 + 3 * lineHeight + Gap / 2;
827
828 yb00 = yc11 + Gap;
829 yb01 = yb00 + 2 * lineHeight;
830 yb02 = yb01 + Gap;
831 yb03 = yb02 + 2 * lineHeight;
832 yb04 = yb03 + Gap;
833 yb05 = yb04 + 2 * lineHeight;
834 yb06 = yb05 + Gap;
835 yb07 = yb06 + 2 * lineHeight;
836 yb08 = yb07 + Gap;
837
839 yb14 = yb15 - lineHeight;
840 yb13 = yb14 - lineHeight;
841 yb12 = yb14 - d / 4;
842 yb11 = yb15 - d / 2;
843 yb10 = yb13 - Gap - 2 * lineHeight;
844 yb09 = yb10 - Gap;
845
846 // Compensate for large font size:
847 if (yb09 - yb08 < 2 * lineHeight) {
848 yb08 = yb06;
849 yb06 = 0; // drop empty rectangle
850 }
851 if (yb09 - yb08 < 2 * lineHeight) {
852 yb05 = yb09;
853 yb08 = 0; // drop "LCARS" display
854 }
855 if (yb05 - yb04 < 2 * lineHeight) {
856 yb03 = yb09;
857 yb04 = 0; // drop "LOAD" display
858 }
859 if (yb03 - yb02 < 2 * lineHeight) {
860 yb01 = yb09;
861 yb02 = 0; // drop "DISK" display
862 }
863 // Anything else is just insanely large...
864
865 // The main command menu:
866 xm00 = xa03;
867 xm01 = xa05;
868 xm02 = xa06;
869 xm08 = (xa09 + xa00) / 2;
870 xm07 = xm08 - lineHeight;
871 xm06 = xm07 - lineHeight / 2;
872 xm05 = xm06 - lineHeight / 2;
873 xm04 = xm05 - lineHeight;
874 xm03 = xm04 - Gap;
875 ym00 = yc08;
876 ym01 = ym00 + lineHeight / 2;
877 ym02 = ym01 + lineHeight / 2;
878 ym03 = ym02 + Gap;
879 ym07 = yb15;
880 ym06 = ym07 - lineHeight / 2;
881 ym05 = ym06 - lineHeight / 2;
882 ym04 = ym05 - Gap;
883
884 // The status area:
885 xs00 = xm08 + Gap + lineHeight + Gap;
886 xs13 = xa09;
887 xs12 = xa08;
888 xs11 = xa07;
889 xs05 = (xs00 + xs11 + Gap) / 2;
890 xs04 = xs05 - lineHeight / 2;
891 xs03 = xs04 - lineHeight / 2;
892 xs02 = xs03 - 2 * lineHeight;
893 xs01 = xs02 - Gap;
894 xs06 = xs05 + Gap;
895 xs07 = xs06 + lineHeight / 2;
896 xs08 = xs07 + lineHeight / 2;
897 xs09 = xs08 + 2 * lineHeight;
898 xs10 = xs09 + Gap;
899 ys00 = yc06;
900 ys01 = ys00 + lineHeight;
901 ys02 = ys01 + lineHeight / 2;
902 ys04 = ys01 + lineHeight;
903 ys03 = ys04 - Gap;
904 ys05 = yb15;
905
906 // The item area (just to have them initialized, actual setting will be done in SetMenuCategory():
907
908 xi00 = 0;
909 xi01 = 0;
910 xi02 = 0;
911 xi03 = 1;
912 yi00 = 0;
913 yi01 = 1;
914
915 // The color buttons in submenus:
916 xb00 = xa06;
917 xb15 = xa07;
918 int w = (xa08 - xa06) / 4;
919 xb01 = xb00 + lineHeight / 2;
920 xb02 = xb01 + Gap;
921 xb04 = xb00 + w;
922 xb03 = xb04 - Gap;
923 xb05 = xb04 + lineHeight / 2;
924 xb06 = xb05 + Gap;
925 xb08 = xb04 + w;
926 xb07 = xb08 - Gap;
927 xb09 = xb08 + lineHeight / 2;
928 xb10 = xb09 + Gap;
929 xb12 = xb08 + w;
930 xb11 = xb12 - Gap;
931 xb13 = xb12 + lineHeight / 2;
932 xb14 = xb13 + Gap;
933
934 // The color buttons in the main menu:
935 int r = lineHeight;
936 xd07 = xa09;
937 xd06 = xd07 - r;
938 xd05 = xd06 - 4 * r;
939 xd04 = xd05 - r;
940 xd03 = xd04 - Gap;
941 xd02 = xd03 - r;
942 xd01 = xd02 - 4 * r;
943 xd00 = xd01 - r;
944 yd00 = yt00;
945 yd05 = yc04 - Gap;
946 yd04 = yd05 - 2 * r;
947 yd03 = yd04 - Gap;
948 yd02 = yd03 - 2 * r;
949 yd01 = yd02 - Gap;
950
951 xs = 0;
952
954}
955
962
964{
967 initial = true;
969 if (MenuCategory == mcMain) {
970 yi00 = ym03;
971 yi01 = ym04;
972 xi00 = xm00;
973 xi01 = xm03;
974 xi02 = xm04;
975 xi03 = xm05;
980 }
981 else {
982 yi00 = yt02;
983 yi01 = yb13;
984 xi00 = xa03;
985 xi01 = xa07;
986 xi02 = xa08;
987 xi03 = xa09;
989 }
990 }
991}
992
994{
995 // Top left rectangles:
996 osd->DrawRectangle(xa00, yt00, xa02 - 1, yt02 - 1, Color);
997 osd->DrawRectangle(xa00, yt04, xa02 - 1, yt06 - 1, Color);
998 // Upper elbow:
999 osd->DrawRectangle(xa00, yc00, xa01 - 1, yc01 - 1, Color);
1000 osd->DrawEllipse (xa00, yc01, xa01 - 1, yc05 - 1, Color, 3);
1001 osd->DrawRectangle(xa01, yc00, xa02 - 1, yc05 - 1, Color);
1002 osd->DrawEllipse (xa02, yc02, xa04 - 1, yc04 - 1, Color, -3);
1003 osd->DrawRectangle(xa02, yc04, xa05 - 1, yc05 - 1, Color);
1004 // Upper delimiter:
1005 osd->DrawRectangle(xa06, yc04 + lineHeight / 2, xm08 - 1, yc05 - 1, Color);
1006 osd->DrawRectangle(xm08 + Gap, yc04, xs00 - Gap - 1, yc05 - 1, Color);
1007 osd->DrawRectangle(xs00, yc04, xs05 - 1, yc05 - 1, Color);
1008 osd->DrawRectangle(xs06, yc04, xa07 - 1, yc05 - 1, Color);
1009 osd->DrawRectangle(xa08, yc04, xa09 - 1, yc05 - 1, Color);
1010}
1011
1013{
1014 const cFont *font = cFont::GetFont(fontOsd);
1015 // Lower elbow:
1017 osd->DrawEllipse (xa00, yc06, xa01 - 1, yc10 - 1, frameColor, 2);
1019 osd->DrawEllipse (xa02, yc07, xa04 - 1, yc09 - 1, frameColor, -2);
1021 // Lower delimiter:
1023 osd->DrawRectangle(xm08 + Gap, yc06, xs00 - Gap - 1, yc07 - 1, frameColor);
1025 // VDR version:
1027 osd->DrawText(xa00, yb10, "VDR", Theme.Color(clrMenuFrameFg), frameColor, tallFont, xa02 - xa00, yb11 - yb10, taTop | taRight | taBorder);
1029}
1030
1031void cSkinLCARSDisplayMenu::DrawMainButton(const char *Text, int x0, int x1, int x2, int x3, int y0, int y1, tColor ColorFg, tColor ColorBg, const cFont *Font)
1032{
1033 int h = y1 - y0;
1034 osd->DrawEllipse(x0, y0, x1 - 1, y1 - 1, ColorBg, 7);
1035 osd->DrawText(x1, y0, Text, ColorFg, ColorBg, Font, x2 - x1, h, taBottom | taRight);
1036 osd->DrawEllipse(x2, y0, x3 - 1, y1 - 1, ColorBg, 5);
1037}
1038
1040{
1041 // Upper elbow:
1044 osd->DrawEllipse (xa00, yt00, xa01 - 1, yt05 - 1, frameColor, 2);
1046 osd->DrawEllipse (xa02, yt01, xa04 - 1, yt03 - 1, frameColor, -2);
1051 osd->DrawEllipse (xa08 + lineHeight / 2, yt00, xa09 - 1, yt01 - 1, frameColor, 5);
1052 // Center part:
1054 // Lower elbow:
1057 osd->DrawEllipse (xa00, yb11, xa01 - 1, yb15 - 1, frameColor, 3);
1059 osd->DrawEllipse (xa02, yb12, xa04 - 1, yb14 - 1, frameColor, -3);
1063 osd->DrawEllipse (xa08 + lineHeight / 2, yb14, xa09 - 1, yb15 - 1, frameColor, 5);
1064 osd->DrawText(xa00, yb10, "VDR", Theme.Color(clrMenuFrameFg), frameColor, tallFont, xa02 - xa00, yb11 - yb10, taTop | taRight | taBorder);
1065 // Color buttons:
1066 tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
1067 osd->DrawRectangle(xb00, yb14, xb01 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey0]));
1068 osd->DrawRectangle(xb04, yb14, xb05 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey1]));
1069 osd->DrawRectangle(xb08, yb14, xb09 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey2]));
1070 osd->DrawRectangle(xb12, yb14, xb13 - 1, yb15 - 1, Theme.Color(lutBg[Setup.ColorKey3]));
1071}
1072
1074{
1075 cString s = DayDateTime();
1076 if (initial || !*lastDate || strcmp(s, lastDate)) {
1077 const cFont *font = cFont::GetFont(fontOsd);
1078 tColor ColorFg = Theme.Color(clrDateFg);
1079 tColor ColorBg = Theme.Color(clrDateBg);
1080 lastDate = s;
1081 const char *t = strrchr(s, ' ');
1082 osd->DrawText(xa00, yb01 - lineHeight, t, ColorFg, ColorBg, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1083 s.Truncate(t - s);
1084 osd->DrawText(xa00, yb00, s, ColorFg, ColorBg, font, xa02 - xa00, yb01 - yb00 - lineHeight, taTop | taRight | taBorder);
1085 }
1086}
1087
1089{
1090 if (yb02) {
1091 if (cVideoDiskUsage::HasChanged(lastDiskUsageState) || initial) { // must call HasChanged() first, or it shows an outdated value in the 'initial' case!
1092 const cFont *font = cFont::GetFont(fontOsd);
1093 int DiskUsage = cVideoDiskUsage::UsedPercent();
1094 bool DiskAlert = DiskUsage > DISKUSAGEALERTLIMIT;
1095 tColor ColorFg = DiskAlert ? Theme.Color(clrAlertFg) : Theme.Color(clrMenuFrameFg);
1096 tColor ColorBg = DiskAlert ? Theme.Color(clrAlertBg) : frameColor;
1097 if (initial || DiskAlert != lastDiskAlert)
1098 osd->DrawText(xa00, yb02, tr("DISK"), ColorFg, ColorBg, tinyFont, xa02 - xa00, yb03 - yb02, taTop | taLeft | taBorder);
1099 osd->DrawText(xa01, yb02, itoa(DiskUsage), ColorFg, ColorBg, font, xa02 - xa01, lineHeight, taBottom | taRight | taBorder);
1100 osd->DrawText(xa00, yb03 - lineHeight, cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60), ColorFg, ColorBg, font, xa02 - xa00, 0, taBottom | taRight | taBorder);
1101 lastDiskAlert = DiskAlert;
1102 }
1103 }
1104}
1105
1107{
1108 if (yb04) {
1109 tColor ColorFg = Theme.Color(clrMenuFrameFg);
1110 tColor ColorBg = frameColor;
1111 if (initial)
1112 osd->DrawText(xa00, yb04, tr("LOAD"), ColorFg, ColorBg, tinyFont, xa02 - xa00, yb05 - yb04, taTop | taLeft | taBorder);
1113 double SystemLoad;
1114 if (getloadavg(&SystemLoad, 1) > 0) {
1115 if (initial || SystemLoad != lastSystemLoad) {
1116 osd->DrawText(xa00, yb05 - lineHeight, cString::sprintf("%.1f", SystemLoad), ColorFg, ColorBg, cFont::GetFont(fontOsd), xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1117 lastSystemLoad = SystemLoad;
1118 }
1119 }
1120 }
1121}
1122
1124{
1125 tColor Color = Theme.Color(clrMenuMainBracket);
1126 osd->DrawRectangle(xm00, ym00, xm01 - 1, ym01 - 1, Color);
1127 osd->DrawRectangle(xm02, ym00, xm07 - 1, ym01 - 1, Color);
1128 osd->DrawEllipse (xm07, ym00, xm08 - 1, ym02 - 1, Color, 1);
1129 osd->DrawEllipse (xm06, ym01, xm07 - 1, ym02 - 1, Color, -1);
1130 osd->DrawRectangle(xm07, ym03, xm08 - 1, ym04 - 1, Color);
1131 osd->DrawEllipse (xm06, ym05, xm07 - 1, ym06 - 1, Color, -4);
1132 osd->DrawEllipse (xm07, ym05, xm08 - 1, ym07 - 1, Color, 4);
1133 osd->DrawRectangle(xm02, ym06, xm07 - 1, ym07 - 1, Color);
1134 osd->DrawRectangle(xm00, ym06, xm01 - 1, ym07 - 1, Color);
1135}
1136
1138{
1139 const cFont *font = cFont::GetFont(fontOsd);
1140 osd->DrawText (xs00, ys00, tr("TIMERS"), Theme.Color(clrMenuFrameFg), frameColor, font, xs01 - xs00, lineHeight, taBottom | taLeft | taBorder);
1142 osd->DrawEllipse (xs03, ys00, xs05 - 1, ys01 - 1, frameColor, 1);
1143 osd->DrawEllipse (xs03, ys01, xs04 - 1, ys02 - 1, frameColor, -1);
1146 osd->DrawText (xs10, ys00, tr("DEVICES"), Theme.Color(clrMenuFrameFg), frameColor, font, xs11 - xs10, lineHeight, taBottom | taRight | taBorder);
1148 osd->DrawEllipse (xs06, ys00, xs08 - 1, ys01 - 1, frameColor, 2);
1149 osd->DrawEllipse (xs07, ys01, xs08 - 1, ys02 - 1, frameColor, -2);
1153}
1154
1156{
1157 DrawDate();
1158 DrawDisk();
1159 DrawLoad();
1160 if (initial) {
1161 if (yb06)
1163 if (yb08) {
1164 const cFont *font = cFont::GetFont(fontOsd);
1166 osd->DrawText(xa00, yb09 - lineHeight, "LCARS", Theme.Color(clrMenuFrameFg), frameColor, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1167 }
1168 }
1169}
1170
1171void cSkinLCARSDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown)
1172{
1173 int x0, x1, tt, tb;
1174 tColor ClearColor;
1175 if (MenuCategory() == mcMain) {
1176 x0 = xm07;
1177 x1 = xm08;
1178 tt = ym03;
1179 tb = ym04;
1180 ClearColor = Theme.Color(clrMenuMainBracket);
1181 }
1182 else {
1183 x0 = xa02 + Gap;
1184 x1 = x0 + lineHeight / 2;
1185 tt = yc00;
1186 tb = yc11;
1187 ClearColor = Theme.Color(clrBackground);
1188 int d = TextFrame;
1189 if (CanScrollUp)
1190 osd->DrawBitmap(xa02 - bmArrowUp.Width() - d, yc00 + d, bmArrowUp, Theme.Color(clrMenuScrollbarArrow), frameColor);
1191 else
1192 osd->DrawRectangle(xa02 - bmArrowUp.Width() - d, yc00 + d, xa02 - d - 1, yc00 + d + bmArrowUp.Height() - 1, frameColor);
1193 if (CanScrollDown)
1194 osd->DrawBitmap(xa02 - bmArrowDown.Width() - d, yc11 - d - bmArrowDown.Height(), bmArrowDown, Theme.Color(clrMenuScrollbarArrow), frameColor);
1195 else
1196 osd->DrawRectangle(xa02 - bmArrowDown.Width() - d, yc11 - d - bmArrowDown.Height(), xa02 - d - 1, yc11 - d - 1, frameColor);
1197 }
1198 if (Total > 0 && Total > Shown) {
1199 int sw = x1 - x0;
1200 int sh = max(int((tb - tt) * double(Shown) / Total + 0.5), sw);
1201 int st = min(int(tt + (tb - tt) * double(Offset) / Total + 0.5), tb - sh);
1202 int sb = min(st + sh, tb);
1203 osd->DrawRectangle(x0, tt, x1 - 1, tb - 1, Theme.Color(clrMenuScrollbarTotal));
1204 osd->DrawRectangle(x0, st, x1 - 1, sb - 1, Theme.Color(clrMenuScrollbarShown));
1205 }
1206 else if (MenuCategory() != mcMain)
1207 osd->DrawRectangle(x0, tt, x1 - 1, tb - 1, ClearColor);
1208}
1209
1210void cSkinLCARSDisplayMenu::DrawTimer(const cTimer *Timer, int y, bool MultiRec)
1211{
1212 // The timer data:
1213 bool Alert = !Timer->Recording() && Timer->Pending();
1214 tColor ColorFg = Alert ? Theme.Color(clrAlertFg) : Theme.Color(clrTimerFg);
1215 tColor ColorBg = Alert ? Theme.Color(clrAlertBg) : Theme.Color(clrTimerBg);
1216 osd->DrawRectangle(xs00, y, xs03 - 1, y + lineHeight - 1, ColorBg);
1217 cString Date;
1218 if (Timer->Recording())
1219 Date = cString::sprintf("-%s", *TimeString(Timer->StopTimeEvent()));
1220 else {
1221 time_t Now = time(NULL);
1222 time_t StartTime = Timer->StartTimeEvent();
1223 cString Today = WeekDayName(Now);
1224 cString Time = TimeString(StartTime);
1225 cString Day = WeekDayName(StartTime);
1226 if (StartTime > Now + 6 * SECSINDAY)
1227 Date = DayDateTime(StartTime);
1228 else if (strcmp(Day, Today) != 0)
1229 Date = cString::sprintf("%s %s", *Day, *Time);
1230 else
1231 Date = Time;
1232 }
1233 if (Timer->Flags() & tfVps)
1234 Date = cString::sprintf("VPS %s", *Date);
1235 const cChannel *Channel = Timer->Channel();
1236 const cEvent *Event = Timer->Event();
1237 int d = max(TextFrame / 2, 1);
1238 if (Channel) {
1239 osd->DrawText(xs00 + d, y, Channel->Name(), ColorFg, ColorBg, tinyFont, xs03 - xs00 - d);
1240 osd->DrawText(xs03 - tinyFont->Width(Date) - d, y, Date, ColorFg, ColorBg, tinyFont);
1241 }
1242 if (Event)
1243 osd->DrawText(xs00 + d, y + lineHeight - tinyFont->Height(), Event->Title(), ColorFg, ColorBg, tinyFont, xs03 - xs00 - 2 * d);
1244 // The remote timer indicator:
1245 if (Timer->Remote())
1246 osd->DrawRectangle(xs00 - (lineHeight - Gap) / 2, y, xs00 - Gap - 1, y + lineHeight - 1, Timer->Recording() ? Theme.Color(clrMenuTimerRecording) : ColorBg);
1247 // The timer recording indicator:
1248 else if (Timer->Recording())
1249 osd->DrawRectangle(xs03 + Gap, y - (MultiRec ? Gap : 0), xs04 - Gap / 2 - 1, y + lineHeight - 1, Theme.Color(clrMenuTimerRecording));
1250}
1251
1253{
1254 if (const cTimers *Timers = cTimers::GetTimersRead(timersStateKey)) {
1256 const cFont *font = cFont::GetFont(fontOsd);
1259 cSortedTimers SortedTimers(Timers);
1260 cVector<int> FreeDeviceSlots;
1261 int NumDevices = 0;
1262 int y = ys04;
1263 // Timers and recording devices:
1265 while (1) {
1266 int NumTimers = 0;
1267 const cDevice *Device = NULL;
1268 for (int i = 0; i < SortedTimers.Size(); i++) {
1269 if (y + lineHeight > ys05)
1270 break;
1271 if (const cTimer *Timer = SortedTimers[i]) {
1272 if (Timer->IsPatternTimer())
1273 SortedTimers[i] = NULL;
1274 else if (Timer->Recording()) {
1275 if (Timer->Remote()) {
1276 if (!Device && Timer->HasFlags(tfActive)) {
1277 DrawTimer(Timer, y, false);
1278 FreeDeviceSlots.Append(y);
1279 y += lineHeight + Gap;
1280 }
1281 else
1282 continue;
1283 }
1284 else if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(Timer)) {
1285 if (!Device || Device == RecordControl->Device()) {
1286 DrawTimer(Timer, y, NumTimers > 0);
1287 NumTimers++;
1288 if (!Device) {
1289 Device = RecordControl->Device();
1290 deviceOffset[Device->DeviceNumber()] = y;
1291 deviceRecording[Device->DeviceNumber()] = true;
1292 NumDevices++;
1293 }
1294 else
1295 FreeDeviceSlots.Append(y);
1296 y += lineHeight + Gap;
1297 }
1298 else
1299 continue;
1300 }
1301 SortedTimers[i] = NULL;
1302 }
1303 else if (!Device && Timer->HasFlags(tfActive)) {
1304 DrawTimer(Timer, y, false);
1305 FreeDeviceSlots.Append(y);
1306 y += lineHeight + Gap;
1307 SortedTimers[i] = NULL;
1308 }
1309 }
1310 }
1311 if (!Device)
1312 break;
1313 }
1314 // Devices currently not recording:
1315 int Slot = 0;
1316 for (int i = 0; i < cDevice::NumDevices(); i++) {
1317 if (const cDevice *Device = cDevice::GetDevice(i)) {
1318 if (Device->NumProvidedSystems()) {
1319 if (!deviceRecording[Device->DeviceNumber()]) {
1320 if (Slot < FreeDeviceSlots.Size()) {
1321 y = FreeDeviceSlots[Slot];
1322 Slot++;
1323 }
1324 if (y + lineHeight > ys05)
1325 break;
1326 deviceOffset[Device->DeviceNumber()] = y;
1327 y += lineHeight + Gap;
1328 NumDevices++;
1329 }
1330 }
1331 }
1332 }
1333 // Total number of active timers:
1334 int NumTimers = 0;
1335 for (const cTimer *Timer = Timers->First(); Timer; Timer = Timers->Next(Timer)) {
1336 if (Timer->HasFlags(tfActive))
1337 NumTimers++;
1338 }
1339 osd->DrawText(xs02, ys00, itoa(NumTimers), Theme.Color(clrMenuFrameFg), frameColor, font, xs03 - xs02, ys01 - ys00, taBottom | taLeft | taBorder);
1340 osd->DrawText(xs08, ys00, itoa(NumDevices), Theme.Color(clrMenuFrameFg), frameColor, font, xs09 - xs08, ys01 - ys00, taBottom | taRight | taBorder);
1342 initial = true; // forces redrawing of devices
1344 }
1345}
1346
1348{
1349 int dn = Device->DeviceNumber();
1350 int y = deviceOffset[dn];
1351 if (y + lineHeight <= ys05) {
1352 if (DrawDeviceData(osd, Device, xs08, y, xs11, y + lineHeight, xs, tinyFont, lastDeviceType[dn], lastCamSlot[dn], initial)) {
1353 // Make sure signal meters are redrawn:
1354 lastSignalStrength[dn] = -1;
1355 lastSignalQuality[dn] = -1;
1357 }
1358 // The device recording indicator:
1359 if (deviceRecording[dn])
1360 osd->DrawRectangle(xs07 + Gap / 2, y, xs08 - Gap - 1, y + lineHeight - 1, Theme.Color(clrMenuDeviceRecording));
1361 }
1362}
1363
1365{
1366 for (int i = 0; i < cDevice::NumDevices(); i++) {
1367 if (const cDevice *Device = cDevice::GetDevice(i)) {
1368 if (Device->NumProvidedSystems())
1369 DrawDevice(Device);
1370 }
1371 }
1372}
1373
1375{
1376 cDevice *Device = cDevice::PrimaryDevice();
1377 int y = -1;
1378 bool Transferring = Device->Transferring();
1379 if (!Device->Replaying() || Transferring)
1381 if (initial || y != lastLiveIndicatorY || Transferring != lastLiveIndicatorTransferring) {
1382 if (lastLiveIndicatorY >= 0)
1384 if (y > 0) {
1385 tColor ColorBg = Theme.Color(clrChannelFrameBg);
1386 osd->DrawRectangle(xs12, y, xs12 + lineHeight / 2 - 1, y + lineHeight - 1, ColorBg);
1387 osd->DrawEllipse (xs12 + lineHeight / 2, y, xs13 - 1, y + lineHeight - 1, ColorBg, 5);
1388 if (Transferring) {
1389 int w = bmTransferMode.Width();
1390 int h = bmTransferMode.Height();
1391 int b = w * w + h * h; // the diagonal of the bitmap (squared)
1392 int c = lineHeight * lineHeight; // the diameter of the circle (squared)
1393 const cBitmap *bm = &bmTransferMode;
1394 if (b > c) {
1395 // the bitmap doesn't fit, so scale it down:
1396 double f = sqrt(double(c) / (2 * b));
1397 bm = bmTransferMode.Scaled(f, f);
1398 }
1399 osd->DrawBitmap((xs12 + xs13 - bm->Width()) / 2, y + (lineHeight - bm->Height()) / 2, *bm, Theme.Color(clrChannelFrameFg), ColorBg);
1400 if (bm != &bmTransferMode)
1401 delete bm;
1402 }
1403 }
1405 lastLiveIndicatorTransferring = Transferring;
1406 }
1407}
1408
1410{
1411 time_t Now = time(NULL);
1413 for (int i = 0; i < cDevice::NumDevices(); i++) {
1414 if (const cDevice *Device = cDevice::GetDevice(i)) {
1415 if (Device->NumProvidedSystems()) {
1416 if (int y = deviceOffset[i])
1418 }
1419 }
1420 }
1421 lastSignalDisplay = Now;
1422 }
1423}
1424
1426{
1427 if (lastMode != cmLive) {
1428 initial = true;
1429 lastMode = cmLive;
1430 }
1431 if (initial) {
1432 DrawMainFrameUpper(Theme.Color(clrChannelFrameBg));
1433 osd->DrawText(xd00, yd00, tr("LIVE"), Theme.Color(clrChannelFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder);
1434 }
1435 if (!Channel)
1436 return;
1437 if (initial || Channel != lastChannel || strcmp(Channel->Name(), lastChannelName)) {
1438 osd->DrawText(xa00, yt00, itoa(Channel->Number()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), tallFont, xa02 - xa00, yt02 - yt00, taTop | taRight | taBorder);
1439 osd->DrawText(xa03, yt00, Channel->Name(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
1440 int x = xa00 + (yc03 - yc02); // compensate for the arc
1441 osd->DrawText(x, yc00, cSource::ToString(Channel->Source()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), cFont::GetFont(fontOsd), xa02 - x, yc03 - yc00, taTop | taRight | taBorder);
1442 lastChannel = Channel;
1443 lastChannelName = Channel->Name();
1444 DrawSeen(0, 0);
1445 }
1446 // The current programme:
1448 if (const cSchedule *Schedule = Schedules->GetSchedule(Channel)) {
1449 const cEvent *Event = Schedule->GetPresentEvent();
1450 if (initial || Event != lastEvent) {
1451 DrawInfo(Event, true);
1452 lastEvent = Event;
1453 lastSeen = -1;
1454 }
1455 int Current = 0;
1456 int Total = 0;
1457 if (Event) {
1458 time_t t = time(NULL);
1459 if (t > Event->StartTime())
1460 Current = t - Event->StartTime();
1461 Total = Event->Duration();
1462 }
1463 DrawSeen(Current, Total);
1464 }
1465}
1466
1468{
1469 if (lastMode != cmPlay) {
1470 initial = true;
1471 lastMode = cmPlay;
1472 }
1473 if (initial) {
1474 DrawMainFrameUpper(Theme.Color(clrReplayFrameBg));
1475 osd->DrawText(xd00, yd00, tr("PLAY"), Theme.Color(clrReplayFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder);
1476 }
1477 // The current progress:
1478 int Current = 0;
1479 int Total = 0;
1480 if (Control->GetIndex(Current, Total))
1481 DrawSeen(Current, Total);
1482 // The current programme:
1483 if (const cRecording *Recording = Control->GetRecording()) {
1484 if (initial || Recording != lastRecording) {
1485 const cFont *font = cFont::GetFont(fontOsd);
1486 if (const cRecordingInfo *Info = Recording->Info()) {
1487 osd->DrawText(xa03, yt00, Info->ChannelName(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
1488 DrawInfo(Info->GetEvent(), false);
1489 }
1490 else
1491 osd->DrawText(xa03, yt04, Recording->Name(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), font, xd00 - xa03, 0, taTop | taLeft);
1492 osd->DrawText(xa00, yt04, ShortDateString(Recording->Start()), Theme.Color(clrReplayFrameFg), Theme.Color(clrReplayFrameBg), font, xa02 - xa00, 0, taTop | taRight | taBorder);
1493 osd->DrawText(xa00, yt06 - lineHeight, TimeString(Recording->Start()), Theme.Color(clrReplayFrameFg), Theme.Color(clrReplayFrameBg), font, xa02 - xa00, 0, taBottom | taRight | taBorder);
1494 lastRecording = Recording;
1495 }
1496 }
1497 else {
1498 cString Header = Control->GetHeader();
1499 if (!*lastHeader || strcmp(Header, lastHeader)) {
1500 osd->DrawText(xa03, yt00, Header, Theme.Color(clrMenuText), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft);
1501 lastHeader = Header;
1502 }
1503 }
1504}
1505
1506void cSkinLCARSDisplayMenu::DrawInfo(const cEvent *Event, bool WithTime)
1507{
1508 if (Event) {
1509 const cFont *font = cFont::GetFont(fontOsd);
1510 int y = yt04;
1511 osd->DrawText(xa03, y, Event->Title(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), font, xd00 - xa03 - lineHeight, lineHeight, taBottom | taLeft);
1512 y += lineHeight;
1513 osd->DrawText(xa03, y, Event->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xd00 - xa03 - lineHeight, lineHeight, taTop | taLeft);
1514 if (WithTime) {
1515 osd->DrawText(xa00, yt04, Event->GetTimeString(), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), font, xa02 - xa00, lineHeight, taTop | taRight | taBorder);
1516 osd->DrawText(xa00, yt06 - lineHeight, cString::sprintf("-%s", *Event->GetEndTimeString()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder);
1517 }
1518 }
1519}
1520
1522{
1523 int Seen = (Total > 0) ? min(xm08 - xm02, int((xm08 - xm02) * double(Current) / Total)) : 0;
1524 if (initial || Seen != lastSeen) {
1525 int y0 = yc04 - ShowSeenExtent;
1526 int y1 = yc04 + lineHeight / 2 - Gap / 2;
1527 osd->DrawRectangle(xm02, y0, xm02 + Seen - 1, y1 - 1, Theme.Color(clrSeen));
1528 osd->DrawRectangle(xm02 + Seen, y0, xm08 - 1, y1 - 1, Theme.Color(clrBackground));
1529 lastSeen = Seen;
1530 }
1531}
1532
1538
1539void cSkinLCARSDisplayMenu::Scroll(bool Up, bool Page)
1540{
1541 cSkinDisplayMenu::Scroll(Up, Page);
1543}
1544
1546{
1547 if (MenuCategory() == mcMain)
1548 return (ym04 - ym03) / lineHeight;
1549 else
1550 return (yb13 - yt02) / lineHeight;
1551}
1552
1558
1559void cSkinLCARSDisplayMenu::SetTitle(const char *Title)
1560{
1561 if (MenuCategory() != mcMain) {
1562 const cFont *font = cFont::GetFont(fontOsd);
1563 int w = min(font->Width(Title), xa07 - xa06 - Gap);
1564 osd->DrawRectangle(xa06, yt00, xa07 - w - Gap - 1, yt01 - 1, frameColor);
1565 osd->DrawText(xa07 - w - Gap, yt00, Title, Theme.Color(clrMenuTitle), Theme.Color(clrBackground), font, w + Gap, yt01 - yt00, taRight);
1566 }
1567}
1568
1569void cSkinLCARSDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
1570{
1571 const char *lutText[] = { Red, Green, Yellow, Blue };
1572 tColor lutFg[] = { clrButtonRedFg, clrButtonGreenFg, clrButtonYellowFg, clrButtonBlueFg };
1573 tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
1574 const cFont *font = cFont::GetFont(fontSml);
1575 if (MenuCategory() == mcMain) {
1580 }
1581 else {
1582 int h = yb15 - yb14;
1583 osd->DrawText(xb02, yb14, lutText[Setup.ColorKey0], Theme.Color(lutFg[Setup.ColorKey0]), Theme.Color(lutBg[Setup.ColorKey0]), font, xb03 - xb02, h, taLeft | taBorder);
1584 osd->DrawText(xb06, yb14, lutText[Setup.ColorKey1], Theme.Color(lutFg[Setup.ColorKey1]), Theme.Color(lutBg[Setup.ColorKey1]), font, xb07 - xb06, h, taLeft | taBorder);
1585 osd->DrawText(xb10, yb14, lutText[Setup.ColorKey2], Theme.Color(lutFg[Setup.ColorKey2]), Theme.Color(lutBg[Setup.ColorKey2]), font, xb11 - xb10, h, taLeft | taBorder);
1586 osd->DrawText(xb14, yb14, lutText[Setup.ColorKey3], Theme.Color(lutFg[Setup.ColorKey3]), Theme.Color(lutBg[Setup.ColorKey3]), font, xb15 - xb14, h, taLeft | taBorder);
1587 }
1588}
1589
1591{
1592 if (Text) {
1593 osd->SaveRegion(xb00, yb14, xb15 - 1, yb15 - 1);
1594 osd->DrawText(xb00, yb14, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), xb15 - xb00, yb15 - yb14, taCenter);
1595 }
1596 else
1597 osd->RestoreRegion();
1598}
1599
1600void cSkinLCARSDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
1601{
1602 int y = yi00 + Index * lineHeight;
1603 tColor ColorFg, ColorBg;
1604 if (Current) {
1605 if (TwoColors) {
1606 ColorFg = Theme.Color(clrBackground);
1607 ColorBg = Theme.Color(clrMenuFrameBg);
1608 }
1609 else {
1610 ColorFg = Theme.Color(clrMenuItemCurrentFg);
1611 ColorBg = Theme.Color(clrMenuItemCurrentBg);
1612 }
1613 osd->DrawRectangle(xi00, y, xi01 - 1, y + lineHeight - 1, ColorBg);
1614 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, y + lineHeight - 1, ColorBg);
1615 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, y + lineHeight - 1, ColorBg, 5);
1616 currentIndex = Index;
1617 }
1618 else {
1619 ColorFg = Theme.Color(Selectable ? clrMenuItemSelectable : clrMenuItemNonSelectable);
1620 ColorBg = Theme.Color(clrBackground);
1621 if (currentIndex == Index)
1623 }
1624 const cFont *font = cFont::GetFont(fontOsd);
1625 for (int i = 0; i < MaxTabs; i++) {
1626 const char *s = GetTabbedText(Text, i);
1627 if (s) {
1628 int xt = xi00 + TextSpacing + Tab(i);
1629 osd->DrawText(xt, y, s, ColorFg, ColorBg, font, xi01 - xt);
1630 }
1631 if (!Tab(i + 1))
1632 break;
1633 }
1635}
1636
1637void cSkinLCARSDisplayMenu::SetScrollbar(int Total, int Offset)
1638{
1639 DrawScrollbar(Total, Offset, MaxItems(), Offset > 0, Offset + MaxItems() < Total);
1640}
1641
1643{
1644 if (!Event)
1645 return;
1646 const cFont *font = cFont::GetFont(fontOsd);
1647 int xl = xi00;
1648 int y = yi00;
1649 cTextScroller ts;
1650 cString t = cString::sprintf("%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
1651 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, t, font, Theme.Color(clrEventTime), Theme.Color(clrBackground));
1652 if (Event->Vps() && Event->Vps() != Event->StartTime()) {
1653 cString buffer = cString::sprintf(" VPS: %s ", *Event->GetVpsString());
1654 const cFont *font = cFont::GetFont(fontSml);
1655 int w = font->Width(buffer);
1656 osd->DrawText(xi01 - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1657 int yb = y + font->Height();
1658 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor);
1659 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5);
1660 }
1661 y += ts.Height();
1662 if (Event->ParentalRating()) {
1663 cString buffer = cString::sprintf(" %s ", *Event->GetParentalRatingString());
1664 const cFont *font = cFont::GetFont(fontSml);
1665 int w = font->Width(buffer);
1666 osd->DrawText(xi01 - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1667 int yb = y + font->Height();
1668 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor);
1669 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5);
1670 }
1671 y += font->Height();
1672 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Event->Title(), font, Theme.Color(clrEventTitle), Theme.Color(clrBackground));
1673 y += ts.Height();
1674 if (!isempty(Event->ShortText())) {
1675 const cFont *font = cFont::GetFont(fontSml);
1676 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Event->ShortText(), font, Theme.Color(clrEventShortText), Theme.Color(clrBackground));
1677 y += ts.Height();
1678 }
1679 y += font->Height();
1680 if (!isempty(Event->Description())) {
1681 int yt = y;
1682 int yb = yi01;
1683 textScroller.Set(osd, xl, yt, xi01 - xl, yb - yt, Event->Description(), font, Theme.Color(clrEventDescription), Theme.Color(clrBackground));
1685 }
1686}
1687
1689{
1690 if (!Recording)
1691 return;
1692 const cRecordingInfo *Info = Recording->Info();
1693 const cFont *font = cFont::GetFont(fontOsd);
1694 int xl = xi00;
1695 int y = yi00;
1696 cTextScroller ts;
1697 cString t = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), Info->ChannelName() ? Info->ChannelName() : "");
1698 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, t, font, Theme.Color(clrEventTime), Theme.Color(clrBackground));
1699 y += ts.Height();
1700 int xt = xi01;
1701 if (Info->GetEvent()->ParentalRating()) {
1702 cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString());
1703 const cFont *font = cFont::GetFont(fontSml);
1704 int w = font->Width(buffer);
1705 osd->DrawText(xt - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1706 xt -= w + xi02 - xi01;
1707 }
1708 if (Info->Errors() > 0) {
1709 // TRANSLATORS: note the plural/singular!
1710 cString buffer = cString::sprintf(" %d %s ", Info->Errors(), Info->Errors() > 1 ? tr("errors") : tr("error"));
1711 const cFont *font = cFont::GetFont(fontSml);
1712 int w = font->Width(buffer);
1713 osd->DrawText(xt - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w);
1714 xt -= w + xi02 - xi01;
1715 }
1716 if (xt != xi01) {
1717 const cFont *font = cFont::GetFont(fontSml);
1718 int yb = y + font->Height();
1719 osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor);
1720 osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5);
1721 }
1722 y += font->Height();
1723 const char *Title = Info->Title();
1724 if (isempty(Title))
1725 Title = Recording->Name();
1726 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Title, font, Theme.Color(clrEventTitle), Theme.Color(clrBackground));
1727 y += ts.Height();
1728 if (!isempty(Info->ShortText())) {
1729 const cFont *font = cFont::GetFont(fontSml);
1730 ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Info->ShortText(), font, Theme.Color(clrEventShortText), Theme.Color(clrBackground));
1731 y += ts.Height();
1732 }
1733 y += font->Height();
1734 if (!isempty(Info->Description())) {
1735 int yt = y;
1736 int yb = yi01;
1737 cString d = Info->Description();
1738 cString f = Info->FrameParams();
1739 if (*f) {
1740 d.Append("\n\n");
1741 d.Append(f);
1742 }
1743 textScroller.Set(osd, xl, yt, xi01 - xl, yb - yt, d, font, Theme.Color(clrEventDescription), Theme.Color(clrBackground));
1745 }
1746}
1747
1748void cSkinLCARSDisplayMenu::SetText(const char *Text, bool FixedFont)
1749{
1752}
1753
1755{
1756 return xi01 - xi00;
1757}
1758
1760{
1761 const cFont *font = cFont::GetFont(FixedFont ? fontFix : fontOsd);
1762 //XXX -> make a way to let the text define which font to use
1763 return font;
1764}
1765
1767{
1768 if (MenuCategory() == mcMain) {
1769 cDevice *Device = cDevice::PrimaryDevice();
1770 if (!Device->Replaying() || Device->Transferring()) {
1772 const cChannel *Channel = Channels->GetByNumber(cDevice::PrimaryDevice()->CurrentChannel());
1773 DrawLive(Channel);
1774 }
1775 else {
1776 cMutexLock ControlMutexLock;
1777 if (cControl *Control = cControl::Control(ControlMutexLock, true))
1778 DrawPlay(Control);
1779 }
1780 DrawTimers();
1781 DrawDevices();
1783 DrawSignals();
1784 }
1786 osd->Flush();
1787 initial = false;
1788}
1789
1790// --- cSkinLCARSDisplayReplay -----------------------------------------------
1791
1793private:
1804 void DrawDate(void);
1805 void DrawTrack(void);
1806public:
1807 cSkinLCARSDisplayReplay(bool ModeOnly);
1808 virtual ~cSkinLCARSDisplayReplay() override;
1809 virtual void SetRecording(const cRecording *Recording) override;
1810 virtual void SetTitle(const char *Title) override;
1811 virtual void SetMode(bool Play, bool Forward, int Speed) override;
1812 virtual void SetProgress(int Current, int Total) override;
1813 virtual void SetCurrent(const char *Current) override;
1814 virtual void SetTotal(const char *Total) override;
1815 virtual void SetJump(const char *Jump) override;
1816 virtual void SetMessage(eMessageType Type, const char *Text) override;
1817 virtual void Flush(void) override;
1818 };
1819
1821{
1822 const cFont *font = cFont::GetFont(fontOsd);
1823 modeOnly = ModeOnly;
1824 lineHeight = font->Height();
1825 frameColor = Theme.Color(clrReplayFrameBg);
1826 lastCurrentWidth = 0;
1827 lastTotalWidth = 0;
1828 memset(&lastTrackId, 0, sizeof(lastTrackId));
1829 int d = 5 * lineHeight;
1830 xp00 = 0;
1831 xp01 = xp00 + d / 2;
1832 xp02 = xp00 + d;
1833 xp03 = xp02 + lineHeight;
1834 xp04 = xp02 + d / 4;
1835 xp05 = xp02 + d;
1836 xp06 = xp05 + Gap;
1837 xp15 = cOsd::OsdWidth();
1838 xp14 = xp15 - lineHeight;
1839 xp13 = xp14 - Gap;
1840 xp07 = (xp15 + xp00) / 2;
1841 xp08 = xp07 + Gap;
1842 xp09 = xp08 + lineHeight;
1843 xp10 = xp09 + Gap;
1844 xp11 = (xp10 + xp13 + Gap) / 2;
1845 xp12 = xp11 + Gap;
1846
1847 yp00 = 0;
1848 yp01 = yp00 + 2 * lineHeight;
1849 yp02 = yp01 + Gap;
1850 yp03 = yp02 + 2 * lineHeight;
1851
1852 yp04 = yp03 + Gap;
1853 yp09 = yp04 + 3 * lineHeight + Gap / 2;
1854 yp08 = yp09 - lineHeight;
1855 yp07 = yp08 - lineHeight;
1856 yp06 = yp08 - d / 4;
1857 yp05 = yp09 - d / 2;
1858
1861 // Rectangles:
1862 if (!modeOnly)
1865 if (!modeOnly) {
1866 // Elbow:
1869 osd->DrawEllipse (xp00, yp05, xp01 - 1, yp09 - 1, frameColor, 3);
1871 osd->DrawEllipse (xp02, yp06, xp04 - 1, yp08 - 1, frameColor, -3);
1873 // Status area:
1877 osd->DrawRectangle(xp12, yp08, xp13 - 1, yp09 - 1, Theme.Color(clrDateBg));
1880 osd->DrawEllipse (xp14 + lineHeight / 2, yp08, xp15 - 1, yp09 - 1, frameColor, 5);
1881 }
1882}
1883
1888
1890{
1891 cString s = DayDateTime();
1892 if (!*lastDate || strcmp(s, lastDate)) {
1894 lastDate = s;
1895 }
1896}
1897
1899{
1900 cDevice *Device = cDevice::PrimaryDevice();
1901 tTrackId TrackId;
1902 bool Track = Device->GetTrackId(Device->GetCurrentAudioTrack(), TrackId);
1903 if (Track ? strcmp(lastTrackId.description, TrackId.description) : *lastTrackId.description) {
1904 osd->DrawText(xp03, yp04, Track ? TrackId.description : "", Theme.Color(clrTrackName), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xp07 - xp03);
1905 strn0cpy(lastTrackId.description, Track ? TrackId.description : "", sizeof(lastTrackId.description));
1906 }
1907}
1908
1910{
1911 const cRecordingInfo *RecordingInfo = Recording->Info();
1912 SetTitle(RecordingInfo->Title());
1913 osd->DrawText(xp03, yp01 - lineHeight, RecordingInfo->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xp13 - xp03);
1914 osd->DrawText(xp00, yp00, ShortDateString(Recording->Start()), Theme.Color(clrReplayFrameFg), frameColor, cFont::GetFont(fontOsd), xp02 - xp00, 0, taTop | taRight | taBorder);
1916}
1917
1919{
1921}
1922
1923static const char *const *ReplaySymbols[2][2][5] = {
1924 { { pause_xpm, srew_xpm, srew1_xpm, srew2_xpm, srew3_xpm },
1925 { pause_xpm, sfwd_xpm, sfwd1_xpm, sfwd2_xpm, sfwd3_xpm }, },
1926 { { play_xpm, frew_xpm, frew1_xpm, frew2_xpm, frew3_xpm },
1927 { play_xpm, ffwd_xpm, ffwd1_xpm, ffwd2_xpm, ffwd3_xpm } }
1928 };
1929
1930void cSkinLCARSDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
1931{
1932 Speed = constrain(Speed, -1, 3);
1933 cBitmap bm(ReplaySymbols[Play][Forward][Speed + 1]);
1934 osd->DrawBitmap(xp01 - bm.Width() / 2, (yp02 + yp03 - bm.Height()) / 2, bm, Theme.Color(clrReplayFrameFg), frameColor);
1935}
1936
1938{
1939 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));
1940 osd->DrawBitmap(xp03, yp02, pb);
1941}
1942
1944{
1945 const cFont *font = cFont::GetFont(fontOsd);
1946 int w = font->Width(Current);
1947 osd->DrawText(xp03, yp03 - lineHeight, Current, Theme.Color(clrReplayPosition), Theme.Color(clrBackground), font, max(lastCurrentWidth, w), 0, taLeft);
1948 lastCurrentWidth = w;
1949}
1950
1952{
1953 const cFont *font = cFont::GetFont(fontOsd);
1954 int w = font->Width(Total);
1955 osd->DrawText(xp13 - w, yp03 - lineHeight, Total, Theme.Color(clrReplayPosition), Theme.Color(clrBackground), font, max(lastTotalWidth, w), 0, taRight);
1956 lastTotalWidth = w;
1957}
1958
1960{
1961 if (Jump)
1962 osd->DrawText(xp06, yp08, Jump, Theme.Color(clrReplayJumpFg), Theme.Color(clrReplayJumpBg), cFont::GetFont(fontOsd), xp07 - xp06, 0, taCenter);
1963 else
1965}
1966
1968{
1969 if (Text) {
1970 osd->SaveRegion(xp06, yp08, xp13 - 1, yp09 - 1);
1971 osd->DrawText(xp06, yp08, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), xp13 - xp06, yp09 - yp08, taCenter);
1972 }
1973 else
1974 osd->RestoreRegion();
1975}
1976
1978{
1979 if (!modeOnly) {
1980 DrawDate();
1981 DrawTrack();
1982 }
1983 osd->Flush();
1984}
1985
1986// --- cSkinLCARSDisplayVolume -----------------------------------------------
1987
1989private:
1991 int x0, x1, x2, x3, x4, x5, x6, x7;
1992 int y0, y1;
1994 int mute;
1995public:
1997 virtual ~cSkinLCARSDisplayVolume() override;
1998 virtual void SetVolume(int Current, int Total, bool Mute) override;
1999 virtual void Flush(void) override;
2000 };
2001
2003{
2004 const cFont *font = cFont::GetFont(fontOsd);
2005 int lineHeight = font->Height();
2006 frameColor = Theme.Color(clrVolumeFrame);
2007 mute = -1;
2008 x0 = 0;
2009 x1 = lineHeight / 2;
2010 x2 = lineHeight;
2011 x3 = x2 + Gap;
2012 x7 = cOsd::OsdWidth();
2013 x6 = x7 - lineHeight / 2;
2014 x5 = x6 - lineHeight / 2;
2015 x4 = x5 - Gap;
2016 y0 = 0;
2017 y1 = lineHeight;
2018 osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1, x0, y0, x7 - 1, y1 - 1);
2020 osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
2021 osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
2022 osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
2023 osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
2024 osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
2025 osd->DrawRectangle(x6, y0, x7 - 1, y1 - 1, clrTransparent);
2026 osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
2027}
2028
2033
2034void cSkinLCARSDisplayVolume::SetVolume(int Current, int Total, bool Mute)
2035{
2036 int xl = x3 + TextSpacing;
2037 int xr = x4 - TextSpacing;
2038 int yt = y0 + TextFrame;
2039 int yb = y1 - TextFrame;
2040 if (mute != Mute) {
2041 osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
2042 mute = Mute;
2043 }
2044 cBitmap bm(Mute ? mute_xpm : volume_xpm);
2045 osd->DrawBitmap(xl, y0 + (y1 - y0 - bm.Height()) / 2, bm, Theme.Color(clrVolumeSymbol), frameColor);
2046 if (!Mute) {
2047 xl += bm.Width() + TextSpacing;
2048 int w = (y1 - y0) / 3;
2049 int d = TextFrame;
2050 int n = (xr - xl + d) / (w + d);
2051 int x = xr - n * (w + d);
2052 tColor Color = Theme.Color(clrVolumeBarLower);
2053 for (int i = 0; i < n; i++) {
2054 if (Total * i >= Current * n)
2055 Color = Theme.Color(clrVolumeBarUpper);
2056 osd->DrawRectangle(x, yt, x + w - 1, yb - 1, Color);
2057 x += w + d;
2058 }
2059 }
2060}
2061
2063{
2064 osd->Flush();
2065}
2066
2067// --- cSkinLCARSDisplayTracks -----------------------------------------------
2068
2070private:
2078 void SetItem(const char *Text, int Index, bool Current);
2079public:
2080 cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
2081 virtual ~cSkinLCARSDisplayTracks() override;
2082 virtual void SetTrack(int Index, const char * const *Tracks) override;
2083 virtual void SetAudioChannel(int AudioChannel) override;
2084 virtual void Flush(void) override;
2085 };
2086
2090
2091cSkinLCARSDisplayTracks::cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
2092{
2093 const cFont *font = cFont::GetFont(fontOsd);
2094 lineHeight = font->Height();
2095 frameColor = Theme.Color(clrTrackFrameBg);
2096 currentIndex = -1;
2097 xt00 = 0;
2098 xt01 = xt00 + lineHeight / 2;
2099 xt02 = xt01 + Gap;
2100 xt03 = xt00 + 2 * lineHeight;
2101 int ItemsWidth = font->Width(Title) + xt03 - xt02;
2102 for (int i = 0; i < NumTracks; i++)
2103 ItemsWidth = max(ItemsWidth, font->Width(Tracks[i]) + 2 * TextFrame);
2104 xt04 = xt02 + ItemsWidth;
2105 xt05 = xt04 + Gap;
2106 xt06 = xt04 + lineHeight;
2107 xt07 = xt05 + lineHeight;
2108 xt08 = xt07 + lineHeight;
2109 xt09 = xt08 + Gap;
2110 xt10 = xt09 + lineHeight / 2;
2111 xt11 = xt10 + Gap;
2112 xt12 = xt11 + lineHeight;
2113 yt00 = 0;
2114 yt01 = yt00 + lineHeight;
2115 yt02 = yt01 + lineHeight;
2116 yt03 = yt02 + Gap;
2117 yt04 = yt03 + NumTracks * lineHeight + (NumTracks - 1) * Gap;
2118 yt05 = yt04 + Gap;
2119 yt06 = yt05 + lineHeight;
2120 yt07 = yt06 + lineHeight;
2121 while (yt07 > cOsd::OsdHeight()) {
2122 yt04 -= lineHeight + Gap;
2123 yt05 = yt04 + Gap;
2124 yt06 = yt05 + lineHeight;
2125 yt07 = yt06 + lineHeight;
2126 }
2128 // The upper elbow:
2131 osd->DrawEllipse (xt00, yt00, xt03 - 1, yt02 - 1, frameColor, 2);
2134 osd->DrawEllipse (xt04, yt01, xt06 - 1, yt02 - 1, frameColor, -2);
2138 osd->DrawEllipse (xt11 + lineHeight / 2, yt00, xt12 - 1, yt01 - 1, frameColor, 5);
2139 osd->DrawText(xt03, yt00, Title, Theme.Color(clrTrackFrameFg), frameColor, font, xt04 - xt03, 0, taTop | taRight);
2140 // The items:
2141 for (int i = 0; i < NumTracks; i++)
2142 SetItem(Tracks[i], i, false);
2143 // The lower elbow:
2145 osd->DrawEllipse (xt00, yt05, xt03 - 1, yt07 - 1, frameColor, 3);
2148 osd->DrawEllipse (xt04, yt05, xt06 - 1, yt06 - 1, frameColor, -3);
2152 osd->DrawEllipse (xt11 + lineHeight / 2, yt06, xt12 - 1, yt07 - 1, frameColor, 5);
2153}
2154
2159
2160void cSkinLCARSDisplayTracks::SetItem(const char *Text, int Index, bool Current)
2161{
2162 int y0 = yt03 + Index * (lineHeight + Gap);
2163 int y1 = y0 + lineHeight;
2164 if (y1 > yt04)
2165 return;
2166 tColor ColorFg, ColorBg;
2167 if (Current) {
2168 ColorFg = Theme.Color(clrTrackItemCurrentFg);
2169 ColorBg = Theme.Color(clrTrackItemCurrentBg);
2170 osd->DrawRectangle(xt00, y0, xt01 - 1, y1 - 1, frameColor);
2171 osd->DrawRectangle(xt02, y0, xt04 - 1, y1 - 1, ColorBg);
2172 osd->DrawRectangle(xt05, y0, xt05 + lineHeight / 2 - 1, y1 - 1, ColorBg);
2173 osd->DrawEllipse (xt05 + lineHeight / 2, y0, xt07 - 1, y1 - 1, ColorBg, 5);
2174 currentIndex = Index;
2175 }
2176 else {
2177 ColorFg = Theme.Color(clrTrackItemFg);
2178 ColorBg = Theme.Color(clrTrackItemBg);
2179 osd->DrawRectangle(xt00, y0, xt01 - 1, y1 - 1, frameColor);
2180 osd->DrawRectangle(xt02, y0, xt04 - 1, y1 - 1, ColorBg);
2181 if (currentIndex == Index)
2182 osd->DrawRectangle(xt05, y0, xt07 - 1, y1 - 1, Theme.Color(clrBackground));
2183 }
2184 const cFont *font = cFont::GetFont(fontOsd);
2185 osd->DrawText(xt02, y0, Text, ColorFg, ColorBg, font, xt04 - xt02, y1 - y0, taTop | taLeft | taBorder);
2186}
2187
2188void cSkinLCARSDisplayTracks::SetTrack(int Index, const char * const *Tracks)
2189{
2190 if (currentIndex >= 0)
2191 SetItem(Tracks[currentIndex], currentIndex, false);
2192 SetItem(Tracks[Index], Index, true);
2193}
2194
2196{
2197 cBitmap *bm = NULL;
2198 switch (AudioChannel) {
2199 case 0: bm = &bmAudioStereo; break;
2200 case 1: bm = &bmAudioLeft; break;
2201 case 2: bm = &bmAudioRight; break;
2202 default: ;
2203 }
2204 if (bm)
2205 osd->DrawBitmap(xt04 - bm->Width(), (yt06 + yt07 - bm->Height()) / 2, *bm, Theme.Color(clrTrackFrameFg), frameColor);
2206 else
2208}
2209
2211{
2212 osd->Flush();
2213}
2214
2215// --- cSkinLCARSDisplayMessage ----------------------------------------------
2216
2218private:
2220 int x0, x1, x2, x3, x4, x5, x6, x7;
2221 int y0, y1;
2222public:
2224 virtual ~cSkinLCARSDisplayMessage() override;
2225 virtual void SetMessage(eMessageType Type, const char *Text) override;
2226 virtual void Flush(void) override;
2227 };
2228
2230{
2231 const cFont *font = cFont::GetFont(fontOsd);
2232 int lineHeight = font->Height();
2233 x0 = 0;
2234 x1 = lineHeight / 2;
2235 x2 = lineHeight;
2236 x3 = x2 + Gap;
2237 x7 = cOsd::OsdWidth();
2238 x6 = x7 - lineHeight / 2;
2239 x5 = x6 - lineHeight / 2;
2240 x4 = x5 - Gap;
2241 y0 = 0;
2242 y1 = lineHeight;
2243 osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1, x0, y0, x7 - 1, y1 - 1);
2244}
2245
2250
2252{
2253 tColor ColorFg = Theme.Color(clrMessageStatusFg + 2 * Type);
2254 tColor ColorBg = Theme.Color(clrMessageStatusBg + 2 * Type);
2256 osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
2257 osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, ColorBg, 7);
2258 osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, ColorBg);
2259 osd->DrawText(x3, y0, Text, ColorFg, ColorBg, cFont::GetFont(fontSml), x4 - x3, y1 - y0, taCenter);
2260 osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, ColorBg);
2261 osd->DrawRectangle(x6, y0, x7 - 1, y1 - 1, clrTransparent);
2262 osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, ColorBg, 5);
2263}
2264
2266{
2267 osd->Flush();
2268}
2269
2270// --- cSkinLCARS ------------------------------------------------------------
2271
2273:cSkin("lcars", &::Theme)
2274{
2275}
2276
2278{
2279 return "LCARS";
2280}
2281
2283{
2284 return new cSkinLCARSDisplayChannel(WithInfo);
2285}
2286
2291
2293{
2294 return new cSkinLCARSDisplayReplay(ModeOnly);
2295}
2296
2301
2302cSkinDisplayTracks *cSkinLCARS::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
2303{
2304 return new cSkinLCARSDisplayTracks(Title, NumTracks, Tracks);
2305}
2306
cString ChannelString(const cChannel *Channel, int Number)
Definition channels.c:1140
#define LOCK_CHANNELS_READ
Definition channels.h:277
Definition osd.h:170
int Height(void) const
Definition osd.h:190
cBitmap * Scaled(double FactorX, double FactorY, bool AntiAlias=false) const
Creates a copy of this bitmap, scaled by the given factors.
Definition osd.c:838
int Width(void) const
Definition osd.h:189
Definition ci.h:233
int MasterSlotNumber(void)
Returns the number of this CAM's master slot within the whole system.
Definition ci.h:349
int Tpid(void) const
Definition channels.h:179
int Vpid(void) const
Definition channels.h:154
int Source(void) const
Definition channels.h:152
int Number(void) const
Definition channels.h:187
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:189
int Ca(int Index=0) const
Definition channels.h:181
static cControl * Control(cMutexLock &MutexLock, bool Hidden=false, bool *LockedOtherwise=NULL)
Returns the current replay control (if any) in case it is currently visible.
Definition player.c:75
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:117
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:1446
bool GetTrackId(eTrackType Type, tTrackId &TrackId)
Copies the given track id into TrackId and returns true, or returns false if Type is not a valid trac...
Definition device.c:1182
static cDevice * ActualDevice(void)
Returns the actual receiving device in case of Transfer Mode, or the primary device otherwise.
Definition device.c:229
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:237
eTrackType GetCurrentAudioTrack(void) const
Definition device.h:599
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
Definition device.c:168
bool Transferring(void) const
Returns true if we are currently in Transfer Mode.
Definition device.c:1451
virtual int SignalQuality(void) const
Returns the "quality" of the currently received signal.
Definition device.c:817
virtual int SignalStrength(void) const
Returns the "strength" of the currently received signal.
Definition device.c:812
virtual cString DeviceType(void) const
Returns a string identifying the type of this device (like "DVB-S").
Definition device.c:177
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:74
const char * ShortText(void) const
Definition epg.h:109
time_t Vps(void) const
Definition epg.h:117
cString GetDateString(void) const
Definition epg.c:437
const char * Description(void) const
Definition epg.h:110
int ParentalRating(void) const
Definition epg.h:113
time_t StartTime(void) const
Definition epg.h:114
cString GetTimeString(void) const
Definition epg.c:442
const char * Title(void) const
Definition epg.h:108
cString GetEndTimeString(void) const
Definition epg.c:447
int Duration(void) const
Definition epg.h:116
cString GetVpsString(void) const
Definition epg.c:452
cString GetParentalRatingString(void) const
Definition epg.c:430
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:566
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:2318
The cOsd class is the interface to the "On Screen Display".
Definition osd.h:756
static int OsdHeight(void)
Definition osd.h:842
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas)
Sets the sub-areas to the given areas.
Definition osd.c:2116
virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg=0, tColor ColorBg=0, bool ReplacePalette=false, bool Overlay=false)
Sets the pixels in the OSD with the data from the given Bitmap, putting the upper left corner of the ...
Definition osd.c:2234
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:2274
void SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
Allows the system to optimize utilization of the limited color palette entries when generating blende...
Definition osd.c:1983
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas)
Checks whether the OSD can display the given set of sub-areas.
Definition osd.c:2094
static int OsdTop(void)
Definition osd.h:840
virtual void SaveRegion(int x1, int y1, int x2, int y2)
Saves the region defined by the given coordinates for later restoration through RestoreRegion().
Definition osd.c:2151
virtual void Flush(void)
Actually commits all data to the OSD hardware.
Definition osd.c:2294
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:2264
static int OsdLeft(void)
Definition osd.h:839
static int OsdWidth(void)
Definition osd.h:841
virtual void RestoreRegion(void)
Restores the region previously saved by a call to SaveRegion().
Definition osd.c:2169
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:2254
static void Delete(cOsd *&Osd)
Deregisters and deletes the given Osd (if any) and sets it to NULL.
Definition osd.c:1958
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:5960
static cRecordControl * GetRecordControl(const char *FileName)
Definition menu.c:5908
const char * ChannelName(void) const
Definition recording.h:95
const cEvent * GetEvent(void) const
Definition recording.h:96
int Errors(void) const
Definition recording.h:122
const char * ShortText(void) const
Definition recording.h:98
const char * Title(void) const
Definition recording.h:97
cString FrameParams(void) const
Definition recording.c:713
const char * Description(void) const
Definition recording.h:99
const char * Name(void) const
Returns the full name of the recording (without the video directory).
Definition recording.h:179
time_t Start(void) const
Definition recording.h:163
cRecordingInfo * Info(void) const
Definition recording.h:186
int ColorKey3
Definition config.h:330
int ColorKey2
Definition config.h:330
int FontOsdSize
Definition config.h:352
int ColorKey0
Definition config.h:330
char FontOsd[MAXFONTNAME]
Definition config.h:346
int ChannelInfoPos
Definition config.h:338
int ColorKey1
Definition config.h:330
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:111
cTextScroller textScroller
Definition skins.h:174
int Tab(int n)
Returns the offset of the given tab from the left border of the item display area.
Definition skins.h:175
eMenuCategory MenuCategory(void) const
Returns the menu category, set by a previous call to SetMenuCategory().
Definition skins.h:184
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:116
virtual void SetMenuCategory(eMenuCategory MenuCategory)
Sets the current menu category.
Definition skins.c:90
const cErrors * errors
Definition skins.h:321
cSkinDisplayReplay(void)
Definition skins.c:218
const cMarks * marks
< This class implements the progress display used during replay of a recording.
Definition skins.h:320
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) override
Sets the current channel to Channel.
Definition skinlcars.c:538
virtual void SetEvents(const cEvent *Present, const cEvent *Following) override
Sets the Present and Following EPG events.
Definition skinlcars.c:590
void DrawSeen(int Current, int Total)
Definition skinlcars.c:503
static cBitmap bmEncrypted
Definition skinlcars.c:368
static cBitmap bmAudio
Definition skinlcars.c:368
static cBitmap bmRecording
Definition skinlcars.c:368
cSkinLCARSDisplayChannel(bool WithInfo)
Definition skinlcars.c:391
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition skinlcars.c:655
static cBitmap bmDolbyDigital
Definition skinlcars.c:368
static cBitmap bmRadio
Definition skinlcars.c:368
virtual void SetPositioner(const cPositioner *Positioner) override
Sets the Positioner used to move the satellite dish.
Definition skinlcars.c:641
virtual ~cSkinLCARSDisplayChannel() override
Definition skinlcars.c:476
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
Definition skinlcars.c:612
eCurrentMode lastMode
Definition skinlcars.c:711
cVector< bool > deviceRecording
Definition skinlcars.c:704
virtual int MaxItems(void) override
Returns the maximum number of items the menu can display.
Definition skinlcars.c:1545
virtual ~cSkinLCARSDisplayMenu() override
Definition skinlcars.c:956
virtual void Scroll(bool Up, bool Page) override
If this menu contains a text area that can be scrolled, this function will be called to actually scro...
Definition skinlcars.c:1539
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition skinlcars.c:1766
void DrawTextScrollbar(void)
Definition skinlcars.c:1533
bool lastLiveIndicatorTransferring
Definition skinlcars.c:719
void DrawStatusElbows(void)
Definition skinlcars.c:1137
void DrawMenuFrame(void)
Definition skinlcars.c:1039
virtual void SetEvent(const cEvent *Event) override
Sets the Event that shall be displayed, using the entire central area of the menu.
Definition skinlcars.c:1642
virtual void SetRecording(const cRecording *Recording) override
Sets the Recording that shall be displayed, using the entire central area of the menu.
Definition skinlcars.c:1688
virtual void Clear(void) override
Clears the entire central area of the menu.
Definition skinlcars.c:1553
void DrawLiveIndicator(void)
Definition skinlcars.c:1374
void DrawDevice(const cDevice *Device)
Definition skinlcars.c:1347
virtual void SetMenuCategory(eMenuCategory MenuCategory) override
Sets the current menu category.
Definition skinlcars.c:963
virtual const cFont * GetTextAreaFont(bool FixedFont) const override
Returns a pointer to the font which is used to display text with SetText().
Definition skinlcars.c:1759
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable) override
Sets the item at the given Index to Text.
Definition skinlcars.c:1600
virtual void SetTitle(const char *Title) override
Sets the title of this menu to Title.
Definition skinlcars.c:1559
cVector< cCamSlot * > lastCamSlot
Definition skinlcars.c:706
virtual void SetText(const char *Text, bool FixedFont) override
Sets the Text that shall be displayed, using the entire central area of the menu.
Definition skinlcars.c:1748
static cBitmap bmArrowDown
Definition skinlcars.c:726
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:1031
const cRecording * lastRecording
Definition skinlcars.c:723
cString lastDeviceType[MAXDEVICES]
Definition skinlcars.c:705
void DrawLive(const cChannel *Channel)
Definition skinlcars.c:1425
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
Definition skinlcars.c:1590
const cChannel * lastChannel
Definition skinlcars.c:720
void DrawPlay(cControl *Control)
Definition skinlcars.c:1467
void DrawMainFrameLower(void)
Definition skinlcars.c:1012
void DrawSeen(int Current, int Total)
Definition skinlcars.c:1521
virtual void SetScrollbar(int Total, int Offset) override
Sets the Total number of items in the currently displayed list, and the Offset of the first item that...
Definition skinlcars.c:1637
virtual int GetTextAreaWidth(void) const override
Returns the width in pixel of the area which is used to display text with SetText().
Definition skinlcars.c:1754
cVector< int > lastSignalStrength
Definition skinlcars.c:707
void DrawTimer(const cTimer *Timer, int y, bool MultiRec)
Definition skinlcars.c:1210
static cBitmap bmTransferMode
Definition skinlcars.c:726
void DrawInfo(const cEvent *Event, bool WithTime)
Definition skinlcars.c:1506
cStateKey timersStateKey
Definition skinlcars.c:716
void DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown)
Definition skinlcars.c:1171
cVector< int > lastSignalQuality
Definition skinlcars.c:708
void DrawMainBracket(void)
Definition skinlcars.c:1123
const cEvent * lastEvent
Definition skinlcars.c:722
virtual void SetButtons(const char *Red, const char *Green=NULL, const char *Yellow=NULL, const char *Blue=NULL) override
Sets the color buttons to the given strings.
Definition skinlcars.c:1569
void DrawMainFrameUpper(tColor Color)
Definition skinlcars.c:993
void DrawFrameDisplay(void)
Definition skinlcars.c:1155
static cBitmap bmArrowUp
Definition skinlcars.c:726
cVector< int > deviceOffset
Definition skinlcars.c:703
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition skinlcars.c:2265
virtual void SetMessage(eMessageType Type, const char *Text) override
< This class implements a simple message display.
Definition skinlcars.c:2251
virtual ~cSkinLCARSDisplayMessage() override
Definition skinlcars.c:2246
virtual void SetProgress(int Current, int Total) override
This function will be called whenever the position in or the total length of the recording has change...
Definition skinlcars.c:1937
virtual void SetTitle(const char *Title) override
Sets the title of the recording.
Definition skinlcars.c:1918
virtual void SetRecording(const cRecording *Recording) override
Sets the recording that is currently being played.
Definition skinlcars.c:1909
virtual void SetCurrent(const char *Current) override
Sets the current position within the recording, as a user readable string in the form "h:mm:ss....
Definition skinlcars.c:1943
virtual void SetMode(bool Play, bool Forward, int Speed) override
Sets the current replay mode, which can be used to display some indicator, showing the user whether w...
Definition skinlcars.c:1930
virtual void SetJump(const char *Jump) override
Sets the prompt that allows the user to enter a jump point.
Definition skinlcars.c:1959
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
Definition skinlcars.c:1967
virtual ~cSkinLCARSDisplayReplay() override
Definition skinlcars.c:1884
cSkinLCARSDisplayReplay(bool ModeOnly)
Definition skinlcars.c:1820
virtual void SetTotal(const char *Total) override
Sets the total length of the recording, as a user readable string in the form "h:mm:ss".
Definition skinlcars.c:1951
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition skinlcars.c:1977
static cBitmap bmAudioLeft
Definition skinlcars.c:2077
static cBitmap bmAudioRight
Definition skinlcars.c:2077
cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char *const *Tracks)
Definition skinlcars.c:2091
virtual void SetAudioChannel(int AudioChannel) override
Sets the audio channel indicator.
Definition skinlcars.c:2195
static cBitmap bmAudioStereo
Definition skinlcars.c:2077
virtual ~cSkinLCARSDisplayTracks() override
Definition skinlcars.c:2155
void SetItem(const char *Text, int Index, bool Current)
Definition skinlcars.c:2160
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition skinlcars.c:2210
virtual void SetTrack(int Index, const char *const *Tracks) override
< This class implements the track display.
Definition skinlcars.c:2188
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition skinlcars.c:2062
virtual ~cSkinLCARSDisplayVolume() override
Definition skinlcars.c:2029
virtual void SetVolume(int Current, int Total, bool Mute) override
< This class implements the volume/mute display.
Definition skinlcars.c:2034
cSkinLCARS(void)
Definition skinlcars.c:2272
virtual cSkinDisplayChannel * DisplayChannel(bool WithInfo) override
Creates and returns a new object for displaying the current channel.
Definition skinlcars.c:2282
virtual cSkinDisplayMessage * DisplayMessage(void) override
Creates and returns a new object for displaying a message.
Definition skinlcars.c:2307
virtual cSkinDisplayTracks * DisplayTracks(const char *Title, int NumTracks, const char *const *Tracks) override
Creates and returns a new object for displaying the available tracks.
Definition skinlcars.c:2302
virtual cSkinDisplayReplay * DisplayReplay(bool ModeOnly) override
Creates and returns a new object for displaying replay progress.
Definition skinlcars.c:2292
virtual const char * Description(void) override
Returns a user visible, single line description of this skin, which may consist of arbitrary text and...
Definition skinlcars.c:2277
virtual cSkinDisplayMenu * DisplayMenu(void) override
Creates and returns a new object for displaying a menu.
Definition skinlcars.c:2287
virtual cSkinDisplayVolume * DisplayVolume(void) override
Creates and returns a new object for displaying the current volume.
Definition skinlcars.c:2297
cTheme * Theme(void)
Definition skins.h:425
cSkin(const char *Name, cTheme *Theme=NULL)
Creates a new skin class, with the given Name and Theme.
Definition skins.c:241
static cString ToString(int Code)
Definition sources.c:52
void Remove(bool IncState=true)
Removes this key from the lock it was previously used with.
Definition thread.c:904
void Reset(void)
Resets the state of this key, so that the next call to a lock's Lock() function with this key will re...
Definition thread.c:899
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition tools.c:1242
cString & Append(const char *String)
Definition tools.c:1195
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:1226
int Height(void)
Definition osd.h:1103
bool CanScroll(void)
Definition osd.h:1107
int Total(void)
Definition osd.h:1104
int Offset(void)
Definition osd.h:1105
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:2449
void Reset(void)
Definition osd.c:2466
int Shown(void)
Definition osd.h:1106
bool CanScrollDown(void)
Definition osd.h:1109
bool CanScrollUp(void)
Definition osd.h:1108
tColor Color(int Subject)
Returns the color for the given Subject.
Definition themes.c:182
bool Recording(void) const
Definition timers.h:66
time_t StopTimeEvent(void) const
or by the user (for normal timers)
Definition timers.c:855
const cEvent * Event(void) const
Definition timers.h:87
uint Flags(void) const
Definition timers.h:69
const cChannel * Channel(void) const
Definition timers.h:70
bool Pending(void) const
Definition timers.h:67
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:844
const char * Remote(void) const
Definition timers.h:81
static const cTimers * GetTimersRead(cStateKey &StateKey, int TimeoutMs=0)
Gets the list of timers for read access.
Definition timers.c:1318
int Size(void) const
Definition tools.h:773
virtual void Clear(void)
Definition tools.h:828
virtual void Append(T Data)
Definition tools.h:794
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:373
#define VDRVERSION
Definition config.h:25
#define MAXDEVICES
Definition device.h:29
#define LOCK_SCHEDULES_READ
Definition epg.h:232
@ 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:159
@ taBorder
Definition osd.h:164
@ taTop
Definition osd.h:162
@ taBottom
Definition osd.h:163
@ taRight
Definition osd.h:161
@ taLeft
Definition osd.h:160
@ oeOk
Definition osd.h:45
static cTheme Theme
Definition skinclassic.c:21
#define clrTransparent
Definition skincurses.c:36
#define clrBackground
Definition skincurses.c:35
#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:1923
#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:300
int bpp
Definition osd.h:302
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:1348
bool isempty(const char *s)
Definition tools.c:387
cString WeekDayName(int WeekDay)
Converts the given WeekDay (0=Sunday, 1=Monday, ...) to a three letter day name.
Definition tools.c:1265
cString ShortDateString(time_t t)
Converts the given time to a string of the form "dd.mm.yy".
Definition tools.c:1339
cString DateString(time_t t)
Converts the given time to a string of the form "www dd.mm.yyyy".
Definition tools.c:1328
cString DayDateTime(time_t t)
Converts the given time to a string of the form "www dd.mm. hh:mm".
Definition tools.c:1307
char * strn0cpy(char *dest, const char *src, size_t n)
Definition tools.c:128
cString itoa(int n)
Definition tools.c:485
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