vdr 2.7.7
skinclassic.c
Go to the documentation of this file.
1/*
2 * skinclassic.c: The 'classic' VDR skin
3 *
4 * See the main source file 'vdr.c' for copyright information and
5 * how to reach the author.
6 *
7 * $Id: skinclassic.c 5.5 2025/03/02 11:03:35 kls Exp $
8 */
9
10#include "skinclassic.h"
11#include "font.h"
12#include "i18n.h"
13#include "osd.h"
14#include "themes.h"
15#include "videodir.h"
16
17#define ScrollWidth (Setup.FontOsdSize / 4)
18#define TextFrame (Setup.FontOsdSize / 10)
19#define TextSpacing (Setup.FontOsdSize / 4)
20
22
24THEME_CLR(Theme, clrButtonRedFg, clrWhite);
25THEME_CLR(Theme, clrButtonRedBg, clrRed);
26THEME_CLR(Theme, clrButtonGreenFg, clrBlack);
27THEME_CLR(Theme, clrButtonGreenBg, clrGreen);
28THEME_CLR(Theme, clrButtonYellowFg, clrBlack);
29THEME_CLR(Theme, clrButtonYellowBg, clrYellow);
30THEME_CLR(Theme, clrButtonBlueFg, clrWhite);
31THEME_CLR(Theme, clrButtonBlueBg, clrBlue);
32THEME_CLR(Theme, clrMessageStatusFg, clrBlack);
33THEME_CLR(Theme, clrMessageStatusBg, clrCyan);
34THEME_CLR(Theme, clrMessageInfoFg, clrBlack);
35THEME_CLR(Theme, clrMessageInfoBg, clrGreen);
36THEME_CLR(Theme, clrMessageWarningFg, clrBlack);
37THEME_CLR(Theme, clrMessageWarningBg, clrYellow);
38THEME_CLR(Theme, clrMessageErrorFg, clrWhite);
39THEME_CLR(Theme, clrMessageErrorBg, clrRed);
40THEME_CLR(Theme, clrVolumePrompt, clrGreen);
41THEME_CLR(Theme, clrVolumeBarUpper, clrWhite);
42THEME_CLR(Theme, clrVolumeBarLower, clrGreen);
43THEME_CLR(Theme, clrChannelName, clrWhite);
44THEME_CLR(Theme, clrChannelDate, clrWhite);
45THEME_CLR(Theme, clrChannelEpgTimeFg, clrWhite);
46THEME_CLR(Theme, clrChannelEpgTimeBg, clrRed);
47THEME_CLR(Theme, clrChannelEpgTitle, clrCyan);
48THEME_CLR(Theme, clrChannelEpgShortText, clrYellow);
49THEME_CLR(Theme, clrMenuTitleFg, clrBlack);
50THEME_CLR(Theme, clrMenuTitleBg, clrCyan);
51THEME_CLR(Theme, clrMenuDate, clrBlack);
52THEME_CLR(Theme, clrMenuItemCurrentFg, clrBlack);
53THEME_CLR(Theme, clrMenuItemCurrentBg, clrCyan);
54THEME_CLR(Theme, clrMenuItemSelectable, clrWhite);
55THEME_CLR(Theme, clrMenuItemNonSelectable, clrCyan);
56THEME_CLR(Theme, clrMenuEventTime, clrWhite);
57THEME_CLR(Theme, clrMenuEventVpsFg, clrBlack);
58THEME_CLR(Theme, clrMenuEventVpsBg, clrWhite);
59THEME_CLR(Theme, clrMenuEventTitle, clrCyan);
60THEME_CLR(Theme, clrMenuEventShortText, clrWhite);
61THEME_CLR(Theme, clrMenuEventDescription, clrCyan);
62THEME_CLR(Theme, clrMenuScrollbarTotal, clrWhite);
63THEME_CLR(Theme, clrMenuScrollbarShown, clrCyan);
64THEME_CLR(Theme, clrMenuText, clrWhite);
65THEME_CLR(Theme, clrReplayTitle, clrWhite);
66THEME_CLR(Theme, clrReplayCurrent, clrWhite);
67THEME_CLR(Theme, clrReplayTotal, clrWhite);
68THEME_CLR(Theme, clrReplayModeJump, clrWhite);
69THEME_CLR(Theme, clrReplayProgressSeen, clrGreen);
70THEME_CLR(Theme, clrReplayProgressRest, clrWhite);
71THEME_CLR(Theme, clrReplayProgressSelected, clrRed);
72THEME_CLR(Theme, clrReplayProgressMark, clrBlack);
73THEME_CLR(Theme, clrReplayProgressCurrent, clrRed);
74THEME_CLR(Theme, clrReplayProgressError, clrBlack);
75
76// --- cSkinClassicDisplayChannel --------------------------------------------
77
79private:
83 bool message;
85public:
86 cSkinClassicDisplayChannel(bool WithInfo);
87 virtual ~cSkinClassicDisplayChannel() override;
88 virtual void SetChannel(const cChannel *Channel, int Number) override;
89 virtual void SetEvents(const cEvent *Present, const cEvent *Following) override;
90 virtual void SetMessage(eMessageType Type, const char *Text) override;
91 virtual void Flush(void) override;
92 };
93
95{
96 int Lines = WithInfo ? 5 : 1;
97 const cFont *font = cFont::GetFont(fontOsd);
98 lineHeight = font->Height();
99 message = false;
100 osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - Lines * lineHeight));
101 timeWidth = font->Width("00:00") + 2 * TextFrame;
102 tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, Lines * lineHeight - 1, 8 } };
103 if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
104 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
105 else {
106 tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, Lines * lineHeight - 1, 4 } };
107 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
108 }
109 osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, Theme.Color(clrBackground));
110}
111
116
117void cSkinClassicDisplayChannel::SetChannel(const cChannel *Channel, int Number)
118{
119 osd->DrawRectangle(0, 0, osd->Width() - 1, lineHeight - 1, Theme.Color(clrBackground));
120 osd->DrawText(TextFrame, 0, ChannelString(Channel, Number), Theme.Color(clrChannelName), Theme.Color(clrBackground), cFont::GetFont(fontOsd));
121 lastDate = NULL;
122}
123
124void cSkinClassicDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
125{
126 osd->DrawRectangle(0, lineHeight, timeWidth - 1, osd->Height(), Theme.Color(clrChannelEpgTimeBg));
127 osd->DrawRectangle(timeWidth, lineHeight, osd->Width() - 1, osd->Height(), Theme.Color(clrBackground));
128 for (int i = 0; i < 2; i++) {
129 const cEvent *e = !i ? Present : Following;
130 if (e) {
131 osd->DrawText( TextFrame, (2 * i + 1) * lineHeight, e->GetTimeString(), Theme.Color(clrChannelEpgTimeFg), Theme.Color(clrChannelEpgTimeBg), cFont::GetFont(fontOsd));
132 osd->DrawText(timeWidth + 2 * TextSpacing, (2 * i + 1) * lineHeight, e->Title(), Theme.Color(clrChannelEpgTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd));
133 osd->DrawText(timeWidth + 2 * TextSpacing, (2 * i + 2) * lineHeight, e->ShortText(), Theme.Color(clrChannelEpgShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml));
134 }
135 }
136}
137
139{
140 const cFont *font = cFont::GetFont(fontOsd);
141 if (Text) {
142 osd->SaveRegion(0, 0, osd->Width() - 1, lineHeight - 1);
143 osd->DrawText(0, 0, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, osd->Width(), 0, taCenter);
144 message = true;
145 }
146 else {
147 osd->RestoreRegion();
148 message = false;
149 }
150}
151
153{
154 if (!message) {
155 cString date = DayDateTime();
156 if (!*lastDate || strcmp(date, lastDate)) {
157 const cFont *font = cFont::GetFont(fontSml);
158 int w = font->Width(date);
159 osd->DrawText(osd->Width() - w - TextFrame, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml), w);
160 lastDate = date;
161 }
162 }
163 osd->Flush();
164}
165
166// --- cSkinClassicDisplayMenu -----------------------------------------------
167
169private:
171 int x0, x1, x2, x3;
172 int y0, y1, y2, y3, y4, y5;
178 void DrawTitle(void);
179 void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown);
180 void SetTextScrollbar(void);
181public:
183 virtual ~cSkinClassicDisplayMenu() override;
184 virtual void Scroll(bool Up, bool Page) override;
185 virtual int MaxItems(void) override;
186 virtual void Clear(void) override;
187 virtual void SetTitle(const char *Title) override;
188 virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL) override;
189 virtual void SetMessage(eMessageType Type, const char *Text) override;
190 virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable) override;
191 virtual void SetScrollbar(int Total, int Offset) override;
192 virtual void SetEvent(const cEvent *Event) override;
193 virtual void SetRecording(const cRecording *Recording) override;
194 virtual void SetText(const char *Text, bool FixedFont) override;
195 virtual int GetTextAreaWidth(void) const;
196 virtual const cFont *GetTextAreaFont(bool FixedFont) const;
197 virtual void Flush(void) override;
198 };
199
201{
202 const cFont *font = cFont::GetFont(fontOsd);
203 lineHeight = font->Height();
205 dateWidth = 0;
206 x0 = 0;
207 x1 = x0 + 2 * TextSpacing;
208 x3 = cOsd::OsdWidth();
209 x2 = x3 - 2 * ScrollWidth;
210 y0 = 0;
211 y1 = lineHeight;
212 y2 = y1 + lineHeight;
214 y4 = y5 - lineHeight;
215 y3 = y4 - lineHeight;
217 tArea Areas[] = { { x0, y0, x3 - 1, y5 - 1, 8 } };
218 if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
219 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
220 else {
221 tArea Areas[] = { { x0, y0, x3 - 1, y5 - 1, 4 } };
222 if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
223 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
224 else {
225 tArea Areas[] = { { x0, y0, x3 - 1, y1 - 1, 2 },
226 { x0, y1, x3 - 1, y3 - 1, 2 },
227 { x0, y3, x3 - 1, y5 - 1, 4 }
228 };
229 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
230 }
231 }
232 osd->DrawRectangle(x0, y0, x3 - 1, y5 - 1, Theme.Color(clrBackground));
233}
234
239
240void cSkinClassicDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
241{
242 if (Total > 0 && Total > Shown) {
243 int yt = Top;
244 int yb = yt + Height;
245 int st = yt;
246 int sb = yb;
247 int th = max(int((sb - st) * double(Shown) / Total + 0.5), ScrollWidth);
248 int tt = min(int(st + (sb - st) * double(Offset) / Total + 0.5), sb - th);
249 int tb = min(tt + th, sb);
250 int xl = x3 - ScrollWidth;
251 osd->DrawRectangle(xl, st, x3 - 1, sb - 1, Theme.Color(clrMenuScrollbarTotal));
252 osd->DrawRectangle(xl, tt, x3 - 1, tb - 1, Theme.Color(clrMenuScrollbarShown));
253 }
254}
255
257{
258 if (textScroller.CanScroll())
259 DrawScrollbar(textScroller.Total(), textScroller.Offset(), textScroller.Shown(), textScroller.Top(), textScroller.Height(), textScroller.CanScrollUp(), textScroller.CanScrollDown());
260}
261
262void cSkinClassicDisplayMenu::Scroll(bool Up, bool Page)
263{
264 cSkinDisplayMenu::Scroll(Up, Page);
266}
267
269{
270 return (y3 - y2) / lineHeight;
271}
272
274{
275 textScroller.Reset();
276 osd->DrawRectangle(x0, y1, x3 - 1, y4 - 1, Theme.Color(clrBackground));
277}
278
280{
281 const cFont *font = cFont::GetFont(fontOsd);
282 bool WithDisk = MenuCategory() == mcMain || MenuCategory() == mcRecording;
283 osd->DrawText(x0, y0, WithDisk ? cString::sprintf("%s - %s", *title, *cVideoDiskUsage::String()) : title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x3 - x0 - dateWidth);
284}
285
287{
288 title = Title;
289 DrawTitle();
290}
291
292void cSkinClassicDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
293{
294 const cFont *font = cFont::GetFont(fontOsd);
295 const char *lutText[] = { Red, Green, Yellow, Blue };
296 tColor lutFg[] = { clrButtonRedFg, clrButtonGreenFg, clrButtonYellowFg, clrButtonBlueFg };
297 tColor lutBg[] = { clrButtonRedBg, clrButtonGreenBg, clrButtonYellowBg, clrButtonBlueBg };
298 int w = x3 - x0;
299 int t0 = x0;
300 int t1 = x0 + w / 4;
301 int t2 = x0 + w / 2;
302 int t3 = x3 - w / 4;
303 int t4 = x3;
304 osd->DrawText(t0, y4, lutText[Setup.ColorKey0], Theme.Color(lutFg[Setup.ColorKey0]), lutText[Setup.ColorKey0] ? Theme.Color(lutBg[Setup.ColorKey0]) : Theme.Color(clrBackground), font, t1 - t0, 0, taCenter);
305 osd->DrawText(t1, y4, lutText[Setup.ColorKey1], Theme.Color(lutFg[Setup.ColorKey1]), lutText[Setup.ColorKey1] ? Theme.Color(lutBg[Setup.ColorKey1]) : Theme.Color(clrBackground), font, t2 - t1, 0, taCenter);
306 osd->DrawText(t2, y4, lutText[Setup.ColorKey2], Theme.Color(lutFg[Setup.ColorKey2]), lutText[Setup.ColorKey2] ? Theme.Color(lutBg[Setup.ColorKey2]) : Theme.Color(clrBackground), font, t3 - t2, 0, taCenter);
307 osd->DrawText(t3, y4, lutText[Setup.ColorKey3], Theme.Color(lutFg[Setup.ColorKey3]), lutText[Setup.ColorKey3] ? Theme.Color(lutBg[Setup.ColorKey3]) : Theme.Color(clrBackground), font, t4 - t3, 0, taCenter);
308}
309
311{
312 const cFont *font = cFont::GetFont(fontOsd);
313 if (Text)
314 osd->DrawText(x0, y3, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x3 - x0, 0, taCenter);
315 else
316 osd->DrawRectangle(x0, y3, x3 - 1, y4 - 1, Theme.Color(clrBackground));
317}
318
319void cSkinClassicDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
320{
321 int y = y2 + Index * lineHeight;
322 tColor ColorFg, ColorBg;
323 if (Current) {
324 ColorFg = Theme.Color(clrMenuItemCurrentFg);
325 ColorBg = Theme.Color(clrMenuItemCurrentBg);
326 }
327 else {
328 ColorFg = Theme.Color(Selectable ? clrMenuItemSelectable : clrMenuItemNonSelectable);
329 ColorBg = Theme.Color(clrBackground);
330 }
331 const cFont *font = cFont::GetFont(fontOsd);
332 for (int i = 0; i < MaxTabs; i++) {
333 const char *s = GetTabbedText(Text, i);
334 if (s) {
335 int xt = x0 + Tab(i);
336 osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x2 - xt);
337 }
338 if (!Tab(i + 1))
339 break;
340 }
341 SetEditableWidth(x2 - x0 - Tab(1));
342}
343
344void cSkinClassicDisplayMenu::SetScrollbar(int Total, int Offset)
345{
346 DrawScrollbar(Total, Offset, MaxItems(), y2, MaxItems() * lineHeight, Offset > 0, Offset + MaxItems() < Total);
347}
348
350{
351 if (!Event)
352 return;
353 const cFont *font = cFont::GetFont(fontOsd);
354 int y = y2;
355 cTextScroller ts;
356 cString t = cString::sprintf("%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
357 ts.Set(osd, x1, y, x2 - x1, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
358 if (Event->Vps() && Event->Vps() != Event->StartTime()) {
359 cString buffer = cString::sprintf(" VPS: %s ", *Event->GetVpsString());
360 const cFont *font = cFont::GetFont(fontSml);
361 int w = font->Width(buffer);
362 osd->DrawText(x3 - w, y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font, w);
363 }
364 y += ts.Height();
365 if (Event->ParentalRating()) {
366 cString buffer = cString::sprintf(" %s ", *Event->GetParentalRatingString());
367 const cFont *font = cFont::GetFont(fontSml);
368 int w = font->Width(buffer);
369 osd->DrawText(x3 - w, y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font, w);
370 }
371 y += font->Height();
372 ts.Set(osd, x1, y, x2 - x1, y3 - y, Event->Title(), font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
373 y += ts.Height();
374 if (!isempty(Event->ShortText())) {
375 const cFont *font = cFont::GetFont(fontSml);
376 ts.Set(osd, x1, y, x2 - x1, y3 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
377 y += ts.Height();
378 }
379 y += font->Height();
380 if (!isempty(Event->Description())) {
381 textScroller.Set(osd, x1, y, x2 - x1, y3 - y, Event->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
383 }
384}
385
387{
388 if (!Recording)
389 return;
390 const cRecordingInfo *Info = Recording->Info();
391 const cFont *font = cFont::GetFont(fontOsd);
392 int y = y2;
393 cTextScroller ts;
394 cString t = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), Info->ChannelName() ? Info->ChannelName() : "");
395 ts.Set(osd, x1, y, x2 - x1, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
396 y += ts.Height();
397 int xt = x3;
398 if (Info->GetEvent()->ParentalRating()) {
399 cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString());
400 const cFont *font = cFont::GetFont(fontSml);
401 int w = font->Width(buffer);
402 osd->DrawText(xt - w, y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font, w);
403 xt -= w + 5;
404 }
405 if (Info->Errors() > 0) {
406 // TRANSLATORS: note the plural/singular!
407 cString buffer = cString::sprintf(" %d %s ", Info->Errors(), Info->Errors() > 1 ? tr("errors") : tr("error"));
408 const cFont *font = cFont::GetFont(fontSml);
409 int w = font->Width(buffer);
410 osd->DrawText(xt - w, y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font, w);
411 xt -= w + 5;
412 }
413 y += font->Height();
414 const char *Title = Info->Title();
415 if (isempty(Title))
416 Title = Recording->Name();
417 ts.Set(osd, x1, y, x2 - x1, y3 - y, Title, font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
418 y += ts.Height();
419 if (!isempty(Info->ShortText())) {
420 const cFont *font = cFont::GetFont(fontSml);
421 ts.Set(osd, x1, y, x2 - x1, y3 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
422 y += ts.Height();
423 }
424 y += font->Height();
425 if (!isempty(Info->Description())) {
426 cString d = Info->Description();
427 cString f = Info->FrameParams();
428 if (*f) {
429 d.Append("\n\n");
430 d.Append(f);
431 }
432 textScroller.Set(osd, x1, y, x2 - x1, y3 - y, d, font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
434 }
435}
436
437void cSkinClassicDisplayMenu::SetText(const char *Text, bool FixedFont)
438{
439 textScroller.Set(osd, x1, y2, GetTextAreaWidth(), y3 - y2, Text, GetTextAreaFont(FixedFont), Theme.Color(clrMenuText), Theme.Color(clrBackground));
441}
442
444{
445return x2 - x1;
446}
447
449{
450 return cFont::GetFont(FixedFont ? fontFix : fontOsd);
451}
452
454{
456 DrawTitle();
457 cString date = DayDateTime();
458 if (!*lastDate || strcmp(date, lastDate)) {
459 const cFont *font = cFont::GetFont(fontOsd);
460 int w = font->Width(date);
461 osd->DrawText(x3 - w - TextFrame, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font, w);
462 lastDate = date;
464 }
465 osd->Flush();
466}
467
468// --- cSkinClassicDisplayReplay ---------------------------------------------
469
471private:
473 int x0, x1;
474 int y0, y1, y2, y3;
476public:
477 cSkinClassicDisplayReplay(bool ModeOnly);
478 virtual ~cSkinClassicDisplayReplay() override;
479 virtual void SetTitle(const char *Title) override;
480 virtual void SetMode(bool Play, bool Forward, int Speed) override;
481 virtual void SetProgress(int Current, int Total) override;
482 virtual void SetCurrent(const char *Current) override;
483 virtual void SetTotal(const char *Total) override;
484 virtual void SetJump(const char *Jump) override;
485 virtual void SetMessage(eMessageType Type, const char *Text) override;
486 virtual void Flush(void) override;
487 };
488
490{
491 const cFont *font = cFont::GetFont(fontOsd);
492 int lineHeight = font->Height();
494 x0 = 0;
495 x1 = cOsd::OsdWidth();
496 y0 = 0;
497 y1 = lineHeight;
498 y2 = 2 * lineHeight;
499 y3 = 3 * lineHeight;
501 tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 8 } };
502 if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
503 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
504 else {
505 tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 4 } };
506 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
507 }
508 osd->DrawRectangle(x0, y0, x1 - 1, y3 - 1, ModeOnly ? clrTransparent : Theme.Color(clrBackground));
509}
510
515
517{
518 osd->DrawText(x0, y0, Title, Theme.Color(clrReplayTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), x1 - x0);
519}
520
521void cSkinClassicDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
522{
523 if (Setup.ShowReplayMode) {
524 const char *Mode;
525 if (Speed == -1) Mode = Play ? " > " : " || ";
526 else if (Play) Mode = Forward ? " X>> " : " <<X ";
527 else Mode = Forward ? " X|> " : " <|X ";
528 char buf[16];
529 strn0cpy(buf, Mode, sizeof(buf));
530 char *p = strchr(buf, 'X');
531 if (p)
532 *p = Speed > 0 ? '1' + Speed - 1 : ' ';
533 SetJump(buf);
534 }
535}
536
538{
539 cProgressBar pb(x1 - x0, y2 - y1, Current, Total, marks, errors, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent), Theme.Color(clrReplayProgressError));
540 osd->DrawBitmap(x0, y1, pb);
541}
542
544{
545 const cFont *font = cFont::GetFont(fontOsd);
546 int w = font->Width(Current);
547 osd->DrawText(x0, y2, Current, Theme.Color(clrReplayCurrent), Theme.Color(clrBackground), font, lastCurrentWidth > w ? lastCurrentWidth : w);
549}
550
552{
553 const cFont *font = cFont::GetFont(fontOsd);
554 int w = font->Width(Total);
555 osd->DrawText(x1 - font->Width(Total), y2, Total, Theme.Color(clrReplayTotal), Theme.Color(clrBackground), font, w);
556}
557
559{
560 osd->DrawText(x0 + (x1 - x0) / 4, y2, Jump, Theme.Color(clrReplayModeJump), Theme.Color(clrBackground), cFont::GetFont(fontOsd), (x1 - x0) / 2, 0, taCenter);
561}
562
564{
565 const cFont *font = cFont::GetFont(fontOsd);
566 if (Text) {
567 osd->SaveRegion(x0, y2, x1 - 1, y3 - 1);
568 osd->DrawText(x0, y2, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x1 - x0, y3 - y2, taCenter);
569 }
570 else
571 osd->RestoreRegion();
572}
573
575{
576 osd->Flush();
577}
578
579// --- cSkinClassicDisplayVolume ---------------------------------------------
580
582private:
584public:
586 virtual ~cSkinClassicDisplayVolume() override;
587 virtual void SetVolume(int Current, int Total, bool Mute) override;
588 virtual void Flush(void) override;
589 };
590
592{
593 const cFont *font = cFont::GetFont(fontOsd);
594 int lineHeight = font->Height();
596 tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 8 } };
597 if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
598 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
599 else {
600 tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 4 } };
601 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
602 }
603}
604
609
610void cSkinClassicDisplayVolume::SetVolume(int Current, int Total, bool Mute)
611{
612 const cFont *font = cFont::GetFont(fontOsd);
613 if (Mute) {
614 osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, clrTransparent);
615 osd->DrawText(0, 0, tr("Key$Mute"), Theme.Color(clrVolumePrompt), Theme.Color(clrBackground), font);
616 }
617 else {
618 // TRANSLATORS: note the trailing blank!
619 const char *Prompt = tr("Volume ");
620 int l = font->Width(Prompt);
621 int p = (osd->Width() - l) * Current / Total;
622 osd->DrawText(0, 0, Prompt, Theme.Color(clrVolumePrompt), Theme.Color(clrBackground), font);
623 osd->DrawRectangle(l, 0, l + p - 1, osd->Height() - 1, Theme.Color(clrVolumeBarLower));
624 osd->DrawRectangle(l + p, 0, osd->Width() - 1, osd->Height() - 1, Theme.Color(clrVolumeBarUpper));
625 }
626}
627
629{
630 osd->Flush();
631}
632
633// --- cSkinClassicDisplayTracks ---------------------------------------------
634
636private:
638 int x0, x1;
639 int y0, y1, y2;
642 void SetItem(const char *Text, int Index, bool Current);
643public:
644 cSkinClassicDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
645 virtual ~cSkinClassicDisplayTracks() override;
646 virtual void SetTrack(int Index, const char * const *Tracks) override;
647 virtual void SetAudioChannel(int AudioChannel) {}
648 virtual void Flush(void) override;
649 };
650
651cSkinClassicDisplayTracks::cSkinClassicDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
652{
653 const cFont *font = cFont::GetFont(fontOsd);
654 lineHeight = font->Height();
655 currentIndex = -1;
656 int ItemsWidth = font->Width(Title);
657 for (int i = 0; i < NumTracks; i++)
658 ItemsWidth = max(ItemsWidth, font->Width(Tracks[i]));
659 ItemsWidth += 2 * TextSpacing;
660 x0 = 0;
661 x1 = cOsd::OsdWidth();
662 int d = x1 - x0;
663 if (d > ItemsWidth) {
664 d = (d - ItemsWidth) & ~0x07; // must be multiple of 8
665 x1 -= d;
666 }
667 y0 = 0;
668 y1 = lineHeight;
669 y2 = y1 + NumTracks * lineHeight;
671 tArea Areas[] = { { x0, y0, x1 - 1, y2 - 1, 8 } };
672 if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
673 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
674 else {
675 tArea Areas[] = { { x0, y0, x1 - 1, y2 - 1, 4 } };
676 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
677 }
678 osd->DrawText(x0, y0, Title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x1 - x0);
679 for (int i = 0; i < NumTracks; i++)
680 SetItem(Tracks[i], i, false);
681}
682
687
688void cSkinClassicDisplayTracks::SetItem(const char *Text, int Index, bool Current)
689{
690 int y = y1 + Index * lineHeight;
691 tColor ColorFg, ColorBg;
692 if (Current) {
693 ColorFg = Theme.Color(clrMenuItemCurrentFg);
694 ColorBg = Theme.Color(clrMenuItemCurrentBg);
695 currentIndex = Index;
696 }
697 else {
698 ColorFg = Theme.Color(clrMenuItemSelectable);
699 ColorBg = Theme.Color(clrBackground);
700 }
701 const cFont *font = cFont::GetFont(fontOsd);
702 osd->DrawText(x0, y, Text, ColorFg, ColorBg, font, x1 - x0);
703}
704
705void cSkinClassicDisplayTracks::SetTrack(int Index, const char * const *Tracks)
706{
707 if (currentIndex >= 0)
708 SetItem(Tracks[currentIndex], currentIndex, false);
709 SetItem(Tracks[Index], Index, true);
710}
711
713{
714 osd->Flush();
715}
716
717// --- cSkinClassicDisplayMessage --------------------------------------------
718
720private:
722public:
724 virtual ~cSkinClassicDisplayMessage() override;
725 virtual void SetMessage(eMessageType Type, const char *Text) override;
726 virtual void Flush(void) override;
727 };
728
730{
731 const cFont *font = cFont::GetFont(fontOsd);
732 int lineHeight = font->Height();
734 tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 8 } };
735 if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
736 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
737 else {
738 tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 2 } };
739 osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
740 }
741}
742
747
749{
750 const cFont *font = cFont::GetFont(fontOsd);
751 osd->DrawText(0, 0, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, cOsd::OsdWidth(), 0, taCenter);
752}
753
755{
756 osd->Flush();
757}
758
759// --- cSkinClassic ----------------------------------------------------------
760
762:cSkin("classic", &::Theme)//XXX naming problem???
763{
764}
765
767{
768 return tr("Classic VDR");
769}
770
772{
773 return new cSkinClassicDisplayChannel(WithInfo);
774}
775
780
782{
783 return new cSkinClassicDisplayReplay(ModeOnly);
784}
785
790
791cSkinDisplayTracks *cSkinClassic::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
792{
793 return new cSkinClassicDisplayTracks(Title, NumTracks, Tracks);
794}
795
cString ChannelString(const cChannel *Channel, int Number)
Definition channels.c:1140
Definition epg.h:73
const char * ShortText(void) const
Definition epg.h:106
time_t Vps(void) const
Definition epg.h:114
cString GetDateString(void) const
Definition epg.c:431
const char * Description(void) const
Definition epg.h:107
int ParentalRating(void) const
Definition epg.h:110
time_t StartTime(void) const
Definition epg.h:111
cString GetTimeString(void) const
Definition epg.c:436
const char * Title(void) const
Definition epg.h:105
cString GetEndTimeString(void) const
Definition epg.c:441
cString GetVpsString(void) const
Definition epg.c:446
cString GetParentalRatingString(void) const
Definition epg.c:424
Definition font.h:37
virtual int Width(void) const =0
Returns the original character width as requested when the font was created, or 0 if the default widt...
virtual int Height(void) const =0
Returns the height of this font in pixel (all characters have the same height).
static const cFont * GetFont(eDvbFont Font)
Gets the given Font, which was previously set by a call to SetFont().
Definition font.c:412
static cOsd * NewOsd(int Left, int Top, uint Level=OSD_LEVEL_DEFAULT)
Returns a pointer to a newly created cOsd object, which will be located at the given coordinates.
Definition osd.c:2290
The cOsd class is the interface to the "On Screen Display".
Definition osd.h:753
static int OsdHeight(void)
Definition osd.h:831
static int OsdTop(void)
Definition osd.h:829
static int OsdLeft(void)
Definition osd.h:828
static int OsdWidth(void)
Definition osd.h:830
const char * ChannelName(void) const
Definition recording.h:88
const cEvent * GetEvent(void) const
Definition recording.h:89
int Errors(void) const
Definition recording.h:110
const char * ShortText(void) const
Definition recording.h:91
const char * Title(void) const
Definition recording.h:90
cString FrameParams(void) const
Definition recording.c:651
const char * Description(void) const
Definition recording.h:92
const char * Name(void) const
Returns the full name of the recording (without the video directory).
Definition recording.h:164
time_t Start(void) const
Definition recording.h:149
cRecordingInfo * Info(void) const
Definition recording.h:171
cSkinClassicDisplayChannel(bool WithInfo)
Definition skinclassic.c:94
virtual void SetEvents(const cEvent *Present, const cEvent *Following) override
Sets the Present and Following EPG events.
virtual ~cSkinClassicDisplayChannel() override
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
virtual void Flush(void) override
Actually draws the OSD display to the output device.
virtual void SetChannel(const cChannel *Channel, int Number) override
Sets the current channel to Channel.
virtual void SetScrollbar(int Total, int Offset) override
Sets the Total number of items in the currently displayed list, and the Offset of the first item that...
virtual void SetText(const char *Text, bool FixedFont) override
Sets the Text that shall be displayed, using the entire central area of the menu.
virtual void Flush(void) override
Actually draws the OSD display to the output device.
virtual const cFont * GetTextAreaFont(bool FixedFont) const
Returns a pointer to the font which is used to display text with SetText().
virtual void SetTitle(const char *Title) override
Sets the title of this menu to Title.
virtual void Clear(void) override
Clears the entire central area of the menu.
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable) override
Sets the item at the given Index to Text.
virtual void SetEvent(const cEvent *Event) override
Sets the Event that shall be displayed, using the entire central area of the menu.
virtual ~cSkinClassicDisplayMenu() override
void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
virtual void SetRecording(const cRecording *Recording) override
Sets the Recording that shall be displayed, using the entire central area of the menu.
virtual void Scroll(bool Up, bool Page) override
If this menu contains a text area that can be scrolled, this function will be called to actually scro...
virtual void SetButtons(const char *Red, const char *Green=NULL, const char *Yellow=NULL, const char *Blue=NULL) override
Sets the color buttons to the given strings.
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
virtual int GetTextAreaWidth(void) const
Returns the width in pixel of the area which is used to display text with SetText().
virtual int MaxItems(void) override
Returns the maximum number of items the menu can display.
virtual void SetMessage(eMessageType Type, const char *Text) override
< This class implements a simple message display.
virtual void Flush(void) override
Actually draws the OSD display to the output device.
virtual ~cSkinClassicDisplayMessage() override
virtual void SetTotal(const char *Total) override
Sets the total length of the recording, as a user readable string in the form "h:mm:ss".
cSkinClassicDisplayReplay(bool ModeOnly)
virtual void Flush(void) override
Actually draws the OSD display to the output device.
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
virtual void SetTitle(const char *Title) override
Sets the title of the recording.
virtual void SetProgress(int Current, int Total) override
This function will be called whenever the position in or the total length of the recording has change...
virtual void SetMode(bool Play, bool Forward, int Speed) override
Sets the current replay mode, which can be used to display some indicator, showing the user whether w...
virtual ~cSkinClassicDisplayReplay() override
virtual void SetCurrent(const char *Current) override
Sets the current position within the recording, as a user readable string in the form "h:mm:ss....
virtual void SetJump(const char *Jump) override
Sets the prompt that allows the user to enter a jump point.
virtual void SetTrack(int Index, const char *const *Tracks) override
< This class implements the track display.
void SetItem(const char *Text, int Index, bool Current)
virtual void Flush(void) override
Actually draws the OSD display to the output device.
virtual void SetAudioChannel(int AudioChannel)
Sets the audio channel indicator.
virtual ~cSkinClassicDisplayTracks() override
cSkinClassicDisplayTracks(const char *Title, int NumTracks, const char *const *Tracks)
virtual ~cSkinClassicDisplayVolume() override
virtual void Flush(void) override
Actually draws the OSD display to the output device.
virtual void SetVolume(int Current, int Total, bool Mute) override
< This class implements the volume/mute display.
cSkinClassic(void)
virtual cSkinDisplayVolume * DisplayVolume(void) override
Creates and returns a new object for displaying the current volume.
virtual cSkinDisplayChannel * DisplayChannel(bool WithInfo) override
Creates and returns a new object for displaying the current channel.
virtual const char * Description(void) override
Returns a user visible, single line description of this skin, which may consist of arbitrary text and...
virtual cSkinDisplayMenu * DisplayMenu(void) override
Creates and returns a new object for displaying a menu.
virtual cSkinDisplayReplay * DisplayReplay(bool ModeOnly) override
Creates and returns a new object for displaying replay progress.
virtual cSkinDisplayMessage * DisplayMessage(void) override
Creates and returns a new object for displaying a message.
virtual cSkinDisplayTracks * DisplayTracks(const char *Title, int NumTracks, const char *const *Tracks) override
Creates and returns a new object for displaying the available tracks.
cSkinDisplayChannel(void)
Definition skins.c:68
virtual void Scroll(bool Up, bool Page)
If this menu contains a text area that can be scrolled, this function will be called to actually scro...
Definition skins.c:107
cTextScroller textScroller
Definition skins.h:173
int Tab(int n)
Returns the offset of the given tab from the left border of the item display area.
Definition skins.h:174
eMenuCategory MenuCategory(void) const
Returns the menu category, set by a previous call to SetMenuCategory().
Definition skins.h:183
cSkinDisplayMenu(void)
Definition skins.c:84
const char * GetTabbedText(const char *s, int Tab)
Returns the part of the given string that follows the given Tab (where 0 indicates the beginning of t...
Definition skins.c:112
const cErrors * errors
Definition skins.h:318
cSkinDisplayReplay(void)
Definition skins.c:214
const cMarks * marks
< This class implements the progress display used during replay of a recording.
Definition skins.h:317
static cSkinDisplay * Current(void)
Returns the currently active cSkinDisplay.
Definition skins.h:61
void SetEditableWidth(int Width)
If an item is set through a call to cSkinDisplayMenu::SetItem(), this function shall be called to set...
Definition skins.h:49
cTheme * Theme(void)
Definition skins.h:422
cSkin(const char *Name, cTheme *Theme=NULL)
Creates a new skin class, with the given Name and Theme.
Definition skins.c:237
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition tools.c:1195
cString & Append(const char *String)
Definition tools.c:1148
int Height(void)
Definition osd.h:1088
void Set(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg)
Definition osd.c:2421
static bool HasChanged(int &State)
Returns true if the usage of the video disk space has changed since the last call to this function wi...
Definition videodir.c:210
static cString String(void)
Returns a localized string of the form "Disk nn% - hh:mm free".
Definition videodir.c:234
cSetup Setup
Definition config.c:372
@ fontOsd
Definition font.h:22
@ fontFix
Definition font.h:23
uint32_t tColor
Definition font.h:30
#define tr(s)
Definition i18n.h:85
@ taCenter
Definition osd.h:158
@ oeOk
Definition osd.h:44
@ clrGray50
Definition osd.h:33
static cTheme Theme
Definition skinclassic.c:21
#define TextFrame
Definition skinclassic.c:18
#define ScrollWidth
Definition skinclassic.c:17
#define TextSpacing
Definition skinclassic.c:19
#define clrBlue
Definition skincurses.c:41
#define clrTransparent
Definition skincurses.c:36
#define clrBlack
Definition skincurses.c:37
#define clrWhite
Definition skincurses.c:44
#define clrGreen
Definition skincurses.c:39
#define clrRed
Definition skincurses.c:38
#define clrYellow
Definition skincurses.c:40
#define clrBackground
Definition skincurses.c:35
#define clrCyan
Definition skincurses.c:43
@ mcMain
Definition skins.h:107
@ mcRecording
Definition skins.h:115
eMessageType
Definition skins.h:37
Definition osd.h:298
#define THEME_CLR(Theme, Subject, Color)
Definition themes.h:59
cString TimeString(time_t t)
Converts the given time to a string of the form "hh:mm".
Definition tools.c:1301
bool isempty(const char *s)
Definition tools.c:357
cString DateString(time_t t)
Converts the given time to a string of the form "www dd.mm.yyyy".
Definition tools.c:1281
cString DayDateTime(time_t t)
Converts the given time to a string of the form "www dd.mm. hh:mm".
Definition tools.c:1260
char * strn0cpy(char *dest, const char *src, size_t n)
Definition tools.c:131
T min(T a, T b)
Definition tools.h:63
T max(T a, T b)
Definition tools.h:64