mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Implemented 'skins' and 'themes'
This commit is contained in:
		
							
								
								
									
										201
									
								
								skins.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								skins.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
/*
 | 
			
		||||
 * skins.c: The optical appearance of the OSD
 | 
			
		||||
 *
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * how to reach the author.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: skins.c 1.1 2004/05/15 12:34:38 kls Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "skins.h"
 | 
			
		||||
#include "interface.h"
 | 
			
		||||
#include "status.h"
 | 
			
		||||
#include "tools.h"
 | 
			
		||||
 | 
			
		||||
// --- cSkinDisplay ----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cSkinDisplay *cSkinDisplay::current = NULL;
 | 
			
		||||
 | 
			
		||||
cSkinDisplay::cSkinDisplay(void)
 | 
			
		||||
{
 | 
			
		||||
  current = this;
 | 
			
		||||
  editableWidth = 100; //XXX
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cSkinDisplay::~cSkinDisplay()
 | 
			
		||||
{
 | 
			
		||||
  current = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cSkinDisplayMenu ------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cSkinDisplayMenu::cSkinDisplayMenu(void)
 | 
			
		||||
{
 | 
			
		||||
  SetTabs(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cSkinDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5)
 | 
			
		||||
{
 | 
			
		||||
  tabs[0] = 0;
 | 
			
		||||
  tabs[1] = Tab1 ? tabs[0] + Tab1 : 0;
 | 
			
		||||
  tabs[2] = Tab2 ? tabs[1] + Tab2 : 0;
 | 
			
		||||
  tabs[3] = Tab3 ? tabs[2] + Tab3 : 0;
 | 
			
		||||
  tabs[4] = Tab4 ? tabs[3] + Tab4 : 0;
 | 
			
		||||
  tabs[5] = Tab5 ? tabs[4] + Tab5 : 0;
 | 
			
		||||
  for (int i = 1; i < MaxTabs; i++)
 | 
			
		||||
      tabs[i] *= 12;//XXX average character width of font used for items!!!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cSkinDisplayMenu::Scroll(bool Up, bool Page)
 | 
			
		||||
{
 | 
			
		||||
  textScroller.Scroll(Up, Page);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *cSkinDisplayMenu::GetTabbedText(const char *s, int Tab)
 | 
			
		||||
{
 | 
			
		||||
  if (!s)
 | 
			
		||||
     return NULL;
 | 
			
		||||
  static char buffer[1000];
 | 
			
		||||
  const char *a = s;
 | 
			
		||||
  const char *b = strchrnul(a, '\t');
 | 
			
		||||
  while (*b && Tab-- > 0) {
 | 
			
		||||
        a = b + 1;
 | 
			
		||||
        b = strchrnul(a, '\t');
 | 
			
		||||
        }
 | 
			
		||||
  if (!*b)
 | 
			
		||||
     return (Tab <= 0) ? a : NULL;
 | 
			
		||||
  unsigned int n = b - a;
 | 
			
		||||
  if (n >= sizeof(buffer))
 | 
			
		||||
     n = sizeof(buffer) - 1;
 | 
			
		||||
  strncpy(buffer, a, n);
 | 
			
		||||
  buffer[n] = 0;
 | 
			
		||||
  return buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cSkinDisplayReplay::cProgressBar --------------------------------------
 | 
			
		||||
 | 
			
		||||
cSkinDisplayReplay::cProgressBar::cProgressBar(int Width, int Height, int Current, int Total, const cMarks *Marks, tColor ColorSeen, tColor ColorRest, tColor ColorSelected, tColor ColorMark, tColor ColorCurrent)
 | 
			
		||||
:cBitmap(Width, Height, 2)
 | 
			
		||||
{
 | 
			
		||||
  total = Total;
 | 
			
		||||
  if (total > 0) {
 | 
			
		||||
     int p = Pos(Current);
 | 
			
		||||
     DrawRectangle(0, 0, p, Height - 1, ColorSeen);
 | 
			
		||||
     DrawRectangle(p + 1, 0, Width - 1, Height - 1, ColorRest);
 | 
			
		||||
     if (Marks) {
 | 
			
		||||
        bool Start = true;
 | 
			
		||||
        for (const cMark *m = Marks->First(); m; m = Marks->Next(m)) {
 | 
			
		||||
            int p1 = Pos(m->position);
 | 
			
		||||
            if (Start) {
 | 
			
		||||
               const cMark *m2 = Marks->Next(m);
 | 
			
		||||
               int p2 = Pos(m2 ? m2->position : total);
 | 
			
		||||
               int h = Height / 3;
 | 
			
		||||
               DrawRectangle(p1, h, p2, Height - h, ColorSelected);
 | 
			
		||||
               }
 | 
			
		||||
            Mark(p1, Start, m->position == Current, ColorMark, ColorCurrent);
 | 
			
		||||
            Start = !Start;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cSkinDisplayReplay::cProgressBar::Mark(int x, bool Start, bool Current, tColor ColorMark, tColor ColorCurrent)
 | 
			
		||||
{
 | 
			
		||||
  DrawRectangle(x, 0, x, Height() - 1, ColorMark);
 | 
			
		||||
  const int d = Height() / (Current ? 3 : 9);
 | 
			
		||||
  for (int i = 0; i < d; i++) {
 | 
			
		||||
      int h = Start ? i : Height() - 1 - i;
 | 
			
		||||
      DrawRectangle(x - d + i, h, x + d - i, h, Current ? ColorCurrent : ColorMark);
 | 
			
		||||
      }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cSkinDisplayReplay ----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cSkinDisplayReplay::cSkinDisplayReplay(void)
 | 
			
		||||
{
 | 
			
		||||
  marks = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cSkinDisplayReplay::SetMarks(const cMarks *Marks)
 | 
			
		||||
{
 | 
			
		||||
  marks = Marks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cSkin -----------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cSkin::cSkin(const char *Name, cTheme *Theme)
 | 
			
		||||
{
 | 
			
		||||
  name = strdup(Name);
 | 
			
		||||
  theme = Theme;
 | 
			
		||||
  if (theme)
 | 
			
		||||
     cThemes::Save(name, theme);
 | 
			
		||||
  Skins.Add(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cSkin::~cSkin()
 | 
			
		||||
{
 | 
			
		||||
  free(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cSkins ----------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
cSkins Skins;
 | 
			
		||||
 | 
			
		||||
cSkins::cSkins(void)
 | 
			
		||||
{
 | 
			
		||||
  displayMessage = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cSkins::~cSkins()
 | 
			
		||||
{
 | 
			
		||||
  delete displayMessage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cSkins::SetCurrent(const char *Name)
 | 
			
		||||
{
 | 
			
		||||
  if (Name) {
 | 
			
		||||
     for (cSkin *Skin = First(); Skin; Skin = Next(Skin)) {
 | 
			
		||||
         if (strcmp(Skin->Name(), Name) == 0) {
 | 
			
		||||
            current = Skin;
 | 
			
		||||
            return true;
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
  current = First();
 | 
			
		||||
  return current != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eKeys cSkins::Message(eMessageType Type, const char *s, int Seconds)
 | 
			
		||||
{
 | 
			
		||||
  switch (Type) {
 | 
			
		||||
    case mtInfo:  isyslog("info: %s", s); break;
 | 
			
		||||
    case mtError: esyslog("ERROR: %s", s); break;
 | 
			
		||||
    default: ;
 | 
			
		||||
    }
 | 
			
		||||
  if (!cSkinDisplay::Current() && !displayMessage)
 | 
			
		||||
     displayMessage = Current()->DisplayMessage();
 | 
			
		||||
  cSkinDisplay::Current()->SetMessage(Type, s);
 | 
			
		||||
  cSkinDisplay::Current()->Flush();
 | 
			
		||||
  cStatus::MsgOsdStatusMessage(s);
 | 
			
		||||
  eKeys k = kNone;
 | 
			
		||||
  if (Type != mtStatus) {
 | 
			
		||||
     k = Interface->Wait(Seconds);
 | 
			
		||||
     if (displayMessage) {
 | 
			
		||||
        delete displayMessage;
 | 
			
		||||
        displayMessage = NULL;
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        cSkinDisplay::Current()->SetMessage(Type, NULL);
 | 
			
		||||
     }
 | 
			
		||||
  else if (!s && displayMessage) {
 | 
			
		||||
     delete displayMessage;
 | 
			
		||||
     displayMessage = NULL;
 | 
			
		||||
     }
 | 
			
		||||
  return k;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cSkins::Flush(void)
 | 
			
		||||
{
 | 
			
		||||
  if (cSkinDisplay::Current())
 | 
			
		||||
     cSkinDisplay::Current()->Flush();
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user