vdr  1.7.27
skinsttng.c
Go to the documentation of this file.
00001 /*
00002  * skinsttng.c: A VDR skin with ST:TNG Panels
00003  *
00004  * See the main source file 'vdr.c' for copyright information and
00005  * how to reach the author.
00006  *
00007  * $Id: skinsttng.c 2.14 2012/03/11 14:06:05 kls Exp $
00008  */
00009 
00010 // "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures
00011 // registered in the United States Patent and Trademark Office.
00012 // No infringement intended.
00013 
00014 #include "skinsttng.h"
00015 #include "font.h"
00016 #include "osd.h"
00017 #include "menu.h"
00018 #include "themes.h"
00019 
00020 #include "symbols/arrowdown.xpm"
00021 #include "symbols/arrowup.xpm"
00022 #include "symbols/audio.xpm"
00023 #include "symbols/audioleft.xpm"
00024 #include "symbols/audioright.xpm"
00025 #include "symbols/audiostereo.xpm"
00026 #include "symbols/dolbydigital.xpm"
00027 #include "symbols/encrypted.xpm"
00028 #include "symbols/ffwd.xpm"
00029 #include "symbols/ffwd1.xpm"
00030 #include "symbols/ffwd2.xpm"
00031 #include "symbols/ffwd3.xpm"
00032 #include "symbols/frew.xpm"
00033 #include "symbols/frew1.xpm"
00034 #include "symbols/frew2.xpm"
00035 #include "symbols/frew3.xpm"
00036 #include "symbols/mute.xpm"
00037 #include "symbols/pause.xpm"
00038 #include "symbols/play.xpm"
00039 #include "symbols/radio.xpm"
00040 #include "symbols/recording.xpm"
00041 #include "symbols/sfwd.xpm"
00042 #include "symbols/sfwd1.xpm"
00043 #include "symbols/sfwd2.xpm"
00044 #include "symbols/sfwd3.xpm"
00045 #include "symbols/srew.xpm"
00046 #include "symbols/srew1.xpm"
00047 #include "symbols/srew2.xpm"
00048 #include "symbols/srew3.xpm"
00049 #include "symbols/teletext.xpm"
00050 #include "symbols/volume.xpm"
00051 
00052 #define Roundness     (Setup.FontOsdSize / 2)
00053 #define Gap           (Setup.FontOsdSize / 5)
00054 #define ScrollWidth   (Setup.FontOsdSize / 4)
00055 #define TextFrame     (Setup.FontOsdSize / 10)
00056 #define TextSpacing   (Setup.FontOsdSize / 4)
00057 #define SymbolSpacing (Setup.FontOsdSize / 4)
00058 
00059 static cTheme Theme;
00060 
00061 THEME_CLR(Theme, clrBackground,             clrGray50);
00062 THEME_CLR(Theme, clrButtonRedFg,            clrWhite);
00063 THEME_CLR(Theme, clrButtonRedBg,            clrRed);
00064 THEME_CLR(Theme, clrButtonGreenFg,          clrBlack);
00065 THEME_CLR(Theme, clrButtonGreenBg,          clrGreen);
00066 THEME_CLR(Theme, clrButtonYellowFg,         clrBlack);
00067 THEME_CLR(Theme, clrButtonYellowBg,         clrYellow);
00068 THEME_CLR(Theme, clrButtonBlueFg,           clrWhite);
00069 THEME_CLR(Theme, clrButtonBlueBg,           clrBlue);
00070 THEME_CLR(Theme, clrMessageFrame,           clrYellow);
00071 THEME_CLR(Theme, clrMessageStatusFg,        clrBlack);
00072 THEME_CLR(Theme, clrMessageStatusBg,        clrCyan);
00073 THEME_CLR(Theme, clrMessageInfoFg,          clrBlack);
00074 THEME_CLR(Theme, clrMessageInfoBg,          clrGreen);
00075 THEME_CLR(Theme, clrMessageWarningFg,       clrBlack);
00076 THEME_CLR(Theme, clrMessageWarningBg,       clrYellow);
00077 THEME_CLR(Theme, clrMessageErrorFg,         clrWhite);
00078 THEME_CLR(Theme, clrMessageErrorBg,         clrRed);
00079 THEME_CLR(Theme, clrVolumeFrame,            clrYellow);
00080 THEME_CLR(Theme, clrVolumeSymbol,           clrBlack);
00081 THEME_CLR(Theme, clrVolumeBarUpper,         0xFFBC8024);
00082 THEME_CLR(Theme, clrVolumeBarLower,         0xFF248024);
00083 THEME_CLR(Theme, clrChannelFrame,           clrYellow);
00084 THEME_CLR(Theme, clrChannelName,            clrBlack);
00085 THEME_CLR(Theme, clrChannelDate,            clrBlack);
00086 THEME_CLR(Theme, clrChannelSymbolOn,        clrBlack);
00087 THEME_CLR(Theme, clrChannelSymbolOff,       0xFFBC8024);
00088 THEME_CLR(Theme, clrChannelSymbolRecFg,     clrWhite);
00089 THEME_CLR(Theme, clrChannelSymbolRecBg,     clrRed);
00090 THEME_CLR(Theme, clrChannelEpgTime,         clrBlack);
00091 THEME_CLR(Theme, clrChannelEpgTitle,        clrCyan);
00092 THEME_CLR(Theme, clrChannelEpgShortText,    clrYellow);
00093 THEME_CLR(Theme, clrChannelTimebarSeen,     clrYellow);
00094 THEME_CLR(Theme, clrChannelTimebarRest,     clrGray50);
00095 THEME_CLR(Theme, clrChannelSignalValue,     clrGreen);
00096 THEME_CLR(Theme, clrChannelSignalRest,      clrRed);
00097 THEME_CLR(Theme, clrMenuFrame,              clrYellow);
00098 THEME_CLR(Theme, clrMenuTitle,              clrBlack);
00099 THEME_CLR(Theme, clrMenuDate,               clrBlack);
00100 THEME_CLR(Theme, clrMenuItemCurrentFg,      clrBlack);
00101 THEME_CLR(Theme, clrMenuItemCurrentBg,      clrYellow);
00102 THEME_CLR(Theme, clrMenuItemSelectable,     clrYellow);
00103 THEME_CLR(Theme, clrMenuItemNonSelectable,  clrCyan);
00104 THEME_CLR(Theme, clrMenuEventTime,          clrYellow);
00105 THEME_CLR(Theme, clrMenuEventVps,           clrBlack);
00106 THEME_CLR(Theme, clrMenuEventTitle,         clrCyan);
00107 THEME_CLR(Theme, clrMenuEventShortText,     clrYellow);
00108 THEME_CLR(Theme, clrMenuEventDescription,   clrCyan);
00109 THEME_CLR(Theme, clrMenuScrollbarTotal,     clrYellow);
00110 THEME_CLR(Theme, clrMenuScrollbarShown,     clrCyan);
00111 THEME_CLR(Theme, clrMenuScrollbarArrow,     clrBlack);
00112 THEME_CLR(Theme, clrMenuText,               clrCyan);
00113 THEME_CLR(Theme, clrReplayFrame,            clrYellow);
00114 THEME_CLR(Theme, clrReplayTitle,            clrBlack);
00115 THEME_CLR(Theme, clrReplayMode,             clrBlack);
00116 THEME_CLR(Theme, clrReplayCurrent,          clrBlack);
00117 THEME_CLR(Theme, clrReplayTotal,            clrBlack);
00118 THEME_CLR(Theme, clrReplayJump,             clrBlack);
00119 THEME_CLR(Theme, clrReplayProgressSeen,     clrGreen);
00120 THEME_CLR(Theme, clrReplayProgressRest,     clrWhite);
00121 THEME_CLR(Theme, clrReplayProgressSelected, clrRed);
00122 THEME_CLR(Theme, clrReplayProgressMark,     clrBlack);
00123 THEME_CLR(Theme, clrReplayProgressCurrent,  clrRed);
00124 
00125 // --- cSkinSTTNGDisplayChannel ----------------------------------------------
00126 
00127 class cSkinSTTNGDisplayChannel : public cSkinDisplayChannel {
00128 private:
00129   cOsd *osd;
00130   int x0, x1, x2, x3, x4, x5, x6, x7;
00131   int y0, y1, y2, y3, y4, y5, y6, y7;
00132   bool withInfo;
00133   int lineHeight;
00134   tColor frameColor;
00135   bool message;
00136   const cEvent *present;
00137   cString lastDate;
00138   int lastSeen;
00139   int lastDeviceNumber;
00140   int lastSignalStrength;
00141   int lastSignalQuality;
00142   time_t lastSignalDisplay;
00143   tTrackId lastTrackId;
00144   static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording;
00145 public:
00146   cSkinSTTNGDisplayChannel(bool WithInfo);
00147   virtual ~cSkinSTTNGDisplayChannel();
00148   virtual void SetChannel(const cChannel *Channel, int Number);
00149   virtual void SetEvents(const cEvent *Present, const cEvent *Following);
00150   virtual void SetMessage(eMessageType Type, const char *Text);
00151   virtual void Flush(void);
00152   };
00153 
00154 cBitmap cSkinSTTNGDisplayChannel::bmTeletext(teletext_xpm);
00155 cBitmap cSkinSTTNGDisplayChannel::bmRadio(radio_xpm);
00156 cBitmap cSkinSTTNGDisplayChannel::bmAudio(audio_xpm);
00157 cBitmap cSkinSTTNGDisplayChannel::bmDolbyDigital(dolbydigital_xpm);
00158 cBitmap cSkinSTTNGDisplayChannel::bmEncrypted(encrypted_xpm);
00159 cBitmap cSkinSTTNGDisplayChannel::bmRecording(recording_xpm);
00160 
00161 cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo)
00162 {
00163   present = NULL;
00164   lastSeen = -1;
00165   lastDeviceNumber = -1;
00166   lastSignalStrength = -1;
00167   lastSignalQuality = -1;
00168   lastSignalDisplay = 0;
00169   memset(&lastTrackId, 0, sizeof(lastTrackId));
00170   const cFont *font = cFont::GetFont(fontOsd);
00171   withInfo = WithInfo;
00172   lineHeight = font->Height();
00173   frameColor = Theme.Color(clrChannelFrame);
00174   message = false;
00175   if (withInfo) {
00176      x0 = 0;
00177      x1 = x0 + font->Width("00:00") + 2 * TextFrame;
00178      x2 = x1 + Roundness;
00179      x3 = x2 + Gap;
00180      x7 = cOsd::OsdWidth();
00181      x6 = x7 - lineHeight / 2;
00182      x5 = x6 - lineHeight / 2;
00183      x4 = x5 - Gap;
00184      y0 = 0;
00185      y1 = lineHeight;
00186      y2 = y1 + Roundness;
00187      y3 = y2 + Gap;
00188      y4 = y3 + 4 * lineHeight;
00189      y5 = y4 + Gap;
00190      y6 = y5 + Roundness;
00191      y7 = y6 + cFont::GetFont(fontSml)->Height();
00192      int yt = (y0 + y1) / 2;
00193      int yb = (y6 + y7) / 2;
00194      osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y7));
00195      tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 32 } }; // TrueColor
00196      if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00197         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00198      else {
00199         tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } }; // 256 colors
00200         if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00201            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00202         else {
00203            tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } }; // 16 colors
00204            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00205            }
00206         }
00207      osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
00208      osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
00209      osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
00210      osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
00211      osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
00212      osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
00213      osd->DrawRectangle(x1, y0, x4 - 1, y1 - 1, frameColor);
00214      osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
00215      osd->DrawEllipse  (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
00216      osd->DrawRectangle(x0, y1, x1 - 1, y2 - 1, frameColor);
00217      osd->DrawEllipse  (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
00218      osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, frameColor);
00219      osd->DrawRectangle(x0, y5, x1 - 1, y6 - 1, frameColor);
00220      osd->DrawEllipse  (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
00221      osd->DrawEllipse  (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
00222      osd->DrawRectangle(x1, y6, x4 - 1, y7 - 1, frameColor);
00223      osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
00224      osd->DrawEllipse  (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
00225      }
00226   else {
00227      x0 = 0;
00228      x1 = lineHeight / 2;
00229      x2 = lineHeight;
00230      x3 = x2 + Gap;
00231      x7 = cOsd::OsdWidth();
00232      x6 = x7 - lineHeight / 2;
00233      x5 = x6 - lineHeight / 2;
00234      x4 = x5 - Gap;
00235      y0 = 0;
00236      y1 = lineHeight;
00237      osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y1));
00238      tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 32 } }; // TrueColor
00239      if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00240         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00241      else {
00242         tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; // 256 colors
00243         if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00244            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00245         else {
00246            tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } }; // 16 colors
00247            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00248            }
00249         }
00250      osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
00251      osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
00252      osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
00253      osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
00254      osd->DrawEllipse  (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
00255      }
00256 }
00257 
00258 cSkinSTTNGDisplayChannel::~cSkinSTTNGDisplayChannel()
00259 {
00260   delete osd;
00261 }
00262 
00263 void cSkinSTTNGDisplayChannel::SetChannel(const cChannel *Channel, int Number)
00264 {
00265   osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
00266   int x = x4 - SymbolSpacing;
00267   if (Channel && !Channel->GroupSep()) {
00268      bool rec = cRecordControls::Active();
00269      x -= bmRecording.Width() + SymbolSpacing;
00270      osd->DrawBitmap(x, y0 + (y1 - y0 - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : frameColor);
00271      x -= bmEncrypted.Width() + SymbolSpacing;
00272      osd->DrawBitmap(x, y0 + (y1 - y0 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
00273      x -= bmDolbyDigital.Width() + SymbolSpacing;
00274      osd->DrawBitmap(x, y0 + (y1 - y0 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid(0) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
00275      x -= bmAudio.Width() + SymbolSpacing;
00276      osd->DrawBitmap(x, y0 + (y1 - y0 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid(1) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
00277      if (Channel->Vpid()) {
00278         x -= bmTeletext.Width() + SymbolSpacing;
00279         osd->DrawBitmap(x, y0 + (y1 - y0 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor);
00280         }
00281      else if (Channel->Apid(0)) {
00282         x -= bmRadio.Width() + SymbolSpacing;
00283         osd->DrawBitmap(x, y0 + (y1 - y0 - bmRadio.Height()) / 2, bmRadio, Theme.Color(clrChannelSymbolOn), frameColor);
00284         }
00285      }
00286   osd->DrawText(x3 + TextFrame, y0, ChannelString(Channel, Number), Theme.Color(clrChannelName), frameColor, cFont::GetFont(fontOsd), x - x3 - TextFrame);
00287   lastSignalDisplay = 0;
00288 }
00289 
00290 void cSkinSTTNGDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following)
00291 {
00292   if (!withInfo)
00293      return;
00294   if (present != Present)
00295      lastSeen = -1;
00296   present = Present;
00297   osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, frameColor);
00298   osd->DrawRectangle(x3, y3, x7 - 1, y4 - 1, Theme.Color(clrBackground));
00299   for (int i = 0; i < 2; i++) {
00300       const cEvent *e = !i ? Present : Following;
00301       if (e) {
00302          osd->DrawText(x0 + TextFrame, y3 + 2 * i * lineHeight, e->GetTimeString(), Theme.Color(clrChannelEpgTime), frameColor, cFont::GetFont(fontOsd));
00303          osd->DrawText(x3 + TextFrame, y3 + 2 * i * lineHeight, e->Title(), Theme.Color(clrChannelEpgTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), x4 - x3 - TextFrame);
00304          osd->DrawText(x3 + TextFrame, y3 + (2 * i + 1) * lineHeight, e->ShortText(), Theme.Color(clrChannelEpgShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), x4 - x3 - TextFrame);
00305          }
00306       }
00307 }
00308 
00309 void cSkinSTTNGDisplayChannel::SetMessage(eMessageType Type, const char *Text)
00310 {
00311   const cFont *font = cFont::GetFont(withInfo ? fontSml : fontOsd);
00312   if (Text) {
00313      int yt = withInfo ? y6 : y0;
00314      int yb = withInfo ? y7 : y1;
00315      osd->SaveRegion(x2, yt, x4 - 1, yb - 1);
00316      if (withInfo)
00317         osd->DrawRectangle(x2, yt, x3 - 1, yb - 1, Theme.Color(clrBackground));
00318      osd->DrawText(x3, yt, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x4 - x3, 0, taCenter);
00319      message = true;
00320      }
00321   else {
00322      osd->RestoreRegion();
00323      message = false;
00324      }
00325 }
00326 
00327 void cSkinSTTNGDisplayChannel::Flush(void)
00328 {
00329   if (withInfo) {
00330      if (!message) {
00331         const cFont *font = cFont::GetFont(fontSml);
00332         cString date = DayDateTime();
00333         int w = font->Width(date);
00334         if (!*lastDate || strcmp(date, lastDate)) {
00335            osd->DrawText(x4 - w - TextFrame, y7 - font->Height(), date, Theme.Color(clrChannelDate), frameColor, font, w);
00336            lastDate = date;
00337            }
00338         cDevice *Device = cDevice::PrimaryDevice();
00339         const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
00340         if (!Track && *lastTrackId.description || Track && strcmp(lastTrackId.description, Track->description)) {
00341            osd->DrawText(x3 + TextFrame, y6, Track ? Track->description : "", Theme.Color(clrChannelName), frameColor, font, x4 - x3 - w - 2 * TextFrame);
00342            strn0cpy(lastTrackId.description, Track ? Track->description : "", sizeof(lastTrackId.description));
00343            }
00344         int DeviceNumber = cDevice::ActualDevice()->DeviceNumber() + 1;
00345         if (DeviceNumber != lastDeviceNumber || time(NULL) != lastSignalDisplay) {
00346            int SignalStrength = cDevice::ActualDevice()->SignalStrength();
00347            int SignalQuality = cDevice::ActualDevice()->SignalQuality();
00348            if (DeviceNumber != lastDeviceNumber || SignalStrength != lastSignalStrength || SignalQuality != lastSignalQuality) {
00349               int d = 3;
00350               int h = ((y7 - y6 + 1) - 3 * d) / 2;
00351               int w = (x4 - x3) / 5;
00352               int x = (x3 + x4) / 2 - w / 2;
00353               if (SignalStrength >= 0) {
00354                  int s = SignalStrength * w / 100;
00355                  osd->DrawRectangle(x,     y6 + d, x + s - 1, y6 + d + h - 1, Theme.Color(clrChannelSignalValue));
00356                  osd->DrawRectangle(x + s, y6 + d, x + w - 1, y6 + d + h - 1, Theme.Color(clrChannelSignalRest));
00357                  }
00358               else if (DeviceNumber != lastDeviceNumber)
00359                  osd->DrawRectangle(x, y6 + d, x + w - 1, y6 + d + h - 1, Theme.Color(clrChannelFrame));
00360               if (SignalQuality >= 0) {
00361                  int q = SignalQuality * w / 100;
00362                  osd->DrawRectangle(x,     y7 - d - h + 1, x + q - 1, y7 - d, Theme.Color(clrChannelSignalValue));
00363                  osd->DrawRectangle(x + q, y7 - d - h + 1, x + w - 1, y7 - d, Theme.Color(clrChannelSignalRest));
00364                  }
00365               else if (DeviceNumber != lastDeviceNumber)
00366                  osd->DrawRectangle(x, y7 - d - h + 1, x + w - 1, y7 - d, Theme.Color(clrChannelFrame));
00367               cString dn = cString::sprintf(" %d ", DeviceNumber);
00368               const cFont *font = cFont::GetFont(fontSml);
00369               int dw = font->Width(dn);
00370               osd->DrawText(x - 2 * d - dw, y6, dn, Theme.Color(clrChannelDate), frameColor, font, dw);
00371               lastDeviceNumber = DeviceNumber;
00372               lastSignalStrength = SignalStrength;
00373               lastSignalQuality = SignalQuality;
00374               }
00375            lastSignalDisplay = time(NULL);
00376            }
00377         }
00378      int seen = 0;
00379      if (present) {
00380         time_t t = time(NULL);
00381         if (t > present->StartTime())
00382            seen = min(y4 - y3 - 1, int((y4 - y3) * double(t - present->StartTime()) / present->Duration()));
00383         }
00384      if (seen != lastSeen) {
00385         osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y4 - 1, Theme.Color(clrChannelTimebarRest));
00386         if (seen)
00387            osd->DrawRectangle(x1 + Gap, y3, x1 + Gap + ScrollWidth - 1, y3 + seen, Theme.Color(clrChannelTimebarSeen));
00388         lastSeen = seen;
00389         }
00390      }
00391   osd->Flush();
00392 }
00393 
00394 // --- cSkinSTTNGDisplayMenu -------------------------------------------------
00395 
00396 class cSkinSTTNGDisplayMenu : public cSkinDisplayMenu {
00397 private:
00398   cOsd *osd;
00399   int x0, x1, x2, x3, x4, x5, x6, x7;
00400   int y0, y1, y2, y3, y4, y5, y6, y7;
00401   int lineHeight;
00402   tColor frameColor;
00403   int currentIndex;
00404   bool message;
00405   cString lastDate;
00406   void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown);
00407   void SetTextScrollbar(void);
00408 public:
00409   cSkinSTTNGDisplayMenu(void);
00410   virtual ~cSkinSTTNGDisplayMenu();
00411   virtual void Scroll(bool Up, bool Page);
00412   virtual int MaxItems(void);
00413   virtual void Clear(void);
00414   virtual void SetTitle(const char *Title);
00415   virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
00416   virtual void SetMessage(eMessageType Type, const char *Text);
00417   virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable);
00418   virtual void SetScrollbar(int Total, int Offset);
00419   virtual void SetEvent(const cEvent *Event);
00420   virtual void SetRecording(const cRecording *Recording);
00421   virtual void SetText(const char *Text, bool FixedFont);
00422   virtual int GetTextAreaWidth(void) const;
00423   virtual const cFont *GetTextAreaFont(bool FixedFont) const;
00424   virtual void Flush(void);
00425   };
00426 
00427 cSkinSTTNGDisplayMenu::cSkinSTTNGDisplayMenu(void)
00428 {
00429   const cFont *font = cFont::GetFont(fontOsd);
00430   lineHeight = font->Height();
00431   frameColor = Theme.Color(clrMenuFrame);
00432   currentIndex = -1;
00433   message = false;
00434   x0 = 0;
00435   x1 = lineHeight / 2;
00436   x3 = (x1 + Roundness + Gap + 7) & ~0x07; // must be multiple of 8
00437   x2 = x3 - Gap;
00438   x7 = cOsd::OsdWidth();
00439   x6 = x7 - lineHeight / 2;
00440   x4 = (x6 - lineHeight / 2 - Gap) & ~0x07; // must be multiple of 8
00441   x5 = x4 + Gap;
00442   y0 = 0;
00443   y1 = lineHeight;
00444   y2 = y1 + Roundness;
00445   y3 = y2 + Gap;
00446   y7 = cOsd::OsdHeight();
00447   y6 = y7 - cFont::GetFont(fontSml)->Height();
00448   y5 = y6 - Roundness;
00449   y4 = y5 - Gap;
00450   int yt = (y0 + y1) / 2;
00451   int yb = (y6 + y7) / 2;
00452   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop());
00453   tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 32 } }; // TrueColor
00454   if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00455      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00456   else {
00457      tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } }; // 256 colors
00458      if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00459         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00460      else {
00461         tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } }; // 16 colors
00462         if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00463            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00464         else {
00465            tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 }, // 2..16 colors
00466                              { x0, y3, x3 - 1, y4 - 1, 1 },
00467                              { x3, y3, x4 - 1, y4 - 1, 2 },
00468                              { x4, y3, x7 - 1, y4 - 1, 2 },
00469                              { x0, y4, x7 - 1, y7 - 1, 4 }
00470                            };
00471            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00472            }
00473         }
00474      }
00475   osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
00476   osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
00477   osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
00478   osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
00479   osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
00480   osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
00481   osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
00482   osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
00483   osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
00484   osd->DrawEllipse  (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
00485   osd->DrawRectangle(x0, y1, x1 - 1, y6 - 1, frameColor);
00486   osd->DrawEllipse  (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
00487   osd->DrawEllipse  (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
00488   osd->DrawEllipse  (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
00489   osd->DrawRectangle(x1, y6, x2 - 1, y7 - 1, frameColor);
00490   osd->DrawRectangle(x3, y6, x4 - 1, y7 - 1, frameColor);
00491   osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
00492   osd->DrawEllipse  (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
00493 }
00494 
00495 cSkinSTTNGDisplayMenu::~cSkinSTTNGDisplayMenu()
00496 {
00497   delete osd;
00498 }
00499 
00500 void cSkinSTTNGDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown)
00501 {
00502   if (Total > 0 && Total > Shown) {
00503      int h  = lineHeight;
00504      int yt = Top;
00505      int yb = yt + Height;
00506      int st = yt + h + Gap;
00507      int sb = yb - h - Gap;
00508      int th = max(int((sb - st) * double(Shown) / Total + 0.5), ScrollWidth);
00509      int tt = min(int(st + (sb - st) * double(Offset) / Total + 0.5), sb - th);
00510      int tb = min(tt + th, sb);
00511      osd->DrawRectangle(x5, st, x5 + ScrollWidth - 1, sb - 1, Theme.Color(clrMenuScrollbarTotal));
00512      osd->DrawRectangle(x5, tt, x5 + ScrollWidth - 1, tb - 1, Theme.Color(clrMenuScrollbarShown));
00513      osd->DrawRectangle(x5, yt, x6 - 1, yt + h - 1, frameColor);
00514      osd->DrawEllipse  (x6, yt, x7 - 1, yt + h - 1, frameColor, 5);
00515      osd->DrawRectangle(x5, yb - h, x6 - 1, yb - 1, frameColor);
00516      osd->DrawEllipse  (x6, yb - h, x7 - 1, yb - 1, frameColor, 5);
00517      if (CanScrollUp) {
00518         cBitmap bm(arrowup_xpm);
00519         osd->DrawBitmap(x5 + (x7 - x5 - bm.Width()) / 2 - 2, yt + (h - bm.Height()) / 2, bm, Theme.Color(clrMenuScrollbarArrow), frameColor);
00520         }
00521      if (CanScrollDown) {
00522         cBitmap bm(arrowdown_xpm);
00523         osd->DrawBitmap(x5 + (x7 - x5 - bm.Width()) / 2 - 2, yb - h + (h - bm.Height()) / 2, bm, Theme.Color(clrMenuScrollbarArrow), frameColor);
00524         }
00525    }
00526 }
00527 
00528 void cSkinSTTNGDisplayMenu::SetTextScrollbar(void)
00529 {
00530   if (textScroller.CanScroll())
00531      DrawScrollbar(textScroller.Total(), textScroller.Offset(), textScroller.Shown(), textScroller.Top(), textScroller.Height(), textScroller.CanScrollUp(), textScroller.CanScrollDown());
00532 }
00533 
00534 void cSkinSTTNGDisplayMenu::Scroll(bool Up, bool Page)
00535 {
00536   cSkinDisplayMenu::Scroll(Up, Page);
00537   SetTextScrollbar();
00538 }
00539 
00540 int cSkinSTTNGDisplayMenu::MaxItems(void)
00541 {
00542   return (y4 - y3 - 2 * Roundness) / lineHeight;
00543 }
00544 
00545 void cSkinSTTNGDisplayMenu::Clear(void)
00546 {
00547   textScroller.Reset();
00548   osd->DrawRectangle(x1, y3, x7 - 1, y4 - 1, Theme.Color(clrBackground));
00549 }
00550 
00551 void cSkinSTTNGDisplayMenu::SetTitle(const char *Title)
00552 {
00553   const cFont *font = cFont::GetFont(fontOsd);
00554   const char *VDR = " VDR";
00555   int w = font->Width(VDR);
00556   osd->DrawText(x3 + TextSpacing, y0, Title, Theme.Color(clrMenuTitle), frameColor, font, x4 - w - x3 - TextSpacing);
00557   osd->DrawText(x4 - w, y0, VDR, frameColor, clrBlack, font, w, lineHeight);
00558 }
00559 
00560 void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
00561 {
00562   cString date = DayDateTime();
00563   const cFont *font = cFont::GetFont(fontSml);
00564   int d = 2 * Gap;
00565   int d2 = d / 2;
00566   int t4 = x4 - font->Width(date) - TextFrame;
00567   int w = t4 - x3;
00568   int t0 = x3 + d2;
00569   int t1 = x3 + w / 4;
00570   int t2 = x3 + w / 2;
00571   int t3 = t4 - w / 4;
00572   osd->DrawRectangle(t0 + d2, y6, t1 - d2, y7 - 1, clrBlack);
00573   osd->DrawRectangle(t1 + d2, y6, t2 - d2, y7 - 1, clrBlack);
00574   osd->DrawRectangle(t2 + d2, y6, t3 - d2, y7 - 1, clrBlack);
00575   osd->DrawRectangle(t3 + d2, y6, t4 - d2, y7 - 1, clrBlack);
00576   osd->DrawText(t0 + d, y6, Red,    Theme.Color(clrButtonRedFg),    Theme.Color(clrButtonRedBg),    font, t1 - t0 - 2 * d, 0, taCenter);
00577   osd->DrawText(t1 + d, y6, Green,  Theme.Color(clrButtonGreenFg),  Theme.Color(clrButtonGreenBg),  font, t2 - t1 - 2 * d, 0, taCenter);
00578   osd->DrawText(t2 + d, y6, Yellow, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font, t3 - t2 - 2 * d, 0, taCenter);
00579   osd->DrawText(t3 + d, y6, Blue,   Theme.Color(clrButtonBlueFg),   Theme.Color(clrButtonBlueBg),   font, t4 - t3 - 2 * d, 0, taCenter);
00580 }
00581 
00582 void cSkinSTTNGDisplayMenu::SetMessage(eMessageType Type, const char *Text)
00583 {
00584   const cFont *font = cFont::GetFont(fontSml);
00585   if (Text) {
00586      osd->SaveRegion(x3, y6, x4 - 1, y7 - 1);
00587      osd->DrawText(x3, y6, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x4 - x3, 0, taCenter);
00588      message = true;
00589      }
00590   else {
00591      osd->RestoreRegion();
00592      message = false;
00593      }
00594 }
00595 
00596 void cSkinSTTNGDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable)
00597 {
00598   int y = y3 + Roundness + Index * lineHeight;
00599   tColor ColorFg, ColorBg;
00600   if (Current) {
00601      ColorFg = Theme.Color(clrMenuItemCurrentFg);
00602      ColorBg = Theme.Color(clrMenuItemCurrentBg);
00603      osd->DrawEllipse  (x1, y - Roundness,  x2 - 1, y - 1, frameColor, -3);
00604      osd->DrawRectangle(x1, y,              x2 - 1, y + lineHeight - 1, frameColor);
00605      osd->DrawEllipse  (x1, y + lineHeight, x2 - 1, y + lineHeight + Roundness - 1, frameColor, -2);
00606      osd->DrawRectangle(x3, y,              x4 - 1, y + lineHeight - 1, ColorBg);
00607      currentIndex = Index;
00608      }
00609   else {
00610      ColorFg = Theme.Color(Selectable ? clrMenuItemSelectable : clrMenuItemNonSelectable);
00611      ColorBg = Theme.Color(clrBackground);
00612      if (currentIndex == Index) {
00613         osd->DrawRectangle(x1, y - Roundness,  x2 - 1, y + lineHeight + Roundness - 1, Theme.Color(clrBackground));
00614         osd->DrawRectangle(x3, y,              x4 - 1, y + lineHeight - 1, Theme.Color(clrBackground));
00615         }
00616      }
00617   const cFont *font = cFont::GetFont(fontOsd);
00618   for (int i = 0; i < MaxTabs; i++) {
00619       const char *s = GetTabbedText(Text, i);
00620       if (s) {
00621          int xt = x3 + TextSpacing + Tab(i);
00622          osd->DrawText(xt, y, s, ColorFg, ColorBg, font, x4 - xt);
00623          }
00624       if (!Tab(i + 1))
00625          break;
00626       }
00627   SetEditableWidth(x4 - x3 - TextSpacing - Tab(1));
00628 }
00629 
00630 void cSkinSTTNGDisplayMenu::SetScrollbar(int Total, int Offset)
00631 {
00632   DrawScrollbar(Total, Offset, MaxItems(), y3 + Roundness, MaxItems() * lineHeight, Offset > 0, Offset + MaxItems() < Total);
00633 }
00634 
00635 void cSkinSTTNGDisplayMenu::SetEvent(const cEvent *Event)
00636 {
00637   if (!Event)
00638      return;
00639   const cFont *font = cFont::GetFont(fontOsd);
00640   int xl = x3 + TextSpacing;
00641   int y = y3;
00642   cTextScroller ts;
00643   char t[32];
00644   snprintf(t, sizeof(t), "%s  %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString());
00645   ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
00646   if (Event->Vps() && Event->Vps() != Event->StartTime()) {
00647      cString buffer = cString::sprintf(" VPS: %s ", *Event->GetVpsString());
00648      const cFont *font = cFont::GetFont(fontSml);
00649      int w = font->Width(buffer);
00650      osd->DrawText(x4 - w, y, buffer, Theme.Color(clrMenuEventVps), frameColor, font, w);
00651      int yb = y + font->Height();
00652      osd->DrawRectangle(x5, y, x6 - 1, yb - 1, frameColor);
00653      osd->DrawEllipse  (x6, y, x7 - 1, yb - 1, frameColor, 5);
00654      }
00655   y += ts.Height();
00656   if (Event->ParentalRating()) {
00657      cString buffer = cString::sprintf(" %s ", *Event->GetParentalRatingString());
00658      const cFont *font = cFont::GetFont(fontSml);
00659      int w = font->Width(buffer);
00660      osd->DrawText(x4 - w, y, buffer, Theme.Color(clrMenuEventVps), frameColor, font, w);
00661      int yb = y + font->Height();
00662      osd->DrawRectangle(x5, y, x6 - 1, yb - 1, frameColor);
00663      osd->DrawEllipse  (x6, y, x7 - 1, yb - 1, frameColor, 5);
00664      }
00665   y += font->Height();
00666   ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->Title(), font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
00667   y += ts.Height();
00668   if (!isempty(Event->ShortText())) {
00669      const cFont *font = cFont::GetFont(fontSml);
00670      ts.Set(osd, xl, y, x4 - xl, y4 - y, Event->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
00671      y += ts.Height();
00672      }
00673   y += font->Height();
00674   if (!isempty(Event->Description())) {
00675      int yt = y;
00676      int yb = y4 - Roundness;
00677      textScroller.Set(osd, xl, yt, x4 - xl, yb - yt, Event->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
00678      yb = yt + textScroller.Height();
00679      osd->DrawEllipse  (x1, yt - Roundness, x2, yt,             frameColor, -3);
00680      osd->DrawRectangle(x1, yt,             x2, yb,             frameColor);
00681      osd->DrawEllipse  (x1, yb,             x2, yb + Roundness, frameColor, -2);
00682      SetTextScrollbar();
00683      }
00684 }
00685 
00686 void cSkinSTTNGDisplayMenu::SetRecording(const cRecording *Recording)
00687 {
00688   if (!Recording)
00689      return;
00690   const cRecordingInfo *Info = Recording->Info();
00691   const cFont *font = cFont::GetFont(fontOsd);
00692   int xl = x3 + TextSpacing;
00693   int y = y3;
00694   cTextScroller ts;
00695   char t[32];
00696   snprintf(t, sizeof(t), "%s  %s", *DateString(Recording->Start()), *TimeString(Recording->Start()));
00697   ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
00698   y += ts.Height();
00699   if (Info->GetEvent()->ParentalRating()) {
00700      cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString());
00701      const cFont *font = cFont::GetFont(fontSml);
00702      int w = font->Width(buffer);
00703      osd->DrawText(x4 - w, y, buffer, Theme.Color(clrMenuEventVps), frameColor, font, w);
00704      int yb = y + font->Height();
00705      osd->DrawRectangle(x5, y, x6 - 1, yb - 1, frameColor);
00706      osd->DrawEllipse  (x6, y, x7 - 1, yb - 1, frameColor, 5);
00707      }
00708   y += font->Height();
00709   const char *Title = Info->Title();
00710   if (isempty(Title))
00711      Title = Recording->Name();
00712   ts.Set(osd, xl, y, x4 - xl, y4 - y, Title, font, Theme.Color(clrMenuEventTitle), Theme.Color(clrBackground));
00713   y += ts.Height();
00714   if (!isempty(Info->ShortText())) {
00715      const cFont *font = cFont::GetFont(fontSml);
00716      ts.Set(osd, xl, y, x4 - xl, y4 - y, Info->ShortText(), font, Theme.Color(clrMenuEventShortText), Theme.Color(clrBackground));
00717      y += ts.Height();
00718      }
00719   y += font->Height();
00720   if (!isempty(Info->Description())) {
00721      int yt = y;
00722      int yb = y4 - Roundness;
00723      textScroller.Set(osd, xl, yt, x4 - xl, yb - yt, Info->Description(), font, Theme.Color(clrMenuEventDescription), Theme.Color(clrBackground));
00724      yb = yt + textScroller.Height();
00725      osd->DrawEllipse  (x1, yt - Roundness, x2, yt,             frameColor, -3);
00726      osd->DrawRectangle(x1, yt,             x2, yb,             frameColor);
00727      osd->DrawEllipse  (x1, yb,             x2, yb + Roundness, frameColor, -2);
00728      SetTextScrollbar();
00729      }
00730 }
00731 
00732 void cSkinSTTNGDisplayMenu::SetText(const char *Text, bool FixedFont)
00733 {
00734   textScroller.Set(osd, x3, y3, GetTextAreaWidth(), y4 - y3, Text, GetTextAreaFont(FixedFont), Theme.Color(clrMenuText), Theme.Color(clrBackground));
00735   SetTextScrollbar();
00736 }
00737 
00738 int cSkinSTTNGDisplayMenu::GetTextAreaWidth(void) const
00739 {
00740   return x4 - x3;
00741 }
00742 
00743 const cFont *cSkinSTTNGDisplayMenu::GetTextAreaFont(bool FixedFont) const
00744 {
00745   const cFont *font = cFont::GetFont(FixedFont ? fontFix : fontOsd);
00746   //XXX -> make a way to let the text define which font to use
00747   return font;
00748 }
00749 
00750 void cSkinSTTNGDisplayMenu::Flush(void)
00751 {
00752   if (!message) {
00753      cString date = DayDateTime();
00754      if (!*lastDate || strcmp(date, lastDate)) {
00755         const cFont *font = cFont::GetFont(fontSml);
00756         int w = font->Width(date);
00757         osd->DrawText(x4 - w - TextFrame, y7 - font->Height(), date, Theme.Color(clrMenuDate), frameColor, font, w);
00758         lastDate = date;
00759         }
00760      }
00761   osd->Flush();
00762 }
00763 
00764 // --- cSkinSTTNGDisplayReplay -----------------------------------------------
00765 
00766 class cSkinSTTNGDisplayReplay : public cSkinDisplayReplay {
00767 private:
00768   cOsd *osd;
00769   int x0, x1, x2, x3, x4, x5, x6, x7;
00770   int y0, y1, y2, y3, y4, y5, y6, y7;
00771   tColor frameColor;
00772   int lastCurrentWidth;
00773 public:
00774   cSkinSTTNGDisplayReplay(bool ModeOnly);
00775   virtual ~cSkinSTTNGDisplayReplay();
00776   virtual void SetTitle(const char *Title);
00777   virtual void SetMode(bool Play, bool Forward, int Speed);
00778   virtual void SetProgress(int Current, int Total);
00779   virtual void SetCurrent(const char *Current);
00780   virtual void SetTotal(const char *Total);
00781   virtual void SetJump(const char *Jump);
00782   virtual void SetMessage(eMessageType Type, const char *Text);
00783   virtual void Flush(void);
00784   };
00785 
00786 cSkinSTTNGDisplayReplay::cSkinSTTNGDisplayReplay(bool ModeOnly)
00787 {
00788   const cFont *font = cFont::GetFont(fontSml);
00789   int lineHeight = font->Height();
00790   frameColor = Theme.Color(clrReplayFrame);
00791   lastCurrentWidth = 0;
00792   cBitmap bm(play_xpm);
00793   x0 = 0;
00794   x1 = max(lineHeight * 2, bm.Width());
00795   x2 = x1 + Roundness;
00796   x3 = x2 + Gap;
00797   x7 = cOsd::OsdWidth();
00798   x6 = x7 - lineHeight / 2;
00799   x5 = x6 - lineHeight / 2;
00800   x4 = x5 - Gap;
00801   y0 = 0;
00802   y1 = lineHeight;
00803   y2 = y1 + Roundness;
00804   y3 = y2 + Gap;
00805   y4 = y3 + max(lineHeight, bm.Height());
00806   y5 = y4 + Gap;
00807   y6 = y5 + Roundness;
00808   y7 = y6 + font->Height();
00809   int yt = (y0 + y1) / 2;
00810   int yb = (y6 + y7) / 2;
00811   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y7);
00812   tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 32 } }; // TrueColor
00813   if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00814      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00815   else {
00816      tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } }; // 256 colors
00817      if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00818         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00819      else {
00820         tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } }; // 16 colors
00821         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00822         }
00823      }
00824   osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, ModeOnly ? clrTransparent : Theme.Color(clrBackground));
00825   if (!ModeOnly) {
00826      osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
00827      osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
00828      osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
00829      osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
00830      osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
00831      osd->DrawRectangle(x1, y0, x4 - 1, y1 - 1, frameColor);
00832      osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
00833      osd->DrawEllipse  (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
00834      osd->DrawRectangle(x0, y1, x1 - 1, y2 - 1, frameColor);
00835      osd->DrawEllipse  (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
00836      }
00837   osd->DrawRectangle(x0, y3, x1 - 1, y4 - 1, frameColor);
00838   if (!ModeOnly) {
00839      osd->DrawRectangle(x0, y5, x1 - 1, y6 - 1, frameColor);
00840      osd->DrawEllipse  (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
00841      osd->DrawEllipse  (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
00842      osd->DrawRectangle(x1, y6, x4 - 1, y7 - 1, frameColor);
00843      osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
00844      osd->DrawEllipse  (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
00845      }
00846 }
00847 
00848 cSkinSTTNGDisplayReplay::~cSkinSTTNGDisplayReplay()
00849 {
00850   delete osd;
00851 }
00852 
00853 void cSkinSTTNGDisplayReplay::SetTitle(const char *Title)
00854 {
00855   osd->DrawText(x3 + TextSpacing, y0, Title, Theme.Color(clrReplayTitle), frameColor, cFont::GetFont(fontSml), x4 - x3 - TextSpacing);
00856 }
00857 
00858 static const char *const *ReplaySymbols[2][2][5] = {
00859   { { pause_xpm, srew_xpm, srew1_xpm, srew2_xpm, srew3_xpm },
00860     { pause_xpm, sfwd_xpm, sfwd1_xpm, sfwd2_xpm, sfwd3_xpm }, },
00861   { { play_xpm,  frew_xpm, frew1_xpm, frew2_xpm, frew3_xpm },
00862     { play_xpm,  ffwd_xpm, ffwd1_xpm, ffwd2_xpm, ffwd3_xpm } }
00863   };
00864 
00865 void cSkinSTTNGDisplayReplay::SetMode(bool Play, bool Forward, int Speed)
00866 {
00867   Speed = constrain(Speed, -1, 3);
00868   cBitmap bm(ReplaySymbols[Play][Forward][Speed + 1]);
00869   osd->DrawBitmap(x0 + (x1 - x0 - bm.Width()) / 2, y3 + (y4 - y3 - bm.Height()) / 2, bm, Theme.Color(clrReplayMode), frameColor);
00870 }
00871 
00872 void cSkinSTTNGDisplayReplay::SetProgress(int Current, int Total)
00873 {
00874   cProgressBar pb(x4 - x3, y4 - y3, Current, Total, marks, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent));
00875   osd->DrawBitmap(x3, y3, pb);
00876 }
00877 
00878 void cSkinSTTNGDisplayReplay::SetCurrent(const char *Current)
00879 {
00880   const cFont *font = cFont::GetFont(fontSml);
00881   int w = font->Width(Current);
00882   osd->DrawText(x3, y6, Current, Theme.Color(clrReplayCurrent), frameColor, font, lastCurrentWidth > w ? lastCurrentWidth : w);
00883   lastCurrentWidth = w;
00884 }
00885 
00886 void cSkinSTTNGDisplayReplay::SetTotal(const char *Total)
00887 {
00888   const cFont *font = cFont::GetFont(fontSml);
00889   int w = font->Width(Total);
00890   osd->DrawText(x4 - w - TextSpacing, y6, Total, Theme.Color(clrReplayTotal), frameColor, font, w);
00891 }
00892 
00893 void cSkinSTTNGDisplayReplay::SetJump(const char *Jump)
00894 {
00895   osd->DrawText(x0 + (x4 - x0) / 4, y6, Jump, Theme.Color(clrReplayJump), frameColor, cFont::GetFont(fontSml), (x4 - x3) / 2, 0, taCenter);
00896 }
00897 
00898 void cSkinSTTNGDisplayReplay::SetMessage(eMessageType Type, const char *Text)
00899 {
00900   const cFont *font = cFont::GetFont(fontSml);
00901   if (Text) {
00902      osd->SaveRegion(x2, y6, x4 - 1, y7 - 1);
00903      osd->DrawRectangle(x2, y6, x3 - 1, y7 - 1, Theme.Color(clrBackground));
00904      osd->DrawText(x3, y6, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x4 - x3, 0, taCenter);
00905      }
00906   else
00907      osd->RestoreRegion();
00908 }
00909 
00910 void cSkinSTTNGDisplayReplay::Flush(void)
00911 {
00912   osd->Flush();
00913 }
00914 
00915 // --- cSkinSTTNGDisplayVolume -----------------------------------------------
00916 
00917 class cSkinSTTNGDisplayVolume : public cSkinDisplayVolume {
00918 private:
00919   cOsd *osd;
00920   int x0, x1, x2, x3, x4, x5, x6, x7;
00921   int y0, y1;
00922   tColor frameColor;
00923   int mute;
00924 public:
00925   cSkinSTTNGDisplayVolume(void);
00926   virtual ~cSkinSTTNGDisplayVolume();
00927   virtual void SetVolume(int Current, int Total, bool Mute);
00928   virtual void Flush(void);
00929   };
00930 
00931 cSkinSTTNGDisplayVolume::cSkinSTTNGDisplayVolume(void)
00932 {
00933   const cFont *font = cFont::GetFont(fontOsd);
00934   int lineHeight = font->Height();
00935   frameColor = Theme.Color(clrVolumeFrame);
00936   mute = -1;
00937   x0 = 0;
00938   x1 = lineHeight / 2;
00939   x2 = lineHeight;
00940   x3 = x2 + Gap;
00941   x7 = cOsd::OsdWidth();
00942   x6 = x7 - lineHeight / 2;
00943   x5 = x6 - lineHeight / 2;
00944   x4 = x5 - Gap;
00945   y0 = 0;
00946   y1 = lineHeight;
00947   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1);
00948   tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 32 } }; // TrueColor
00949   if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00950      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00951   else {
00952      tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; // 256 colors
00953      if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
00954         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00955      else {
00956         tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } }; // 16 colors
00957         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
00958         }
00959      }
00960   osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
00961   osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
00962   osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
00963   osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
00964   osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
00965   osd->DrawEllipse  (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
00966 }
00967 
00968 cSkinSTTNGDisplayVolume::~cSkinSTTNGDisplayVolume()
00969 {
00970   delete osd;
00971 }
00972 
00973 void cSkinSTTNGDisplayVolume::SetVolume(int Current, int Total, bool Mute)
00974 {
00975   int xl = x3 + TextSpacing;
00976   int xr = x4 - TextSpacing;
00977   int yt = y0 + TextFrame;
00978   int yb = y1 - TextFrame;
00979   if (mute != Mute) {
00980      osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
00981      mute = Mute;
00982      }
00983   cBitmap bm(Mute ? mute_xpm : volume_xpm);
00984   osd->DrawBitmap(xl, y0 + (y1 - y0 - bm.Height()) / 2, bm, Theme.Color(clrVolumeSymbol), frameColor);
00985   if (!Mute) {
00986      xl += bm.Width() + TextSpacing;
00987      int w = (y1 - y0) / 3;
00988      int d = TextFrame;
00989      int n = (xr - xl + d) / (w + d);
00990      int x = xr - n * (w + d);
00991      tColor Color = Theme.Color(clrVolumeBarLower);
00992      for (int i = 0; i < n; i++) {
00993          if (Total * i >= Current * n)
00994             Color = Theme.Color(clrVolumeBarUpper);
00995          osd->DrawRectangle(x, yt, x + w - 1, yb - 1, Color);
00996          x += w + d;
00997          }
00998      }
00999 }
01000 
01001 void cSkinSTTNGDisplayVolume::Flush(void)
01002 {
01003   osd->Flush();
01004 }
01005 
01006 // --- cSkinSTTNGDisplayTracks -----------------------------------------------
01007 
01008 class cSkinSTTNGDisplayTracks : public cSkinDisplayTracks {
01009 private:
01010   cOsd *osd;
01011   int x0, x1, x2, x3, x4, x5, x6, x7;
01012   int y0, y1, y2, y3, y4, y5, y6, y7;
01013   int lineHeight;
01014   tColor frameColor;
01015   int currentIndex;
01016   static cBitmap bmAudioLeft, bmAudioRight, bmAudioStereo;
01017   void SetItem(const char *Text, int Index, bool Current);
01018 public:
01019   cSkinSTTNGDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
01020   virtual ~cSkinSTTNGDisplayTracks();
01021   virtual void SetTrack(int Index, const char * const *Tracks);
01022   virtual void SetAudioChannel(int AudioChannel);
01023   virtual void Flush(void);
01024   };
01025 
01026 cBitmap cSkinSTTNGDisplayTracks::bmAudioLeft(audioleft_xpm);
01027 cBitmap cSkinSTTNGDisplayTracks::bmAudioRight(audioright_xpm);
01028 cBitmap cSkinSTTNGDisplayTracks::bmAudioStereo(audiostereo_xpm);
01029 
01030 cSkinSTTNGDisplayTracks::cSkinSTTNGDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
01031 {
01032   const cFont *font = cFont::GetFont(fontOsd);
01033   lineHeight = font->Height();
01034   frameColor = Theme.Color(clrMenuFrame);
01035   currentIndex = -1;
01036   int ItemsWidth = font->Width(Title);
01037   for (int i = 0; i < NumTracks; i++)
01038       ItemsWidth = max(ItemsWidth, font->Width(Tracks[i]));
01039   ItemsWidth += 2 * TextSpacing;
01040   x0 = 0;
01041   x1 = lineHeight / 2;
01042   x3 = (x1 + Roundness + Gap + 7) & ~0x07; // must be multiple of 8
01043   x2 = x3 - Gap;
01044   x7 = cOsd::OsdWidth();
01045   x6 = x7 - lineHeight / 2;
01046   x4 = (x6 - lineHeight / 2 - Gap) & ~0x07; // must be multiple of 8
01047   x5 = x4 + Gap;
01048   int d = x4 - x3;
01049   if (d > ItemsWidth) {
01050      d = (d - ItemsWidth) & ~0x07; // must be multiple of 8
01051      x4 -= d;
01052      x5 -= d;
01053      x6 -= d;
01054      x7 -= d;
01055      }
01056   y0 = 0;
01057   y1 = lineHeight;
01058   y2 = y1 + Roundness;
01059   y3 = y2 + Gap;
01060   // limit to cOsd::OsdHeight()? - what if height is too big???
01061   y4 = y3 + NumTracks * lineHeight + 2 * Roundness;
01062   y5 = y4 + Gap;
01063   y6 = y5 + Roundness;
01064   y7 = y6 + cFont::GetFont(fontSml)->Height();
01065   int yt = (y0 + y1) / 2;
01066   int yb = (y6 + y7) / 2;
01067   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y7);
01068   tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 32 } }; // TrueColor
01069   if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
01070      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
01071   else {
01072      tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } }; // 256 colors
01073      if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
01074         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
01075      else {
01076         tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } }; // 16 colors
01077         if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
01078            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
01079         else {
01080            tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 }, // 2..16 colors
01081                              { x0, y3, x3 - 1, y4 - 1, 1 },
01082                              { x3, y3, x4 - 1, y4 - 1, 2 },
01083                              { x4, y3, x7 - 1, y4 - 1, 2 },
01084                              { x0, y4, x7 - 1, y7 - 1, 4 }
01085                            };
01086            osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
01087            }
01088         }
01089      }
01090   osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
01091   osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
01092   osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
01093   osd->DrawRectangle(x6, y0, x7 - 1, yt - 1, clrTransparent);
01094   osd->DrawRectangle(x6, yb, x7 - 1, y7 - 1, clrTransparent);
01095   osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 2);
01096   osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
01097   osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor);
01098   osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
01099   osd->DrawEllipse  (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
01100   osd->DrawRectangle(x0, y1, x1 - 1, y6 - 1, frameColor);
01101   osd->DrawEllipse  (x1, y1, x2 - 1, y2 - 1, frameColor, -2);
01102   osd->DrawEllipse  (x1, y5, x2 - 1, y6 - 1, frameColor, -3);
01103   osd->DrawEllipse  (x0, y6, x1 - 1, y7 - 1, frameColor, 3);
01104   osd->DrawRectangle(x1, y6, x2 - 1, y7 - 1, frameColor);
01105   osd->DrawRectangle(x3, y6, x4 - 1, y7 - 1, frameColor);
01106   osd->DrawRectangle(x5, y6, x6 - 1, y7 - 1, frameColor);
01107   osd->DrawEllipse  (x6, y6, x7 - 1, y7 - 1, frameColor, 5);
01108   osd->DrawText(x3 + TextSpacing, y0, Title, Theme.Color(clrMenuTitle), frameColor, font, x4 - x3 - TextSpacing);
01109   for (int i = 0; i < NumTracks; i++)
01110       SetItem(Tracks[i], i, false);
01111 }
01112 
01113 cSkinSTTNGDisplayTracks::~cSkinSTTNGDisplayTracks()
01114 {
01115   delete osd;
01116 }
01117 
01118 void cSkinSTTNGDisplayTracks::SetItem(const char *Text, int Index, bool Current)
01119 {
01120   int y = y3 + Roundness + Index * lineHeight;
01121   tColor ColorFg, ColorBg;
01122   if (Current) {
01123      ColorFg = Theme.Color(clrMenuItemCurrentFg);
01124      ColorBg = Theme.Color(clrMenuItemCurrentBg);
01125      osd->DrawEllipse  (x1, y - Roundness,  x2 - 1, y - 1, frameColor, -3);
01126      osd->DrawRectangle(x1, y,              x2 - 1, y + lineHeight - 1, frameColor);
01127      osd->DrawEllipse  (x1, y + lineHeight, x2 - 1, y + lineHeight + Roundness - 1, frameColor, -2);
01128      osd->DrawRectangle(x3, y,              x4 - 1, y + lineHeight - 1, ColorBg);
01129      currentIndex = Index;
01130      }
01131   else {
01132      ColorFg = Theme.Color(clrMenuItemSelectable);
01133      ColorBg = Theme.Color(clrBackground);
01134      if (currentIndex == Index) {
01135         osd->DrawRectangle(x1, y - Roundness,  x2 - 1, y + lineHeight + Roundness - 1, Theme.Color(clrBackground));
01136         osd->DrawRectangle(x3, y,              x4 - 1, y + lineHeight - 1, Theme.Color(clrBackground));
01137         }
01138      }
01139   const cFont *font = cFont::GetFont(fontOsd);
01140   int xt = x3 + TextSpacing;
01141   osd->DrawText(xt, y, Text, ColorFg, ColorBg, font, x4 - xt);
01142 }
01143 
01144 void cSkinSTTNGDisplayTracks::SetTrack(int Index, const char * const *Tracks)
01145 {
01146   if (currentIndex >= 0)
01147      SetItem(Tracks[currentIndex], currentIndex, false);
01148   SetItem(Tracks[Index], Index, true);
01149 }
01150 
01151 void cSkinSTTNGDisplayTracks::SetAudioChannel(int AudioChannel)
01152 {
01153   cBitmap *bm = NULL;
01154   switch (AudioChannel) {
01155     case 0: bm = &bmAudioStereo; break;
01156     case 1: bm = &bmAudioLeft;   break;
01157     case 2: bm = &bmAudioRight;  break;
01158     default: ;
01159     }
01160   if (bm)
01161      osd->DrawBitmap(x3 + TextSpacing, y6 + (y7 - y6 - bm->Height()) / 2, *bm, Theme.Color(clrChannelSymbolOn), frameColor);
01162   else
01163      osd->DrawRectangle(x3, y6, x4 - 1, y7 - 1, frameColor);
01164 }
01165 
01166 void cSkinSTTNGDisplayTracks::Flush(void)
01167 {
01168   osd->Flush();
01169 }
01170 
01171 // --- cSkinSTTNGDisplayMessage ----------------------------------------------
01172 
01173 class cSkinSTTNGDisplayMessage : public cSkinDisplayMessage {
01174 private:
01175   cOsd *osd;
01176   int x0, x1, x2, x3, x4, x5, x6, x7;
01177   int y0, y1;
01178 public:
01179   cSkinSTTNGDisplayMessage(void);
01180   virtual ~cSkinSTTNGDisplayMessage();
01181   virtual void SetMessage(eMessageType Type, const char *Text);
01182   virtual void Flush(void);
01183   };
01184 
01185 cSkinSTTNGDisplayMessage::cSkinSTTNGDisplayMessage(void)
01186 {
01187   const cFont *font = cFont::GetFont(fontOsd);
01188   int lineHeight = font->Height();
01189   tColor frameColor = Theme.Color(clrMessageFrame);
01190   x0 = 0;
01191   x1 = lineHeight / 2;
01192   x2 = lineHeight;
01193   x3 = x2 + Gap;
01194   x7 = cOsd::OsdWidth();
01195   x6 = x7 - lineHeight / 2;
01196   x5 = x6 - lineHeight / 2;
01197   x4 = x5 - Gap;
01198   y0 = 0;
01199   y1 = lineHeight;
01200   osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1);
01201   tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 32 } }; // TrueColor
01202   if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
01203      osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
01204   else {
01205      tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; // 256 colors
01206      if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
01207         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
01208      else {
01209         tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 2 } }; // 4 colors
01210         osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
01211         }
01212      }
01213   osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
01214   osd->DrawEllipse  (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
01215   osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
01216   osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor);
01217   osd->DrawEllipse  (x6, y0, x7 - 1, y1 - 1, frameColor, 5);
01218 }
01219 
01220 cSkinSTTNGDisplayMessage::~cSkinSTTNGDisplayMessage()
01221 {
01222   delete osd;
01223 }
01224 
01225 void cSkinSTTNGDisplayMessage::SetMessage(eMessageType Type, const char *Text)
01226 {
01227   const cFont *font = cFont::GetFont(fontOsd);
01228   osd->DrawText(x3, y0, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, x4 - x3, 0, taCenter);
01229 }
01230 
01231 void cSkinSTTNGDisplayMessage::Flush(void)
01232 {
01233   osd->Flush();
01234 }
01235 
01236 // --- cSkinSTTNG ------------------------------------------------------------
01237 
01238 cSkinSTTNG::cSkinSTTNG(void)
01239 :cSkin("sttng", &::Theme)//XXX naming problem???
01240 {
01241 }
01242 
01243 const char *cSkinSTTNG::Description(void)
01244 {
01245   return tr("ST:TNG Panels");
01246 }
01247 
01248 cSkinDisplayChannel *cSkinSTTNG::DisplayChannel(bool WithInfo)
01249 {
01250   return new cSkinSTTNGDisplayChannel(WithInfo);
01251 }
01252 
01253 cSkinDisplayMenu *cSkinSTTNG::DisplayMenu(void)
01254 {
01255   return new cSkinSTTNGDisplayMenu;
01256 }
01257 
01258 cSkinDisplayReplay *cSkinSTTNG::DisplayReplay(bool ModeOnly)
01259 {
01260   return new cSkinSTTNGDisplayReplay(ModeOnly);
01261 }
01262 
01263 cSkinDisplayVolume *cSkinSTTNG::DisplayVolume(void)
01264 {
01265   return new cSkinSTTNGDisplayVolume;
01266 }
01267 
01268 cSkinDisplayTracks *cSkinSTTNG::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks)
01269 {
01270   return new cSkinSTTNGDisplayTracks(Title, NumTracks, Tracks);
01271 }
01272 
01273 cSkinDisplayMessage *cSkinSTTNG::DisplayMessage(void)
01274 {
01275   return new cSkinSTTNGDisplayMessage;
01276 }