vdr  2.7.6
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 
21 static cTheme Theme;
22 
24 THEME_CLR(Theme, clrButtonRedFg, clrWhite);
25 THEME_CLR(Theme, clrButtonRedBg, clrRed);
26 THEME_CLR(Theme, clrButtonGreenFg, clrBlack);
27 THEME_CLR(Theme, clrButtonGreenBg, clrGreen);
28 THEME_CLR(Theme, clrButtonYellowFg, clrBlack);
29 THEME_CLR(Theme, clrButtonYellowBg, clrYellow);
30 THEME_CLR(Theme, clrButtonBlueFg, clrWhite);
31 THEME_CLR(Theme, clrButtonBlueBg, clrBlue);
32 THEME_CLR(Theme, clrMessageStatusFg, clrBlack);
33 THEME_CLR(Theme, clrMessageStatusBg, clrCyan);
34 THEME_CLR(Theme, clrMessageInfoFg, clrBlack);
35 THEME_CLR(Theme, clrMessageInfoBg, clrGreen);
36 THEME_CLR(Theme, clrMessageWarningFg, clrBlack);
37 THEME_CLR(Theme, clrMessageWarningBg, clrYellow);
38 THEME_CLR(Theme, clrMessageErrorFg, clrWhite);
39 THEME_CLR(Theme, clrMessageErrorBg, clrRed);
40 THEME_CLR(Theme, clrVolumePrompt, clrGreen);
41 THEME_CLR(Theme, clrVolumeBarUpper, clrWhite);
42 THEME_CLR(Theme, clrVolumeBarLower, clrGreen);
43 THEME_CLR(Theme, clrChannelName, clrWhite);
44 THEME_CLR(Theme, clrChannelDate, clrWhite);
45 THEME_CLR(Theme, clrChannelEpgTimeFg, clrWhite);
46 THEME_CLR(Theme, clrChannelEpgTimeBg, clrRed);
47 THEME_CLR(Theme, clrChannelEpgTitle, clrCyan);
48 THEME_CLR(Theme, clrChannelEpgShortText, clrYellow);
49 THEME_CLR(Theme, clrMenuTitleFg, clrBlack);
50 THEME_CLR(Theme, clrMenuTitleBg, clrCyan);
51 THEME_CLR(Theme, clrMenuDate, clrBlack);
52 THEME_CLR(Theme, clrMenuItemCurrentFg, clrBlack);
53 THEME_CLR(Theme, clrMenuItemCurrentBg, clrCyan);
54 THEME_CLR(Theme, clrMenuItemSelectable, clrWhite);
55 THEME_CLR(Theme, clrMenuItemNonSelectable, clrCyan);
56 THEME_CLR(Theme, clrMenuEventTime, clrWhite);
57 THEME_CLR(Theme, clrMenuEventVpsFg, clrBlack);
58 THEME_CLR(Theme, clrMenuEventVpsBg, clrWhite);
59 THEME_CLR(Theme, clrMenuEventTitle, clrCyan);
60 THEME_CLR(Theme, clrMenuEventShortText, clrWhite);
61 THEME_CLR(Theme, clrMenuEventDescription, clrCyan);
62 THEME_CLR(Theme, clrMenuScrollbarTotal, clrWhite);
63 THEME_CLR(Theme, clrMenuScrollbarShown, clrCyan);
64 THEME_CLR(Theme, clrMenuText, clrWhite);
65 THEME_CLR(Theme, clrReplayTitle, clrWhite);
66 THEME_CLR(Theme, clrReplayCurrent, clrWhite);
67 THEME_CLR(Theme, clrReplayTotal, clrWhite);
68 THEME_CLR(Theme, clrReplayModeJump, clrWhite);
69 THEME_CLR(Theme, clrReplayProgressSeen, clrGreen);
70 THEME_CLR(Theme, clrReplayProgressRest, clrWhite);
71 THEME_CLR(Theme, clrReplayProgressSelected, clrRed);
72 THEME_CLR(Theme, clrReplayProgressMark, clrBlack);
73 THEME_CLR(Theme, clrReplayProgressCurrent, clrRed);
74 THEME_CLR(Theme, clrReplayProgressError, clrBlack);
75 
76 // --- cSkinClassicDisplayChannel --------------------------------------------
77 
79 private:
82  int timeWidth;
83  bool message;
85 public:
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;
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 
113 {
114  delete osd;
115 }
116 
117 void cSkinClassicDisplayChannel::SetChannel(const cChannel *Channel, int Number)
118 {
120  osd->DrawText(TextFrame, 0, ChannelString(Channel, Number), Theme.Color(clrChannelName), Theme.Color(clrBackground), cFont::GetFont(fontOsd));
121  lastDate = NULL;
122 }
123 
124 void cSkinClassicDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
125 {
126  osd->DrawRectangle(0, lineHeight, timeWidth - 1, osd->Height(), Theme.Color(clrChannelEpgTimeBg));
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 
169 private:
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);
181 public:
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();
204  lastDiskUsageState = -1;
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;
213  y5 = cOsd::OsdHeight();
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  }
233 }
234 
236 {
237  delete osd;
238 }
239 
240 void 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())
260 }
261 
262 void cSkinClassicDisplayMenu::Scroll(bool Up, bool Page)
263 {
264  cSkinDisplayMenu::Scroll(Up, Page);
266 }
267 
269 {
270  return (y3 - y2) / lineHeight;
271 }
272 
274 {
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 
286 void cSkinClassicDisplayMenu::SetTitle(const char *Title)
287 {
288  title = Title;
289  DrawTitle();
290 }
291 
292 void 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
317 }
318 
319 void 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 
344 void 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 
437 void 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 {
445 return 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 
471 private:
473  int x0, x1;
474  int y0, y1, y2, y3;
476 public:
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();
493  lastCurrentWidth = 0;
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 
512 {
513  delete osd;
514 }
515 
516 void cSkinClassicDisplayReplay::SetTitle(const char *Title)
517 {
518  osd->DrawText(x0, y0, Title, Theme.Color(clrReplayTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), x1 - x0);
519 }
520 
521 void 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 
537 void cSkinClassicDisplayReplay::SetProgress(int Current, int Total)
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 
543 void cSkinClassicDisplayReplay::SetCurrent(const char *Current)
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);
548  lastCurrentWidth = w;
549 }
550 
551 void cSkinClassicDisplayReplay::SetTotal(const char *Total)
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 
582 private:
584 public:
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 
606 {
607  delete osd;
608 }
609 
610 void 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 
636 private:
638  int x0, x1;
639  int y0, y1, y2;
642  void SetItem(const char *Text, int Index, bool Current);
643 public:
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 
651 cSkinClassicDisplayTracks::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 
684 {
685  delete osd;
686 }
687 
688 void 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 
705 void 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 
720 private:
722 public:
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 
744 {
745  delete osd;
746 }
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 
766 const char *cSkinClassic::Description(void)
767 {
768  return tr("Classic VDR");
769 }
770 
772 {
773  return new cSkinClassicDisplayChannel(WithInfo);
774 }
775 
777 {
778  return new cSkinClassicDisplayMenu;
779 }
780 
782 {
783  return new cSkinClassicDisplayReplay(ModeOnly);
784 }
785 
787 {
788  return new cSkinClassicDisplayVolume;
789 }
790 
791 cSkinDisplayTracks *cSkinClassic::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
792 {
793  return new cSkinClassicDisplayTracks(Title, NumTracks, Tracks);
794 }
795 
797 {
798  return new cSkinClassicDisplayMessage;
799 }
cString ChannelString(const cChannel *Channel, int Number)
Definition: channels.c:1173
Definition: epg.h:73
time_t Vps(void) const
Definition: epg.h:114
cString GetDateString(void) const
Definition: epg.c:431
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
const char * ShortText(void) const
Definition: epg.h:106
cString GetParentalRatingString(void) const
Definition: epg.c:424
const char * Description(void) const
Definition: epg.h:107
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
int Width(void)
Definition: osd.h:844
static int OsdHeight(void)
Definition: osd.h:831
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas)
Sets the sub-areas to the given areas.
Definition: osd.c:2092
virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg=0, tColor ColorBg=0, bool ReplacePalette=false, bool Overlay=false)
Sets the pixels in the OSD with the data from the given Bitmap, putting the upper left corner of the ...
Definition: osd.c:2206
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas)
Checks whether the OSD can display the given set of sub-areas.
Definition: osd.c:2070
static int OsdTop(void)
Definition: osd.h:829
virtual void SaveRegion(int x1, int y1, int x2, int y2)
Saves the region defined by the given coordinates for later restoration through RestoreRegion().
Definition: osd.c:2127
virtual void Flush(void)
Actually commits all data to the OSD hardware.
Definition: osd.c:2266
virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
Draws a filled rectangle defined by the upper left (x1, y1) and lower right (x2, y2) corners with the...
Definition: osd.c:2236
static int OsdLeft(void)
Definition: osd.h:828
static int OsdWidth(void)
Definition: osd.h:830
virtual void RestoreRegion(void)
Restores the region previously saved by a call to SaveRegion().
Definition: osd.c:2143
int Height(void)
Definition: osd.h:845
virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width=0, int Height=0, int Alignment=taDefault)
Draws the given string at coordinates (x, y) with the given foreground and background color and font.
Definition: osd.c:2226
int Errors(void) const
Definition: recording.h:110
const cEvent * GetEvent(void) const
Definition: recording.h:89
const char * ChannelName(void) const
Definition: recording.h:88
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 * ShortText(void) const
Definition: recording.h:91
const char * Name(void) const
Returns the full name of the recording (without the video directory).
Definition: recording.h:164
time_t Start(void) const
Definition: recording.h:149
cRecordingInfo * Info(void) const
Definition: recording.h:171
int ColorKey3
Definition: config.h:332
int ColorKey2
Definition: config.h:332
int AntiAlias
Definition: config.h:344
int ColorKey0
Definition: config.h:332
int ShowReplayMode
Definition: config.h:360
int ChannelInfoPos
Definition: config.h:337
int ColorKey1
Definition: config.h:332
cSkinClassicDisplayChannel(bool WithInfo)
Definition: skinclassic.c:94
virtual void SetEvents(const cEvent *Present, const cEvent *Following) override
Sets the Present and Following EPG events.
Definition: skinclassic.c:124
virtual ~cSkinClassicDisplayChannel() override
Definition: skinclassic.c:112
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
Definition: skinclassic.c:138
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition: skinclassic.c:152
virtual void SetChannel(const cChannel *Channel, int Number) override
Sets the current channel to Channel.
Definition: skinclassic.c:117
virtual void SetScrollbar(int Total, int Offset) override
Sets the Total number of items in the currently displayed list, and the Offset of the first item that...
Definition: skinclassic.c:344
virtual void SetText(const char *Text, bool FixedFont) override
Sets the Text that shall be displayed, using the entire central area of the menu.
Definition: skinclassic.c:437
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition: skinclassic.c:453
virtual const cFont * GetTextAreaFont(bool FixedFont) const
Returns a pointer to the font which is used to display text with SetText().
Definition: skinclassic.c:448
virtual void SetTitle(const char *Title) override
Sets the title of this menu to Title.
Definition: skinclassic.c:286
virtual void Clear(void) override
Clears the entire central area of the menu.
Definition: skinclassic.c:273
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable) override
Sets the item at the given Index to Text.
Definition: skinclassic.c:319
virtual void SetEvent(const cEvent *Event) override
Sets the Event that shall be displayed, using the entire central area of the menu.
Definition: skinclassic.c:349
virtual ~cSkinClassicDisplayMenu() override
Definition: skinclassic.c:235
void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
Definition: skinclassic.c:240
virtual void SetRecording(const cRecording *Recording) override
Sets the Recording that shall be displayed, using the entire central area of the menu.
Definition: skinclassic.c:386
virtual void Scroll(bool Up, bool Page) override
If this menu contains a text area that can be scrolled, this function will be called to actually scro...
Definition: skinclassic.c:262
virtual void SetButtons(const char *Red, const char *Green=NULL, const char *Yellow=NULL, const char *Blue=NULL) override
Sets the color buttons to the given strings.
Definition: skinclassic.c:292
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
Definition: skinclassic.c:310
virtual int GetTextAreaWidth(void) const
Returns the width in pixel of the area which is used to display text with SetText().
Definition: skinclassic.c:443
void SetTextScrollbar(void)
Definition: skinclassic.c:256
virtual int MaxItems(void) override
Returns the maximum number of items the menu can display.
Definition: skinclassic.c:268
virtual void SetMessage(eMessageType Type, const char *Text) override
< This class implements a simple message display.
Definition: skinclassic.c:748
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition: skinclassic.c:754
virtual ~cSkinClassicDisplayMessage() override
Definition: skinclassic.c:743
virtual void SetTotal(const char *Total) override
Sets the total length of the recording, as a user readable string in the form "h:mm:ss".
Definition: skinclassic.c:551
cSkinClassicDisplayReplay(bool ModeOnly)
Definition: skinclassic.c:489
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition: skinclassic.c:574
virtual void SetMessage(eMessageType Type, const char *Text) override
Sets a one line message Text, with the given Type.
Definition: skinclassic.c:563
virtual void SetTitle(const char *Title) override
Sets the title of the recording.
Definition: skinclassic.c:516
virtual void SetProgress(int Current, int Total) override
This function will be called whenever the position in or the total length of the recording has change...
Definition: skinclassic.c:537
virtual void SetMode(bool Play, bool Forward, int Speed) override
Sets the current replay mode, which can be used to display some indicator, showing the user whether w...
Definition: skinclassic.c:521
virtual ~cSkinClassicDisplayReplay() override
Definition: skinclassic.c:511
virtual void SetCurrent(const char *Current) override
Sets the current position within the recording, as a user readable string in the form "h:mm:ss....
Definition: skinclassic.c:543
virtual void SetJump(const char *Jump) override
Sets the prompt that allows the user to enter a jump point.
Definition: skinclassic.c:558
virtual void SetTrack(int Index, const char *const *Tracks) override
< This class implements the track display.
Definition: skinclassic.c:705
void SetItem(const char *Text, int Index, bool Current)
Definition: skinclassic.c:688
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition: skinclassic.c:712
virtual void SetAudioChannel(int AudioChannel)
Sets the audio channel indicator.
Definition: skinclassic.c:647
virtual ~cSkinClassicDisplayTracks() override
Definition: skinclassic.c:683
cSkinClassicDisplayTracks(const char *Title, int NumTracks, const char *const *Tracks)
Definition: skinclassic.c:651
virtual ~cSkinClassicDisplayVolume() override
Definition: skinclassic.c:605
virtual void Flush(void) override
Actually draws the OSD display to the output device.
Definition: skinclassic.c:628
virtual void SetVolume(int Current, int Total, bool Mute) override
< This class implements the volume/mute display.
Definition: skinclassic.c:610
cSkinClassic(void)
Definition: skinclassic.c:761
virtual cSkinDisplayVolume * DisplayVolume(void) override
Creates and returns a new object for displaying the current volume.
Definition: skinclassic.c:786
virtual cSkinDisplayChannel * DisplayChannel(bool WithInfo) override
Creates and returns a new object for displaying the current channel.
Definition: skinclassic.c:771
virtual const char * Description(void) override
Returns a user visible, single line description of this skin, which may consist of arbitrary text and...
Definition: skinclassic.c:766
virtual cSkinDisplayMenu * DisplayMenu(void) override
Creates and returns a new object for displaying a menu.
Definition: skinclassic.c:776
virtual cSkinDisplayReplay * DisplayReplay(bool ModeOnly) override
Creates and returns a new object for displaying replay progress.
Definition: skinclassic.c:781
virtual cSkinDisplayMessage * DisplayMessage(void) override
Creates and returns a new object for displaying a message.
Definition: skinclassic.c:796
virtual cSkinDisplayTracks * DisplayTracks(const char *Title, int NumTracks, const char *const *Tracks) override
Creates and returns a new object for displaying the available tracks.
Definition: skinclassic.c:791
virtual void Scroll(bool Up, bool Page)
If this menu contains a text area that can be scrolled, this function will be called to actually scro...
Definition: skins.c:107
cTextScroller textScroller
Definition: skins.h:173
int Tab(int n)
Returns the offset of the given tab from the left border of the item display area.
Definition: skins.h:174
eMenuCategory MenuCategory(void) const
Returns the menu category, set by a previous call to SetMenuCategory().
Definition: skins.h:183
const char * GetTabbedText(const char *s, int Tab)
Returns the part of the given string that follows the given Tab (where 0 indicates the beginning of t...
Definition: skins.c:112
const cErrors * errors
Definition: skins.h:318
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
Definition: skins.h:402
Definition: tools.h:178
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
bool CanScroll(void)
Definition: osd.h:1092
int Total(void)
Definition: osd.h:1089
int Top(void)
Definition: osd.h:1086
int Offset(void)
Definition: osd.h:1090
void Set(cOsd *Osd, int Left, int Top, int Width, int Height, const char *Text, const cFont *Font, tColor ColorFg, tColor ColorBg)
Definition: osd.c:2421
void Reset(void)
Definition: osd.c:2438
int Shown(void)
Definition: osd.h:1091
bool CanScrollDown(void)
Definition: osd.h:1094
bool CanScrollUp(void)
Definition: osd.h:1093
Definition: themes.h:17
tColor Color(int Subject)
Returns the color for the given Subject.
Definition: themes.c:201
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:29
#define tr(s)
Definition: i18n.h:85
@ taCenter
Definition: osd.h:158
@ oeOk
Definition: osd.h:44
@ clrBlue
Definition: osd.h:39
@ clrWhite
Definition: osd.h:41
@ clrRed
Definition: osd.h:35
@ clrYellow
Definition: osd.h:37
@ clrCyan
Definition: osd.h:40
@ clrBlack
Definition: osd.h:34
@ clrGray50
Definition: osd.h:33
@ clrTransparent
Definition: osd.h:32
@ clrGreen
Definition: osd.h:36
static cTheme Theme
Definition: skinclassic.c:21
THEME_CLR(Theme, clrBackground, clrGray50)
#define TextFrame
Definition: skinclassic.c:18
#define ScrollWidth
Definition: skinclassic.c:17
#define TextSpacing
Definition: skinclassic.c:19
#define clrBackground
Definition: skincurses.c:35
@ mcMain
Definition: skins.h:107
@ mcRecording
Definition: skins.h:115
eMessageType
Definition: skins.h:37
Definition: osd.h:298
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
char * strn0cpy(char *dest, const char *src, size_t n)
Definition: tools.c:131
cString DayDateTime(time_t t)
Converts the given time to a string of the form "www dd.mm. hh:mm".
Definition: tools.c:1260
T min(T a, T b)
Definition: tools.h:63
T max(T a, T b)
Definition: tools.h:64