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