vdr  2.0.6
skincurses.c
Go to the documentation of this file.
1 /*
2  * skincurses.c: A plugin for the Video Disk Recorder
3  *
4  * See the README file for copyright information and how to reach the author.
5  *
6  * $Id: skincurses.c 2.13 2013/03/31 09:30:18 kls Exp $
7  */
8 
9 #include <ncurses.h>
10 #include <vdr/osd.h>
11 #include <vdr/plugin.h>
12 #include <vdr/skins.h>
13 #include <vdr/videodir.h>
14 
15 static const char *VERSION = "2.0.0";
16 static const char *DESCRIPTION = trNOOP("A text only skin");
17 static const char *MAINMENUENTRY = NULL;
18 
19 // --- cCursesFont -----------------------------------------------------------
20 
21 class cCursesFont : public cFont {
22 public:
23  virtual int Width(uint c) const { return 1; }
24  virtual int Width(const char *s) const { return s ? Utf8StrLen(s) : 0; }
25  virtual int Height(void) const { return 1; }
26  virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
27  virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
28  };
29 
30 static const cCursesFont Font = cCursesFont(); // w/o the '= cCursesFont()' gcc 4.6 complains - can anybody explain why this is necessary?
31 
32 // --- cCursesOsd ------------------------------------------------------------
33 
34 #define clrBackground COLOR_BLACK
35 #define clrTransparent clrBackground
36 #define clrBlack clrBackground
37 #define clrRed COLOR_RED
38 #define clrGreen COLOR_GREEN
39 #define clrYellow COLOR_YELLOW
40 #define clrBlue COLOR_BLUE
41 #define clrMagenta COLOR_MAGENTA
42 #define clrCyan COLOR_CYAN
43 #define clrWhite COLOR_WHITE
44 
45 static int clrMessage[] = {
46  clrBlack,
47  clrCyan,
48  clrBlack,
49  clrGreen,
50  clrBlack,
51  clrYellow,
52  clrWhite,
53  clrRed
54  };
55 
56 static int ScOsdWidth = 50;
57 static int ScOsdHeight = 20;
58 
59 class cCursesOsd : public cOsd {
60 private:
61  WINDOW *savedRegion;
62  WINDOW *window;
63  enum { MaxColorPairs = 16 };
65  void SetColor(int colorFg, int colorBg = clrBackground);
66 public:
67  cCursesOsd(int Left, int Top);
68  virtual ~cCursesOsd();
69  virtual void SaveRegion(int x1, int y1, int x2, int y2);
70  virtual void RestoreRegion(void);
71  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);
72  virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
73  virtual void Flush(void);
74  };
75 
76 cCursesOsd::cCursesOsd(int Left, int Top)
77 :cOsd(Left, Top, 0)
78 {
79  savedRegion = NULL;
80 
81  memset(colorPairs, 0x00, sizeof(colorPairs));
82  start_color();
83  leaveok(stdscr, true);
84 
85  window = subwin(stdscr, ScOsdHeight, ScOsdWidth, 0, 0);
86  syncok(window, true);
87 }
88 
90 {
91  if (window) {
92  werase(window);
93  Flush();
94  delwin(window);
95  window = NULL;
96  }
97 }
98 
99 void cCursesOsd::SetColor(int colorFg, int colorBg)
100 {
101  int color = (colorBg << 16) | colorFg | 0x80000000;
102  for (int i = 0; i < MaxColorPairs; i++) {
103  if (!colorPairs[i]) {
104  colorPairs[i] = color;
105  init_pair(i + 1, colorFg, colorBg);
106  //XXX??? attron(COLOR_PAIR(WHITE_ON_BLUE));
107  wattrset(window, COLOR_PAIR(i + 1));
108  break;
109  }
110  else if (color == colorPairs[i]) {
111  wattrset(window, COLOR_PAIR(i + 1));
112  break;
113  }
114  }
115 }
116 
117 void cCursesOsd::SaveRegion(int x1, int y1, int x2, int y2)
118 {
119  if (savedRegion) {
120  delwin(savedRegion);
121  savedRegion = NULL;
122  }
123  savedRegion = newwin(y2 - y1 + 1, x2 - x1 + 1, y1, x1);
124  copywin(window, savedRegion, y1, x1, 0, 0, y2 - y1, x2 - x1, false);
125 }
126 
128 {
129  if (savedRegion) {
130  copywin(savedRegion, window, 0, 0, savedRegion->_begy, savedRegion->_begx, savedRegion->_maxy - savedRegion->_begy, savedRegion->_maxx - savedRegion->_begx, false);
131  delwin(savedRegion);
132  savedRegion = NULL;
133  }
134 }
135 
136 void cCursesOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment)
137 {
138  int w = Font->Width(s);
139  int h = Font->Height();
140  if (Width || Height) {
141  int cw = Width ? Width : w;
142  int ch = Height ? Height : h;
143  DrawRectangle(x, y, x + cw - 1, y + ch - 1, ColorBg);
144  if (Width) {
145  if ((Alignment & taLeft) != 0)
146  ;
147  else if ((Alignment & taRight) != 0) {
148  if (w < Width)
149  x += Width - w;
150  }
151  else { // taCentered
152  if (w < Width)
153  x += (Width - w) / 2;
154  }
155  }
156  if (Height) {
157  if ((Alignment & taTop) != 0)
158  ;
159  else if ((Alignment & taBottom) != 0) {
160  if (h < Height)
161  y += Height - h;
162  }
163  else { // taCentered
164  if (h < Height)
165  y += (Height - h) / 2;
166  }
167  }
168  }
169  SetColor(ColorFg, ColorBg);
170  wmove(window, y, x); // ncurses wants 'y' before 'x'!
171  waddnstr(window, s, Width ? Width : ScOsdWidth - x);
172 }
173 
174 void cCursesOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
175 {
176  SetColor(Color, Color);
177  for (int y = y1; y <= y2; y++) {
178  wmove(window, y, x1); // ncurses wants 'y' before 'x'!
179  whline(window, ' ', x2 - x1 + 1);
180  }
181  wsyncup(window); // shouldn't be necessary because of 'syncok()', but w/o it doesn't work
182 }
183 
185 {
186  refresh();
187 }
188 
189 // --- cSkinCursesDisplayChannel ---------------------------------------------
190 
192 private:
195  bool message;
196 public:
197  cSkinCursesDisplayChannel(bool WithInfo);
198  virtual ~cSkinCursesDisplayChannel();
199  virtual void SetChannel(const cChannel *Channel, int Number);
200  virtual void SetEvents(const cEvent *Present, const cEvent *Following);
201  virtual void SetMessage(eMessageType Type, const char *Text);
202  virtual void Flush(void);
203  };
204 
206 {
207  int Lines = WithInfo ? 5 : 1;
208  message = false;
209  osd = new cCursesOsd(0, Setup.ChannelInfoPos ? 0 : ScOsdHeight - Lines);
210  timeWidth = strlen("00:00");
211  osd->DrawRectangle(0, 0, ScOsdWidth - 1, Lines - 1, clrBackground);
212 }
213 
215 {
216  delete osd;
217 }
218 
219 void cSkinCursesDisplayChannel::SetChannel(const cChannel *Channel, int Number)
220 {
221  osd->DrawRectangle(0, 0, ScOsdWidth - 1, 0, clrBackground);
222  osd->DrawText(0, 0, ChannelString(Channel, Number), clrWhite, clrBackground, &Font);
223 }
224 
225 void cSkinCursesDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
226 {
227  osd->DrawRectangle(0, 1, timeWidth - 1, 4, clrRed);
229  for (int i = 0; i < 2; i++) {
230  const cEvent *e = !i ? Present : Following;
231  if (e) {
232  osd->DrawText( 0, 2 * i + 1, e->GetTimeString(), clrWhite, clrRed, &Font);
233  osd->DrawText(timeWidth + 1, 2 * i + 1, e->Title(), clrCyan, clrBackground, &Font);
234  osd->DrawText(timeWidth + 1, 2 * i + 2, e->ShortText(), clrYellow, clrBackground, &Font);
235  }
236  }
237 }
238 
240 {
241  if (Text) {
242  osd->SaveRegion(0, 0, ScOsdWidth - 1, 0);
243  osd->DrawText(0, 0, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, ScOsdWidth, 0, taCenter);
244  message = true;
245  }
246  else {
247  osd->RestoreRegion();
248  message = false;
249  }
250 }
251 
253 {
254  if (!message) {
255  cString date = DayDateTime();
256  osd->DrawText(ScOsdWidth - Utf8StrLen(date), 0, date, clrWhite, clrBackground, &Font);
257  }
258  osd->Flush();
259 }
260 
261 // --- cSkinCursesDisplayMenu ------------------------------------------------
262 
264 private:
268  void DrawTitle(void);
269  void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown);
270  void SetTextScrollbar(void);
271 public:
273  virtual ~cSkinCursesDisplayMenu();
274  virtual void Scroll(bool Up, bool Page);
275  virtual int MaxItems(void);
276  virtual void Clear(void);
277  virtual void SetTitle(const char *Title);
278  virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
279  virtual void SetMessage(eMessageType Type, const char *Text);
280  virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
281  virtual void SetScrollbar(int Total, int Offset);
282  virtual void SetEvent(const cEvent *Event);
283  virtual void SetRecording(const cRecording *Recording);
284  virtual void SetText(const char *Text, bool FixedFont);
285  virtual const cFont *GetTextAreaFont(bool FixedFont) const { return &Font; }
286  virtual void Flush(void);
287  };
288 
290 {
291  osd = new cCursesOsd(0, 0);
292  lastDiskUsageState = -1;
294 }
295 
297 {
298  delete osd;
299 }
300 
301 void cSkinCursesDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
302 {
303  if (Total > 0 && Total > Shown) {
304  int yt = Top;
305  int yb = yt + Height;
306  int st = yt;
307  int sb = yb;
308  int th = max(int((sb - st) * double(Shown) / Total + 0.5), 1);
309  int tt = min(int(st + (sb - st) * double(Offset) / Total + 0.5), sb - th);
310  int tb = min(tt + th, sb);
311  int xl = ScOsdWidth - 1;
312  osd->DrawRectangle(xl, st, xl, sb - 1, clrWhite);
313  osd->DrawRectangle(xl, tt, xl, tb - 1, clrCyan);
314  }
315 }
316 
318 {
319  if (textScroller.CanScroll())
321 }
322 
323 void cSkinCursesDisplayMenu::Scroll(bool Up, bool Page)
324 {
325  cSkinDisplayMenu::Scroll(Up, Page);
327 }
328 
330 {
331  return ScOsdHeight - 4;
332 }
333 
335 {
338 }
339 
341 {
342  bool WithDisk = MenuCategory() == mcMain || MenuCategory() == mcRecording;
343  osd->DrawText(0, 0, WithDisk ? cString::sprintf("%s - %s", *title, *cVideoDiskUsage::String()) : title, clrBlack, clrCyan, &Font, ScOsdWidth);
344 }
345 
346 void cSkinCursesDisplayMenu::SetTitle(const char *Title)
347 {
348  title = Title;
349  DrawTitle();
350 }
351 
352 void cSkinCursesDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
353 {
354  int w = ScOsdWidth;
355  int t0 = 0;
356  int t1 = 0 + w / 4;
357  int t2 = 0 + w / 2;
358  int t3 = w - w / 4;
359  int t4 = w;
360  int y = ScOsdHeight - 1;
361  osd->DrawText(t0, y, Red, clrWhite, Red ? clrRed : clrBackground, &Font, t1 - t0, 0, taCenter);
362  osd->DrawText(t1, y, Green, clrBlack, Green ? clrGreen : clrBackground, &Font, t2 - t1, 0, taCenter);
363  osd->DrawText(t2, y, Yellow, clrBlack, Yellow ? clrYellow : clrBackground, &Font, t3 - t2, 0, taCenter);
364  osd->DrawText(t3, y, Blue, clrWhite, Blue ? clrBlue : clrBackground, &Font, t4 - t3, 0, taCenter);
365 }
366 
368 {
369  if (Text)
370  osd->DrawText(0, ScOsdHeight - 2, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, ScOsdWidth, 0, taCenter);
371  else
373 }
374 
375 void cSkinCursesDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
376 {
377  int y = 2 + Index;
378  int ColorFg, ColorBg;
379  if (Current) {
380  ColorFg = clrBlack;
381  ColorBg = clrCyan;
382  }
383  else {
384  ColorFg = Selectable ? clrWhite : clrCyan;
385  ColorBg = clrBackground;
386  }
387  for (int i = 0; i < MaxTabs; i++) {
388  const char *s = GetTabbedText(Text, i);
389  if (s) {
390  int xt = Tab(i) / AvgCharWidth();// Tab() is in "pixel" - see also skins.c!!!
391  osd->DrawText(xt, y, s, ColorFg, ColorBg, &Font, ScOsdWidth - 2 - xt);
392  }
393  if (!Tab(i + 1))
394  break;
395  }
396  SetEditableWidth(ScOsdWidth - 2 - Tab(1) / AvgCharWidth()); // Tab() is in "pixel" - see also skins.c!!!
397 }
398 
399 void cSkinCursesDisplayMenu::SetScrollbar(int Total, int Offset)
400 {
401  DrawScrollbar(Total, Offset, MaxItems(), 2, MaxItems(), Offset > 0, Offset + MaxItems() < Total);
402 }
403 
405 {
406  if (!Event)
407  return;
408  int y = 2;
409  cTextScroller ts;
410  char t[32];
411  snprintf(t, sizeof(t), "%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
412  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
413  if (Event->Vps() && Event->Vps() != Event->StartTime()) {
414  cString buffer = cString::sprintf(" VPS: %s", *Event->GetVpsString());
415  osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font);
416  }
417  y += ts.Height();
418  if (Event->ParentalRating()) {
419  cString buffer = cString::sprintf(" %s ", *Event->GetParentalRatingString());
420  osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font);
421  }
422  y += 1;
423  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Event->Title(), &Font, clrCyan, clrBackground);
424  y += ts.Height();
425  if (!isempty(Event->ShortText())) {
426  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Event->ShortText(), &Font, clrYellow, clrBackground);
427  y += ts.Height();
428  }
429  for (int i = 0; Event->Contents(i); i++) {
430  const char *s = Event->ContentToString(Event->Contents(i));
431  if (!isempty(s)) {
432  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, s, &Font, clrYellow, clrBackground);
433  y += 1;
434  }
435  }
436  y += 1;
437  if (!isempty(Event->Description())) {
438  textScroller.Set(osd, 0, y, ScOsdWidth - 2, ScOsdHeight - y - 2, Event->Description(), &Font, clrCyan, clrBackground);
440  }
441 }
442 
444 {
445  if (!Recording)
446  return;
447  const cRecordingInfo *Info = Recording->Info();
448  int y = 2;
449  cTextScroller ts;
450  cString t = cString::sprintf("%s %s %s", *DateString(Recording->Start()), *TimeString(Recording->Start()), Info->ChannelName() ? Info->ChannelName() : "");
451  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, t, &Font, clrYellow, clrBackground);
452  y += ts.Height();
453  if (Info->GetEvent()->ParentalRating()) {
454  cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString());
455  osd->DrawText(ScOsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font);
456  }
457  y += 1;
458  const char *Title = Info->Title();
459  if (isempty(Title))
460  Title = Recording->Name();
461  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Title, &Font, clrCyan, clrBackground);
462  y += ts.Height();
463  if (!isempty(Info->ShortText())) {
464  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, Info->ShortText(), &Font, clrYellow, clrBackground);
465  y += ts.Height();
466  }
467  for (int i = 0; Info->GetEvent()->Contents(i); i++) {
468  const char *s = Info->GetEvent()->ContentToString(Info->GetEvent()->Contents(i));
469  if (!isempty(s)) {
470  ts.Set(osd, 0, y, ScOsdWidth, ScOsdHeight - y - 2, s, &Font, clrYellow, clrBackground);
471  y += 1;
472  }
473  }
474  y += 1;
475  if (!isempty(Info->Description())) {
476  textScroller.Set(osd, 0, y, ScOsdWidth - 2, ScOsdHeight - y - 2, Info->Description(), &Font, clrCyan, clrBackground);
478  }
479 }
480 
481 void cSkinCursesDisplayMenu::SetText(const char *Text, bool FixedFont)
482 {
483  textScroller.Set(osd, 0, 2, ScOsdWidth - 2, ScOsdHeight - 4, Text, &Font, clrWhite, clrBackground);
485 }
486 
488 {
490  DrawTitle();
491  cString date = DayDateTime();
492  osd->DrawText(ScOsdWidth - Utf8StrLen(date) - 2, 0, date, clrBlack, clrCyan, &Font);
493  osd->Flush();
494 }
495 
496 // --- cSkinCursesDisplayReplay ----------------------------------------------
497 
499 private:
501  bool message;
502 public:
503  cSkinCursesDisplayReplay(bool ModeOnly);
504  virtual ~cSkinCursesDisplayReplay();
505  virtual void SetTitle(const char *Title);
506  virtual void SetMode(bool Play, bool Forward, int Speed);
507  virtual void SetProgress(int Current, int Total);
508  virtual void SetCurrent(const char *Current);
509  virtual void SetTotal(const char *Total);
510  virtual void SetJump(const char *Jump);
511  virtual void SetMessage(eMessageType Type, const char *Text);
512  virtual void Flush(void);
513  };
514 
516 {
517  message = false;
518  osd = new cCursesOsd(0, ScOsdHeight - 3);
519  osd->DrawRectangle(0, 0, ScOsdWidth - 1, 2, ModeOnly ? clrTransparent : clrBackground);
520 }
521 
523 {
524  delete osd;
525 }
526 
527 void cSkinCursesDisplayReplay::SetTitle(const char *Title)
528 {
529  osd->DrawText(0, 0, Title, clrWhite, clrBackground, &Font, ScOsdWidth);
530 }
531 
532 void cSkinCursesDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
533 {
534  if (Setup.ShowReplayMode) {
535  const char *Mode;
536  if (Speed == -1) Mode = Play ? " > " : " || ";
537  else if (Play) Mode = Forward ? " X>> " : " <<X ";
538  else Mode = Forward ? " X|> " : " <|X ";
539  char buf[16];
540  strn0cpy(buf, Mode, sizeof(buf));
541  char *p = strchr(buf, 'X');
542  if (p)
543  *p = Speed > 0 ? '1' + Speed - 1 : ' ';
544  SetJump(buf);
545  }
546 }
547 
548 void cSkinCursesDisplayReplay::SetProgress(int Current, int Total)
549 {
550  int p = Total > 0 ? ScOsdWidth * Current / Total : 0;
551  osd->DrawRectangle(0, 1, p, 1, clrGreen);
552  osd->DrawRectangle(p, 1, ScOsdWidth, 1, clrWhite);
553 }
554 
555 void cSkinCursesDisplayReplay::SetCurrent(const char *Current)
556 {
557  osd->DrawText(0, 2, Current, clrWhite, clrBackground, &Font, Utf8StrLen(Current) + 3);
558 }
559 
560 void cSkinCursesDisplayReplay::SetTotal(const char *Total)
561 {
562  osd->DrawText(ScOsdWidth - Utf8StrLen(Total), 2, Total, clrWhite, clrBackground, &Font);
563 }
564 
565 void cSkinCursesDisplayReplay::SetJump(const char *Jump)
566 {
567  osd->DrawText(ScOsdWidth / 4, 2, Jump, clrWhite, clrBackground, &Font, ScOsdWidth / 2, 0, taCenter);
568 }
569 
571 {
572  if (Text) {
573  osd->SaveRegion(0, 2, ScOsdWidth - 1, 2);
574  osd->DrawText(0, 2, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, ScOsdWidth, 0, taCenter);
575  message = true;
576  }
577  else {
578  osd->RestoreRegion();
579  message = false;
580  }
581 }
582 
584 {
585  osd->Flush();
586 }
587 
588 // --- cSkinCursesDisplayVolume ----------------------------------------------
589 
591 private:
593 public:
595  virtual ~cSkinCursesDisplayVolume();
596  virtual void SetVolume(int Current, int Total, bool Mute);
597  virtual void Flush(void);
598  };
599 
601 {
602  osd = new cCursesOsd(0, ScOsdHeight - 1);
603 }
604 
606 {
607  delete osd;
608 }
609 
610 void cSkinCursesDisplayVolume::SetVolume(int Current, int Total, bool Mute)
611 {
612  if (Mute) {
613  osd->DrawRectangle(0, 0, ScOsdWidth - 1, 0, clrTransparent);
614  osd->DrawText(0, 0, tr("Key$Mute"), clrGreen, clrBackground, &Font);
615  }
616  else {
617  const char *Prompt = tr("Volume ");
618  int l = Utf8StrLen(Prompt);
619  int p = (ScOsdWidth - l) * Current / Total;
620  osd->DrawText(0, 0, Prompt, clrGreen, clrBackground, &Font);
621  osd->DrawRectangle(l, 0, l + p - 1, 0, clrGreen);
622  osd->DrawRectangle(l + p, 0, ScOsdWidth - 1, 0, clrWhite);
623  }
624 }
625 
627 {
628  osd->Flush();
629 }
630 
631 // --- cSkinCursesDisplayTracks ----------------------------------------------
632 
634 private:
638  void SetItem(const char *Text, int Index, bool Current);
639 public:
640  cSkinCursesDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
641  virtual ~cSkinCursesDisplayTracks();
642  virtual void SetTrack(int Index, const char * const *Tracks);
643  virtual void SetAudioChannel(int AudioChannel) {}
644  virtual void Flush(void);
645  };
646 
647 cSkinCursesDisplayTracks::cSkinCursesDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
648 {
649  currentIndex = -1;
650  itemsWidth = Font.Width(Title);
651  for (int i = 0; i < NumTracks; i++)
652  itemsWidth = max(itemsWidth, Font.Width(Tracks[i]));
654  osd = new cCursesOsd(0, 0);
656  osd->DrawText(0, 0, Title, clrBlack, clrCyan, &Font, itemsWidth);
657  for (int i = 0; i < NumTracks; i++)
658  SetItem(Tracks[i], i, false);
659 }
660 
662 {
663  delete osd;
664 }
665 
666 void cSkinCursesDisplayTracks::SetItem(const char *Text, int Index, bool Current)
667 {
668  int y = 1 + Index;
669  int ColorFg, ColorBg;
670  if (Current) {
671  ColorFg = clrBlack;
672  ColorBg = clrCyan;
673  currentIndex = Index;
674  }
675  else {
676  ColorFg = clrWhite;
677  ColorBg = clrBackground;
678  }
679  osd->DrawText(0, y, Text, ColorFg, ColorBg, &Font, itemsWidth);
680 }
681 
682 void cSkinCursesDisplayTracks::SetTrack(int Index, const char * const *Tracks)
683 {
684  if (currentIndex >= 0)
685  SetItem(Tracks[currentIndex], currentIndex, false);
686  SetItem(Tracks[Index], Index, true);
687 }
688 
690 {
691  osd->Flush();
692 }
693 
694 // --- cSkinCursesDisplayMessage ---------------------------------------------
695 
697 private:
699 public:
701  virtual ~cSkinCursesDisplayMessage();
702  virtual void SetMessage(eMessageType Type, const char *Text);
703  virtual void Flush(void);
704  };
705 
707 {
708  osd = new cCursesOsd(0, ScOsdHeight - 1);
709 }
710 
712 {
713  delete osd;
714 }
715 
717 {
718  osd->DrawText(0, 0, Text, clrMessage[2 * Type], clrMessage[2 * Type + 1], &Font, ScOsdWidth, 0, taCenter);
719 }
720 
722 {
723  osd->Flush();
724 }
725 
726 // --- cSkinCurses -----------------------------------------------------------
727 
728 class cSkinCurses : public cSkin {
729 public:
730  cSkinCurses(void);
731  virtual const char *Description(void);
732  virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo);
733  virtual cSkinDisplayMenu *DisplayMenu(void);
734  virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly);
735  virtual cSkinDisplayVolume *DisplayVolume(void);
736  virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
737  virtual cSkinDisplayMessage *DisplayMessage(void);
738  };
739 
741 :cSkin("curses")
742 {
743 }
744 
745 const char *cSkinCurses::Description(void)
746 {
747  return tr("Text mode");
748 }
749 
751 {
752  return new cSkinCursesDisplayChannel(WithInfo);
753 }
754 
756 {
757  return new cSkinCursesDisplayMenu;
758 }
759 
761 {
762  return new cSkinCursesDisplayReplay(ModeOnly);
763 }
764 
766 {
767  return new cSkinCursesDisplayVolume;
768 }
769 
770 cSkinDisplayTracks *cSkinCurses::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
771 {
772  return new cSkinCursesDisplayTracks(Title, NumTracks, Tracks);
773 }
774 
776 {
777  return new cSkinCursesDisplayMessage;
778 }
779 
780 // --- cPluginSkinCurses -----------------------------------------------------
781 
782 class cPluginSkinCurses : public cPlugin {
783 private:
784  // Add any member variables or functions you may need here.
785 public:
786  cPluginSkinCurses(void);
787  virtual ~cPluginSkinCurses();
788  virtual const char *Version(void) { return VERSION; }
789  virtual const char *Description(void) { return tr(DESCRIPTION); }
790  virtual const char *CommandLineHelp(void);
791  virtual bool ProcessArgs(int argc, char *argv[]);
792  virtual bool Initialize(void);
793  virtual bool Start(void);
794  virtual void Housekeeping(void);
795  virtual const char *MainMenuEntry(void) { return tr(MAINMENUENTRY); }
796  virtual cOsdObject *MainMenuAction(void);
797  virtual cMenuSetupPage *SetupMenu(void);
798  virtual bool SetupParse(const char *Name, const char *Value);
799  };
800 
802 {
803  // Initialize any member variables here.
804  // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
805  // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
806 }
807 
809 {
810  // Clean up after yourself!
811  endwin();
812 }
813 
815 {
816  // Return a string that describes all known command line options.
817  return NULL;
818 }
819 
820 bool cPluginSkinCurses::ProcessArgs(int argc, char *argv[])
821 {
822  // Implement command line argument processing here if applicable.
823  return true;
824 }
825 
827 {
828  // Initialize any background activities the plugin shall perform.
829  WINDOW *w = initscr();
830  if (w) {
831  ScOsdWidth = w->_maxx - w->_begx + 1;
832  ScOsdHeight = w->_maxy - w->_begy + 1;
833  return true;
834  }
835  return false;
836 }
837 
839 {
840  // Start any background activities the plugin shall perform.
841  cSkin *Skin = new cSkinCurses;
842  // This skin is normally used for debugging, so let's make it the current one:
843  Skins.SetCurrent(Skin->Name());
844  return true;
845 }
846 
848 {
849  // Perform any cleanup or other regular tasks.
850 }
851 
853 {
854  // Perform the action when selected from the main VDR menu.
855  return NULL;
856 }
857 
859 {
860  // Return a setup menu in case the plugin supports one.
861  return NULL;
862 }
863 
864 bool cPluginSkinCurses::SetupParse(const char *Name, const char *Value)
865 {
866  // Parse your own setup parameters and store their values.
867  return false;
868 }
869 
870 VDRPLUGINCREATOR(cPluginSkinCurses); // Don't touch this!
#define clrRed
Definition: skincurses.c:37
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
static int AvgCharWidth(void)
Returns the average width of a character in pixel (just a raw estimate).
Definition: skins.h:32
virtual cSkinDisplayVolume * DisplayVolume(void)
Creates and returns a new object for displaying the current volume.
Definition: skincurses.c:765
Definition: epg.h:71
eMessageType
Definition: skins.h:23
virtual void SetTrack(int Index, const char *const *Tracks)
< This class implements the track display.
Definition: skincurses.c:682
virtual ~cSkinCursesDisplayMenu()
Definition: skincurses.c:296
Definition: osd.h:450
#define clrWhite
Definition: skincurses.c:43
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: skincurses.c:136
bool isempty(const char *s)
Definition: tools.c:248
VDRPLUGINCREATOR(cPluginSkinCurses)
int Utf8StrLen(const char *s)
Returns the number of UTF-8 symbols formed by the given string of character bytes.
Definition: tools.c:784
cCursesOsd(int Left, int Top)
Definition: skincurses.c:76
virtual bool SetupParse(const char *Name, const char *Value)
Definition: skincurses.c:864
virtual ~cPluginSkinCurses()
Definition: skincurses.c:808
time_t Start(void) const
Definition: recording.h:113
static int clrMessage[]
Definition: skincurses.c:45
static cString String(void)
Returns a localized string of the form "Disk nn% - hh:mm free".
Definition: videodir.c:300
const cRecordingInfo * Info(void) const
Definition: recording.h:121
time_t Vps(void) const
Definition: epg.h:109
void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
Definition: skincurses.c:301
const char * Name(void)
Definition: plugin.h:34
const char * ShortText(void) const
Definition: recording.h:71
virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
Definition: skincurses.c:27
static const char * VERSION
Definition: skincurses.c:15
static const char * ContentToString(uchar Content)
Definition: epg.c:260
cString GetParentalRatingString(void) const
Definition: epg.c:402
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable)
Sets the item at the given Index to Text.
Definition: skincurses.c:375
static int ScOsdHeight
Definition: skincurses.c:57
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition: tools.c:1011
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
Definition: plugin.h:20
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition: skincurses.c:721
char * strn0cpy(char *dest, const char *src, size_t n)
Definition: tools.c:131
virtual const char * Description(void)
Returns a user visible, single line description of this skin, which may consist of arbitrary text and...
Definition: skincurses.c:745
uchar Contents(int i=0) const
Definition: epg.h:104
eMenuCategory MenuCategory(void) const
Returns the menu category, set by a previous call to SetMenuCategory().
Definition: skins.h:141
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition: skincurses.c:487
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: skincurses.c:219
T max(T a, T b)
Definition: tools.h:55
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
cSkinCursesDisplayReplay(bool ModeOnly)
Definition: skincurses.c:515
virtual const char * CommandLineHelp(void)
Definition: skincurses.c:814
static cSkinDisplay * Current(void)
Returns the currently active cSkinDisplay.
Definition: skins.h:47
const char * Name(void)
Definition: skins.h:361
time_t StartTime(void) const
Definition: epg.h:106
int ShowReplayMode
Definition: config.h:335
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition: skincurses.c:583
T min(T a, T b)
Definition: tools.h:54
cString ChannelString(const cChannel *Channel, int Number)
Definition: channels.c:1079
virtual cSkinDisplayMenu * DisplayMenu(void)
Creates and returns a new object for displaying a menu.
Definition: skincurses.c:755
virtual void SetTitle(const char *Title)
Sets the title of the recording.
Definition: skincurses.c:527
#define clrTransparent
Definition: skincurses.c:35
virtual void Flush(void)
Actually commits all data to the OSD hardware.
Definition: osd.c:1949
Definition: osd.h:158
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition: skincurses.c:252
virtual bool ProcessArgs(int argc, char *argv[])
Definition: skincurses.c:820
Definition: osd.h:169
int Height(void)
Definition: osd.h:1013
#define clrBackground
Definition: skincurses.c:34
virtual ~cSkinCursesDisplayVolume()
Definition: skincurses.c:605
virtual cOsdObject * MainMenuAction(void)
Definition: skincurses.c:852
cPluginSkinCurses(void)
Definition: skincurses.c:801
virtual cMenuSetupPage * SetupMenu(void)
Definition: skincurses.c:858
virtual void SetMessage(eMessageType Type, const char *Text)
Sets a one line message Text, with the given Type.
Definition: skincurses.c:367
static int ScOsdWidth
Definition: skincurses.c:56
void SetColor(int colorFg, int colorBg=clrBackground)
Definition: skincurses.c:99
virtual const char * MainMenuEntry(void)
Definition: skincurses.c:795
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const
Draws the given text into the Bitmap at position (x, y) with the given colors.
Definition: skincurses.c:26
virtual const char * Version(void)
Definition: skincurses.c:788
Definition: osd.h:161
cString GetVpsString(void) const
Definition: epg.c:424
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition: skincurses.c:689
virtual const char * Description(void)
Definition: skincurses.c:789
virtual int Height(void) const =0
Returns the height of this font in pixel (all characters have the same height).
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: skincurses.c:117
WINDOW * window
Definition: skincurses.c:62
int ParentalRating(void) const
Definition: epg.h:105
int Top(void)
Definition: osd.h:796
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: skincurses.c:555
virtual cSkinDisplayChannel * DisplayChannel(bool WithInfo)
Creates and returns a new object for displaying the current channel.
Definition: skincurses.c:750
virtual void SetMessage(eMessageType Type, const char *Text)
< This class implements a simple message display.
Definition: skincurses.c:716
virtual bool Initialize(void)
Definition: skincurses.c:826
cTextScroller textScroller
Definition: skins.h:131
#define clrBlack
Definition: skincurses.c:36
virtual int Height(void) const
Returns the height of this font in pixel (all characters have the same height).
Definition: skincurses.c:25
#define trNOOP(s)
Definition: i18n.h:88
WINDOW * savedRegion
Definition: skincurses.c:61
void SetTextScrollbar(void)
Definition: skincurses.c:317
cSkinCursesDisplayTracks(const char *Title, int NumTracks, const char *const *Tracks)
Definition: skincurses.c:647
int ChannelInfoPos
Definition: config.h:311
virtual void SetAudioChannel(int AudioChannel)
Sets the audio channel indicator.
Definition: skincurses.c:643
Definition: osd.h:162
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition: skincurses.c:626
Definition: osd.h:164
cSkinCursesDisplayChannel(bool WithInfo)
Definition: skincurses.c:205
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: skincurses.c:174
virtual void SetText(const char *Text, bool FixedFont)
Sets the Text that shall be displayed, using the entire central area of the menu. ...
Definition: skincurses.c:481
cSkinCurses(void)
Definition: skincurses.c:740
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
#define clrGreen
Definition: skincurses.c:38
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 ~cSkinCursesDisplayReplay()
Definition: skincurses.c:522
static const cCursesFont Font
Definition: skincurses.c:30
The cOsd class is the interface to the "On Screen Display".
Definition: osd.h:716
int Top(void)
Definition: osd.h:1011
Definition: skins.h:79
static const char * DESCRIPTION
Definition: skincurses.c:16
cSetup Setup
Definition: config.c:373
void SetItem(const char *Text, int Index, bool Current)
Definition: skincurses.c:666
bool CanScroll(void)
Definition: osd.h:1017
virtual ~cSkinCursesDisplayChannel()
Definition: skincurses.c:214
cString DayDateTime(time_t t)
Converts the given time to a string of the form "www dd.mm. hh:mm".
Definition: tools.c:1076
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
virtual void SetEvent(const cEvent *Event)
Sets the Event that shall be displayed, using the entire central area of the menu.
Definition: skincurses.c:404
Definition: skins.h:342
virtual void Housekeeping(void)
Definition: skincurses.c:847
virtual int MaxItems(void)
Returns the maximum number of items the menu can display.
Definition: skincurses.c:329
bool CanScrollUp(void)
Definition: osd.h:1018
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: skincurses.c:352
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
int Height(void)
Definition: osd.h:798
const char * Title(void) const
Definition: epg.h:100
virtual void RestoreRegion(void)
Restores the region previously saved by a call to SaveRegion().
Definition: skincurses.c:127
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: skincurses.c:239
virtual void Clear(void)
Clears the entire central area of the menu.
Definition: skincurses.c:334
virtual void SetEvents(const cEvent *Present, const cEvent *Following)
Sets the Present and Following EPG events.
Definition: skincurses.c:225
virtual void SetMessage(eMessageType Type, const char *Text)
Sets a one line message Text, with the given Type.
Definition: skincurses.c:570
virtual void SetTitle(const char *Title)
Sets the title of this menu to Title.
Definition: skincurses.c:346
void Reset(void)
Definition: osd.c:2110
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: skincurses.c:560
virtual int Width(uint c) const
Returns the width of the given character in pixel.
Definition: skincurses.c:23
int Width(void)
Definition: osd.h:797
virtual void SetJump(const char *Jump)
Sets the prompt that allows the user to enter a jump point.
Definition: skincurses.c:565
virtual void SetVolume(int Current, int Total, bool Mute)
< This class implements the volume/mute display.
Definition: skincurses.c:610
Definition: osd.h:159
#define tr(s)
Definition: i18n.h:85
virtual int Width(const char *s) const
Returns the width of the given string in pixel.
Definition: skincurses.c:24
int Left(void)
Definition: osd.h:795
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
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: skincurses.c:323
#define clrBlue
Definition: skincurses.c:40
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: skincurses.c:532
const char * Title(void) const
Definition: recording.h:70
virtual const cFont * GetTextAreaFont(bool FixedFont) const
Returns a pointer to the font which is used to display text with SetText().
Definition: skincurses.c:285
const char * Description(void) const
Definition: epg.h:102
Definition: osd.h:160
virtual int Width(uint c) const =0
Returns the width of the given character in pixel.
#define clrCyan
Definition: skincurses.c:42
virtual void Flush(void)
Actually commits all data to the OSD hardware.
Definition: skincurses.c:184
virtual void RestoreRegion(void)
Restores the region previously saved by a call to SaveRegion().
Definition: osd.c:1848
virtual void SetRecording(const cRecording *Recording)
Sets the Recording that shall be displayed, using the entire central area of the menu.
Definition: skincurses.c:443
const char * ChannelName(void) const
Definition: recording.h:68
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: skincurses.c:399
#define clrYellow
Definition: skincurses.c:39
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: skincurses.c:548
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
int colorPairs[MaxColorPairs]
Definition: skincurses.c:64
cString GetDateString(void) const
Definition: epg.c:409
const char * ShortText(void) const
Definition: epg.h:101
static const char * MAINMENUENTRY
Definition: skincurses.c:17
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
bool SetCurrent(const char *Name=NULL)
Sets the current skin to the one indicated by name.
Definition: skins.c:215
Definition: font.h:37
virtual bool Start(void)
Definition: skincurses.c:838
virtual cSkinDisplayMessage * DisplayMessage(void)
Creates and returns a new object for displaying a message.
Definition: skincurses.c:775
int Offset(void)
Definition: osd.h:1015
Definition: tools.h:166
virtual cSkinDisplayTracks * DisplayTracks(const char *Title, int NumTracks, const char *const *Tracks)
Creates and returns a new object for displaying the available tracks.
Definition: skincurses.c:770
cString DateString(time_t t)
Converts the given time to a string of the form "www dd.mm.yyyy".
Definition: tools.c:1097
virtual ~cSkinCursesDisplayTracks()
Definition: skincurses.c:661
virtual ~cSkinCursesDisplayMessage()
Definition: skincurses.c:711
virtual cSkinDisplayReplay * DisplayReplay(bool ModeOnly)
Creates and returns a new object for displaying replay progress.
Definition: skincurses.c:760
virtual ~cCursesOsd()
Definition: skincurses.c:89
uint32_t tColor
Definition: font.h:29
bool CanScrollDown(void)
Definition: osd.h:1019
cSkins Skins
Definition: skins.c:203
int Total(void)
Definition: osd.h:1014