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