summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlordjaxom <lordjaxom>2004-06-05 18:06:22 +0000
committerlordjaxom <lordjaxom>2004-06-05 18:06:22 +0000
commit6094765d94e4caaf0813039dff826b731f277753 (patch)
treefed79334167f26d5a81a6cae9be3f1341375a36f
parente0c2ee1d37c0f213f22a04df71710bebe3526f85 (diff)
downloadvdr-plugin-text2skin-6094765d94e4caaf0813039dff826b731f277753.tar.gz
vdr-plugin-text2skin-6094765d94e4caaf0813039dff826b731f277753.tar.bz2
- added scrollable texts and "SymbolScrollUp" and "SymbolScrollDown"v0.0.1
- added "MenuText", "MenuEventTitle", "MenuEventShortText", "MenuEventDescription", "MenuEventTime", "MenuRecording", "SymbolEventRunning", "SymbolEventTimer" and "SymbolEventVPS" - implemented image caching - added english and german README - removed some workarounds, and added a patch to vdr to the tree (will be included in 1.3.10) - fixed two bugs when displaying replay symbols - implemented tabbed texts in menu
-rw-r--r--HISTORY13
-rw-r--r--Makefile27
-rw-r--r--README92
-rw-r--r--README.de101
-rw-r--r--SKINS133
-rw-r--r--bitmap.c53
-rw-r--r--bitmap.h17
-rw-r--r--cache.c6
-rw-r--r--cache.h124
-rw-r--r--common.c69
-rw-r--r--common.h10
-rw-r--r--data.c113
-rw-r--r--data.h16
-rw-r--r--display.c46
-rw-r--r--display.h4
-rw-r--r--i18n.c18
-rw-r--r--loader.c7
-rw-r--r--patches/vdr-1.3.9-osd.diff106
-rw-r--r--render.c192
-rw-r--r--render.h23
-rw-r--r--text2skin.c23
-rw-r--r--text2skin.h27
22 files changed, 940 insertions, 280 deletions
diff --git a/HISTORY b/HISTORY
index 13b6a63..afa09ac 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,19 @@
VDR Plugin 'text2skin' Revision History
---------------------------------------
+2004-06-05: Version 0.0.1
+
+- added scrollable texts and "SymbolScrollUp" and "SymbolScrollDown"
+- added "MenuText", "MenuEventTitle", "MenuEventShortText",
+ "MenuEventDescription", "MenuEventTime", "MenuRecording",
+ "SymbolEventRunning", "SymbolEventTimer" and "SymbolEventVPS"
+- implemented image caching
+- added english and german README
+- removed some workarounds, and added a patch to vdr to the tree (will be
+ included in 1.3.10)
+- fixed two bugs when displaying replay symbols
+- implemented tabbed texts in menu
+
2004-06-02: Version 0.0.1-rc4
- implemented image loading through ImageMagick (fixes crashes when running
diff --git a/Makefile b/Makefile
index 3da420d..65e16be 100644
--- a/Makefile
+++ b/Makefile
@@ -1,15 +1,16 @@
-#
-# Makefile for a Video Disk Recorder plugin
-#
-# $Id: Makefile,v 1.5 2004/06/02 20:43:05 lordjaxom Exp $
+# exchange the comments on the following to lines if you would like to use
+# Imlib2 for loading images. BEWARE that you can not use GraphTFT together with
+# Text2Skin if you use Imlib2! (That's why I actually implemented ImageMagick)
-# disable in case you don't want to install imlib
-# in that case, you will not be able to load other files than simple xpms
+HAVE_IMAGEMAGICK=1
# HAVE_IMLIB2=1
-# disable in case you don't want to install ImageMagick
-# in that case, you will not be able to load other files than simple xpms
-HAVE_IMAGEMAGICK=1
+
+# DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING
+# -------------------------------------------------------------
+#
+# $Id: Makefile,v 1.7 2004/06/05 16:52:44 lordjaxom Exp $
+#
# The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin.
@@ -19,7 +20,7 @@ PLUGIN = text2skin
### The version number of this plugin (taken from the main source file):
-VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
+VERSION = $(shell grep 'const char \*cText2SkinPlugin::VERSION *=' $(PLUGIN).c | awk '{ print $$5 }' | sed -e 's/[";]//g')
### The C++ compiler and options:
@@ -58,6 +59,10 @@ ifdef HAVE_IMAGEMAGICK
LIBS += -lMagick++
endif
+ifdef DEBUG
+ DEFINES += -DDEBUG
+endif
+
INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
@@ -65,7 +70,7 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
OBJS = $(PLUGIN).o loader.o data.o display.o render.o common.o bitmap.o \
- file.o i18n.o theme.o
+ file.o i18n.o theme.o cache.o
### Implicit rules:
diff --git a/README b/README
index 4e04b83..16c11f3 100644
--- a/README
+++ b/README
@@ -1,11 +1,97 @@
This is a "plugin" for the Video Disk Recorder (VDR).
-Written by: Your Name <email@host.dom>
+Written by: Sascha Volkenandt <sascha@akv-soft.de>
-Project's homepage: URL
+Project's homepage: http://www.magoa.net/linux/contrib/
-Latest version available at: URL
+Latest version available at: http://www.magoa.net/linux/contrib/
See the file COPYING for license information.
+
Description:
+------------
+
+This plugin is designed to load and interpret a set of files describing the
+layout of the On Screen Display and to make this "Skin" available to VDR via
+Setup -> OSD in the main menu. Of course it is possible to load more than one
+text-based skin this way and to choose between them while running VDR. All
+skins may be themeable (you can create your own color-theme) and translateable
+as the author of the skin wishes.
+
+
+Prerequisites:
+--------------
+
+For loading images in format other than simple XPM, you will need an image
+library. You can choose between two supported libraries, ImageMagick or Imlib2,
+from which the first one is the default. You can specify which library to use
+(if any) in the first few lines of the Makefile. Here is an overview of the
+advantages and drawbacks of each solution:
+
+No library
+ - you can only load XPM files
+ - XPMs don't support partial transparency / alpha channels
+
+ImageMagick
+ + you can load many different image types
+ - is a but slower than Imlib2
+
+Imlib2
+ + you can load many different image types
+ - CRASHES WHEN USED TOGETHER WITH THE GRAPHTFT-PLUGIN!
+
+Using both libraries at the same time doesn't make sense anyway.
+
+HINT: Although the manual of ImageMagick claims that the used library Magick++
+is part of the source distribution, some binary distributions may have to
+install Magick++ separately.
+
+
+Installation:
+-------------
+
+Install text2skin like any other plugin. In this example I assume that you have
+changed to the folder where the VDR sourcecode is located, and that it is
+version 0.0.1 of the plugin you wish to install.
+
+root@linux # cd PLUGINS/src
+root@linux # wget http://www.magoa.net/linux/contrib/vdr-text2skin-0.0.1.tgz
+root@linux # tar -xfz vdr-text2skin-0.0.1.tgz
+root@linux # ln -s text2skin-0.0.1 text2skin
+root@linux # cd ../..
+root@linux # make plugins
+root@linux # ./vdr -P text2skin
+
+If you are using VDR 1.3.9, you also have to apply a patch to the sources. This
+patch will be included in VDR 1.3.10.
+
+root@linux # patch -p1 < PLUGINS/src/text2skin/patches/vdr-1.3.9-osd.diff
+root@linux # make vdr
+root@linux # ./vdr -P text2skin
+
+
+Where to put the skins:
+-----------------------
+
+As you might know, VDR has a subfolder "plugins" inside it's configuration
+folder, where all plugin-related files should reside. If you don't know, where
+this could be, look into the folder you gave to VDR with the -v parameter
+(or the -c parameter, if that was given). "plugins" should be inside that
+folder.
+
+Inside that "plugins" folder, create a subfolder called "text2skin". Inside
+"text2skin", create one folder for each skin. These skin-folders must have the
+same names as the skins residing in them. Each skin must at least have a file
+carrying the same name, but ending in ".skin". Example:
+
+/video0/plugins/text2skin/demo/demo.skin
+/video0/plugins/text2skin/skin2/skin2.skin
+...
+
+The other files inside the skin-folder are additional description files (for
+Themeing and Translation), images, logos and symbols.
+
+If you download a skin, you usually just change to plugins/text2skin and unpack
+it there.
+
diff --git a/README.de b/README.de
new file mode 100644
index 0000000..49a9945
--- /dev/null
+++ b/README.de
@@ -0,0 +1,101 @@
+Dies ist ein "plugin" für den Video Disk Recorder (VDR).
+
+Geschrieben von: Sascha Volkenandt <sascha@akv-soft.de>
+
+Projekthomepage: http://www.magoa.net/linux/contrib/
+
+Letzte Version verfügbar auf: http://www.magoa.net/linux/contrib/
+
+Siehe COPYING für Linzensierungsinformationen.
+
+
+Beschreibung:
+-------------
+
+Dieses Plugin wurde designed um eine Reihe von Dateien zu laden und zu
+interpretieren, die das Aussehen des On Screen Display beschreiben, und diese
+dem VDR via Einstellungen -> OSD zur Verfügung zu stellen. Natürlich ist es
+möglich mehrere textbasierte Skins auf diesem Wege zu laden, und unter diesen
+bei laufendem VDR auszuwählen. Alle Skins können Themeable (die Farbvarianten
+können geändert werden) und Übersetzbar sein, wenn der Autor des Skins dies
+möchte.
+
+
+Voraussetzungen:
+----------------
+
+Um andere Bildformate als einfaches XPM zu laden, brauchen Sie eine
+Grafikbibliothek. Es werden zwei Bibliotheken unterstützt, aus der Sie eine
+zu benutzende wählen können. Dies sind ImageMagick oder Imlib2, wobei erstere
+standardmäßig herangezogen wird. Sie können beeinflussen, welche Bibliothek
+(wenn überhaupt eine) genutzt werden soll, indem Sie die ersten paar Zeilen
+der Datei Makefile ändern. Hier ist eine Übersicht über Möglichkeiten und
+Nachteile jeder möglichen Lösung:
+
+Keine Bibliothek
+ - Sie können nur XPM Dateien laden
+ - XPMs haben weder Teiltransparenzen noch Alphakanäle
+
+ImageMagick
+ + Sie können viele verschiedene Bildformate laden
+ - ist aber etwas langsamer als Imlib2
+
+Imlib2
+ + Sie können viele verschiedene Bildformate laden
+ - STÜRZT AB, WENN ES ZUSAMMEN MIT DEM GRAPHTFT-PLUGIN ZUM EINSATZ KOMMT!
+
+Beide Bibliotheken gleichzeitig zu benutzen macht keinen Sinn.
+
+HINWEIS: Obwohl das Handbuch von ImageMagick behauptet, dass die hier benutzte
+Bibliothek Magick++ integraler Bestandteil der Quellen sind, muss auf manchen
+Distributionen das Paket Magick++ zusätzlich installiert werden.
+
+
+Installation:
+-------------
+
+Installieren Sie text2skin wie jedes andere Plugin. In diesem Beispiel nehme
+ich an Sie sind in den Ordner gewechselt, in dem VDR's Quelltext liegt, und
+Sie wollen Version 0.0.1 des Plugins installieren.
+
+root@linux # cd PLUGINS/src
+root@linux # wget http://www.magoa.net/linux/contrib/vdr-text2skin-0.0.1.tgz
+root@linux # tar -xfz vdr-text2skin-0.0.1.tgz
+root@linux # ln -s text2skin-0.0.1 text2skin
+root@linux # cd ../..
+root@linux # make plugins
+root@linux # ./vdr -P text2skin
+
+Wenn Sie VDR 1.3.9 benutzen, müssen Sie auch noch einen Patch anwenden. Dieser
+Patch wird in VDR 1.3.10 aber enthalten sein.
+
+root@linux # patch -p1 < PLUGINS/src/text2skin/patches/vdr-1.3.9-osd.diff
+root@linux # make vdr
+root@linux # ./vdr -P text2skin
+
+
+Wo die Skins hingehören:
+------------------------
+
+Wie Sie vielleicht wissen, hat VDR einen Unterordner "plugins" innerhalb seines
+Konfigurationsordners, in dem alle Dateien, die zu Plugins gehören, enthalten
+sein sollten. Wenn Sie nicht wissen, wo das sein könnte, schauen Sie in dem
+Ordner nach, den Sie VDR beim Starten mit -v (oder -c, falls gegeben) übergeben
+haben. "plugins" sollte in diesem Ordner enthalten sein.
+
+Innerhalb dieses "plugins" Ordners erstellen Sie einen Ordner namens
+"text2skin". In "text2skin" erstellen Sie einen weiteren Ordner pro Skin. Diese
+Skin-Ordner müssen den gleichen Namen tragen wie die Skins in ihnen. Jedes
+Skin muss mindestens eine Datei enthalten, die denselben Namen trägt, aber mit
+der Endung ".skin". Beispiel:
+
+/video0/plugins/text2skin/demo/demo.skin
+/video0/plugins/text2skin/skin2/skin2.skin
+...
+
+Die anderen Dateien in dem Skin-Ordner sind weitere Beschreibungsdateien (für
+Farben und Übersetzungen) sowie Bilder, Logos und Symbole.
+
+Wenn Sie ein Skin herunterladen, wechseln Sie normalerweise einfach in den
+plugins/text2skin Ordner und entpacken es dort.
+
diff --git a/SKINS b/SKINS
index cd59fd1..ef2de74 100644
--- a/SKINS
+++ b/SKINS
@@ -261,6 +261,84 @@ Description: Draws the specified image into the specified location if the
image handling, see Item=Background.
Parameters: x, y, width, height, path, altpath, fg, bg
+Item: Item=SymbolPlay
+Description: Draws the specified image into the specified location if the
+ current replay is playing normally. If that is not the case, the
+ alternative image (if given) will be displayed. For details on the
+ image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolPause
+Description: Draws the specified image into the specified location if the
+ current replay is paused. If that is not the case, the
+ alternative image (if given) will be displayed. For details on the
+ image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolFastFwd
+Description: Draws the specified image into the specified location if the
+ current replay is fast forwarding. If that is not the case, the
+ alternative image (if given) will be displayed. For details on the
+ image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolFastRew
+Description: Draws the specified image into the specified location if the
+ current replay is fast rewinding. If that is not the case, the
+ alternative image (if given) will be displayed. For details on the
+ image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolSlowFwd
+Description: Draws the specified image into the specified location if the
+ current replay is slow forwarding. If that is not the case, the
+ alternative image (if given) will be displayed. For details on the
+ image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolSlowRew
+Description: Draws the specified image into the specified location if the
+ current replay is slow rewinding. If that is not the case, the
+ alternative image (if given) will be displayed. For details on the
+ image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolEventRunning
+Description: Draws the specified image into the specified location if the
+ displayed event (in menu display) is currently running. If that
+ is not the case, the alternative image (if given) will be
+ displayed. For details on the image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolEventTimer
+Description: Draws the specified image into the specified location if the
+ displayed event (in menu display) will be recorded. If that is
+ not the case, the alternative image (if given) will be displayed.
+ For details on the image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolEventVPS
+Description: Draws the specified image into the specified location if the
+ displayed event (in menu display) is VPS. If that is not the
+ case, the alternative image (if given) will be displayed. For
+ details on the image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolScrollUp
+Description: Draws the specified image into the specified location if the
+ current display is scrollable and not at the top of its contents.
+ If that is not the case, the alternative image (if given) will be
+ displayed. For details on the image handling, see Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
+Item: Item=SymbolScrollDown
+Description: Draws the specified image into the specified location if the
+ current display is scrollable and not at the bottom of its
+ contents. If that is not the case, the alternative image (if
+ given) will be displayed. For details on the image handling, see
+ Item=Background.
+Parameters: x, y, width, height, path, altpath, fg, bg
+
Item: Item=Language
Description: Draws a logo for the current language (currently the only
languages VDR knows are "Audio 1" and possibly "Audio 2",
@@ -317,6 +395,61 @@ Item: Item=MessageError
Description: Draws the current error message (if present).
Parameters: x, y, width, height, fg, font, align, text
+Item: Item=MenuArea
+Description: Specifies the area in which the menu items will be shown as a
+ list.
+Parameters: x, y, width, height
+
+Item: Item=MenuItem
+Description: Specifies how one item is drawn in the list of menu items.
+ list.
+Parameters: [x,] [y,] width, height, fg, bg, font, align
+
+Item: Item=MenuCurrent
+Description: Specifies how the currently selected item is drawn in the list of
+ menu items.
+ list.
+Parameters: [x,] [y,] width, height, fg, bg, font, align
+
+Item: Item=MenuTitle
+Description: Draws the title line of the displayed menu.
+Parameters: x, y, width, height, fg, font, align, text
+
+Item: Item=MenuRed, Item=MenuGreen, Item=MenuYellow, Item=MenuBlue
+Description: Draws the red, green, yellow or blue (respectively) button.
+Parameters: x, y, width, height, fg, font, align, text
+
+Item: Item=MenuText
+Description: Draws the current menu text in a scrollable text-area. If this
+ item is present, SymbolScrollUp and SymbolScrollDown apply, too.
+Parameters: x, y, width, height, fg, [bg,] font, [align,] text
+
+Item: Item=MenuEventTitle
+Description: Draws the title of the currently selected event when viewing EPG
+ entries.
+Parameters: x, y, width, height, fg, font, align, text
+
+Item: Item=MenuEventShortText
+Description: Draws the short text or episode name of the currently selected
+ event when viewing EPG entries.
+Parameters: x, y, width, height, fg, font, align, text
+
+Item: Item=MenuEventDescription
+Description: Draws the long text of the currently selected event when viewing
+ EPG entries in a scrollable text-area. If this item is present,
+ SymbolScrollUp and SymbolScrollDown apply, too.
+Parameters: x, y, width, height, fg, [bg,] font, [align,] text
+
+Item: Item=MenuEventTime
+Description: Draws the start time of the currently selected event when viewing
+ EPG entries.
+Parameters: x, y, width, height, fg, font, align, text
+
+Item: Item=MenuRecording
+Description: Draws the summary of the currently selected recording when
+ browsing recordings in a scrollable text-area. If this item is
+ present, SymbolScrollUp and SymbolScrollDown apply, too.
+Parameters: x, y, width, height, fg, [bg,] font, [align,] text
Known Parameters
----------------
diff --git a/bitmap.c b/bitmap.c
index 185f435..1d9d6f5 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -1,5 +1,5 @@
/*
- * $Id: bitmap.c,v 1.9 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: bitmap.c,v 1.11 2004/06/05 16:52:44 lordjaxom Exp $
*/
#include "bitmap.h"
@@ -12,40 +12,46 @@
#include <Magick++.h>
#endif
-cText2SkinBitmap::cText2SkinBitmap(void): cBitmap(1, 1, 1) {
-#ifdef HAVE_IMLIB2
- imlib_set_cache_size(4096 * 1024);
-#endif
+template<>
+void cImageCache::Delete(string &key, cText2SkinBitmap *&value) {
+ delete value;
}
-cText2SkinBitmap::cText2SkinBitmap(const char *Filename): cBitmap(1, 1, 1) {
-#ifdef HAVE_IMLIB2
- imlib_set_cache_size(4096 * 1024);
-#endif
- Load(Filename);
+cImageCache cText2SkinBitmap::mCache(10);
+
+cText2SkinBitmap::cText2SkinBitmap(void): cBitmap(1, 1, 1) {
}
cText2SkinBitmap::~cText2SkinBitmap() {
}
-bool cText2SkinBitmap::Load(const char *Filename) {
- int len = strlen(Filename);
- if (len > 4) {
- if (strcmp(Filename + len - 4, ".xpm") == 0)
- return LoadXpm(Filename);
+cText2SkinBitmap *cText2SkinBitmap::Load(const char *Filename) {
+ if (mCache.Contains(Filename)) {
+ return mCache[Filename];
+ } else {
+ cText2SkinBitmap *bmp = new cText2SkinBitmap;
+ int len = strlen(Filename);
+ bool result = false;
+ if (len > 4) {
+ if (strcmp(Filename + len - 4, ".xpm") == 0)
+ result = bmp->LoadXpm(Filename);
+ else {
#ifdef HAVE_IMLIB2
- else if (strcmp(Filename + len - 4, ".png") == 0)
- return LoadImlib(Filename);
+ result = bmp->LoadImlib(Filename);
#else
# ifdef HAVE_IMAGEMAGICK
- else if (strcmp(Filename + len - 4, ".png") == 0)
- return LoadMagick(Filename);
+ result = bmp->LoadMagick(Filename);
# endif
#endif
- else
- esyslog("ERROR: text2skin: unknown file format for %s", Filename);
- } else
- esyslog("ERROR: text2skin: filename %s too short to identify format", Filename);
+ }
+ //else
+ //esyslog("ERROR: text2skin: unknown file format for %s", Filename);
+ } else
+ esyslog("ERROR: text2skin: filename %s too short to identify format", Filename);
+
+ if (result)
+ return (mCache[Filename] = bmp);
+ }
return false;
}
@@ -66,7 +72,6 @@ bool cText2SkinBitmap::LoadImlib(const char *Filename) {
for (int x = 0; x < Width(); ++x) {
tColor col = (data[pos + 3] << 24) | (data[pos + 2] << 16) | (data[pos + 1] << 8) | data[pos + 0];
int res = Index(col);
- //printf("color: r=%d,g=%d,b=%d,a=%d\n", data[pos], data[pos+1], data[pos+2], data[pos+3]);
if (pal > 0 && res == 0)
;//esyslog("ERROR: text2skin: Too many colors used in palette");
else
diff --git a/bitmap.h b/bitmap.h
index b0dc35d..6028f0b 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -1,20 +1,29 @@
/*
- * $Id: bitmap.h,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: bitmap.h,v 1.7 2004/06/05 01:39:36 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_BITMAP_H
#define VDR_TEXT2SKIN_BITMAP_H
#include "common.h"
+#include "cache.h"
#include <vdr/osd.h>
+class cText2SkinBitmap;
+typedef cText2SkinCache<string,cText2SkinBitmap*> cImageCache;
+
class cText2SkinBitmap: public cBitmap {
-public:
+private:
+ static cImageCache mCache;
+
+ // disallow direct construction
cText2SkinBitmap(void);
- cText2SkinBitmap(const char *Filename);
+
+public:
+ static cText2SkinBitmap *Load(const char *Filename);
+
virtual ~cText2SkinBitmap();
- bool Load(const char *Filename);
#ifdef HAVE_IMLIB2
bool LoadImlib(const char *Filename);
#endif
diff --git a/cache.c b/cache.c
new file mode 100644
index 0000000..1182e9e
--- /dev/null
+++ b/cache.c
@@ -0,0 +1,6 @@
+/*
+ * $Id: cache.c,v 1.1 2004/06/05 01:40:13 lordjaxom Exp $
+ */
+
+#include "cache.h"
+
diff --git a/cache.h b/cache.h
new file mode 100644
index 0000000..93aff9f
--- /dev/null
+++ b/cache.h
@@ -0,0 +1,124 @@
+/*
+ * $Id: cache.h,v 1.1 2004/06/05 01:40:13 lordjaxom Exp $
+ */
+
+#ifndef VDR_TEXT2SKIN_CACHE_HPP
+#define VDR_TEXT2SKIN_CACHE_HPP
+
+#include "common.h"
+
+// template class generic cache
+
+template<class K,class D>
+class cText2SkinCache {
+private:
+ struct Item {
+ K _key;
+ D _data;
+ time_t _lastUsed;
+
+ Item *_next;
+ Item *_prev;
+
+ Item() { _next = _prev = NULL; }
+ };
+
+ typedef map <K,Item*> DataMap;
+
+ DataMap _items;
+ int _maxItems;
+ Item *_first;
+ Item *_last;
+
+ void Unlink(Item *item);
+ void Update(Item *item);
+ void Delete(Item *item);
+ void Delete(K &key, D &data);
+
+public:
+ cText2SkinCache(int maxItems);
+ ~cText2SkinCache();
+
+ bool Contains(const K &key);
+ D &operator[](const K &key);
+};
+
+template<class K,class D>
+inline void cText2SkinCache<K,D>::Unlink(Item *item) {
+ if (item == _first) {
+ _first = item->_next;
+ if (_first)
+ _first->_prev = NULL;
+ else
+ _last = NULL;
+ } else if (item == _last) {
+ _last = item->_prev;
+ _last->_next = NULL;
+ } else {
+ item->_prev->_next = item->_next;
+ item->_next->_prev = item->_prev;
+ }
+}
+
+template<class K,class D>
+inline void cText2SkinCache<K,D>::Delete(Item *item) {
+ Delete(item->_key, item->_data);
+ delete item;
+}
+
+template<class K,class D>
+inline void cText2SkinCache<K,D>::Delete(K &key, D &Data) {
+}
+
+template<class K,class D>
+inline void cText2SkinCache<K,D>::Update(Item *item) {
+ item->_lastUsed = time_ms();
+ if (item->_next != NULL || item->_prev != NULL)
+ Unlink(item);
+
+ item->_next = NULL;
+ item->_prev = _last;
+ if (_last)
+ _last->_next = item;
+ _last = item;
+ if (!_first)
+ _first = item;
+
+ while ((int)_items.size() > _maxItems) {
+ Item *aged = _first;
+ _items.erase(aged->_key);
+ Unlink(aged);
+ Delete(aged);
+ }
+}
+
+template<class K,class D>
+inline bool cText2SkinCache<K,D>::Contains(const K &key) {
+ return (_items.find(key) != _items.end());
+}
+
+template<class K,class D>
+cText2SkinCache<K,D>::cText2SkinCache(int maxItems) {
+ _maxItems = maxItems;
+ _first = _last = NULL;
+}
+
+template<class K,class D>
+cText2SkinCache<K,D>::~cText2SkinCache() {
+}
+
+template<class K,class D>
+D &cText2SkinCache<K,D>::operator[](const K &key) {
+ Item *item;
+ if (Contains(key)) {
+ item = _items[key];
+ } else {
+ item = new Item;
+ item->_key = key;
+ _items[key] = item;
+ }
+ Update(item);
+ return item->_data;
+}
+
+#endif // VDR_TEXT2SKIN_CACHE_HPP
diff --git a/common.c b/common.c
index bd41565..0d203b5 100644
--- a/common.c
+++ b/common.c
@@ -1,5 +1,5 @@
/*
- * $Id: common.c,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: common.c,v 1.7 2004/06/05 16:52:44 lordjaxom Exp $
*/
#include "data.h"
@@ -10,73 +10,6 @@ const char *SkinPath(void) {
return cPlugin::ConfigDirectory(PLUGIN_NAME_I18N);
}
-void DrawTextTransparent(cOsd *Osd, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment) {
- int w = Font->Width(s);
- int h = Font->Height();
- int limit = 0;
- if (Width || Height) {
- int cw = Width ? Width : w;
- limit = x + cw;
- if (Width) {
- if ((Alignment & taLeft) != 0)
- ;
- else if ((Alignment & taRight) != 0) {
- if (w < Width)
- x += Width - w;
- }
- else { // taCentered
- if (w < Width)
- x += (Width - w) / 2;
- }
- }
- if (Height) {
- if ((Alignment & taTop) != 0)
- ;
- else if ((Alignment & taBottom) != 0) {
- if (h < Height)
- y += Height - h;
- }
- else { // taCentered
- if (h < Height)
- y += (Height - h) / 2;
- }
- }
- }
- while (s && *s) {
- const cFont::tCharData *CharData = Font->CharData(*s++);
- if (limit && int(x + CharData->width) > limit)
- break; // we don't draw partial characters
- if (int(x + CharData->width) > 0) {
- for (int row = 0; row < h; row++) {
- cFont::tPixelData PixelData = CharData->lines[row];
- for (int col = CharData->width; col-- > 0; ) {
- if (PixelData & 1)
- Osd->DrawRectangle(x + col, y + row, x + col, y + row, ColorFg);
- PixelData >>= 1;
- }
- }
- }
- x += CharData->width;
- }
-}
-
-void DrawBitmap(cOsd *Osd, int x, int y, cBitmap &Bitmap, tColor ColorFg, tColor ColorBg) {
- if (ColorFg || ColorBg) {
- Bitmap.SetColor(0, ColorBg);
- Bitmap.SetColor(1, ColorFg);
- }
- tColor fill = Bitmap.Color(*Bitmap.Data(0, 0)); // to be sure to grab a USED color
- Osd->DrawRectangle(x, y, x + Bitmap.Width() - 1, y + Bitmap.Height() - 1, fill); // to be sure the palette is reset, if the Bitmap covers an Area
- for (int iy = 0; iy < Bitmap.Height(); iy++) {
- const tIndex *ptr = Bitmap.Data(0, iy);
- for (int ix = 0; ix < Bitmap.Width(); ix++, ptr += sizeof(tIndex)) {
- // DrawPixel is b0rked
- //Osd->DrawPixel(x + ix, y + iy, Bitmap.Color(*ptr));
- Osd->DrawRectangle(x + ix, y + iy, x + ix, y + iy, Bitmap.Color(*ptr));
- }
- }
-}
-
const char *ChannelNumber(const cChannel *Channel, int Number) {
static char buffer[256];
buffer[0] = '\0';
diff --git a/common.h b/common.h
index 340b5e9..24a7f41 100644
--- a/common.h
+++ b/common.h
@@ -1,5 +1,5 @@
/*
- * $Id: common.h,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: common.h,v 1.7 2004/06/05 16:52:44 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_COMMON_H
@@ -14,14 +14,16 @@ using std::string;
using std::vector;
using std::map;
-#define precond(x) if ((x)) { esyslog("ERROR: text2skin: "#x " not given"); return; }
+#ifdef DEBUG
+# define Dprintf(x...) fprintf(stderr, x);
+#else
+# define Dprintf(x...)
+#endif
class cChannel;
class cText2SkinItem;
const char *SkinPath(void);
-void DrawTextTransparent(cOsd *Osd, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment);
-void DrawBitmap(cOsd *Osd, int x, int y, cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0);
const char *ChannelNumber(const cChannel *Channel, int Number);
const char *ChannelName(const cChannel *Channel, int Number);
diff --git a/data.c b/data.c
index 9d6cdb2..dd8d097 100644
--- a/data.c
+++ b/data.c
@@ -1,13 +1,30 @@
/*
- * $Id: data.c,v 1.12 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: data.c,v 1.13 2004/06/05 01:39:36 lordjaxom Exp $
*/
#include "data.h"
#include "common.h"
static string SectionNames[__SECTION_COUNT__] =
- { "Skin", "ChannelSmall", "Channel", "Volume",
- "ReplayMode", "Replay", "Message", "Menu" };
+ { "Skin", "ChannelSmall", "Channel", "Volume", "ReplayMode", "Replay",
+ "Message", "Menu" };
+
+static string ItemNames[__ITEM_COUNT__] =
+ { "Unknown", "Skin", "Background", "Text", "Image", "Rectangle", "Ellipse",
+ "Slope", "DateTime", "Date", "Time", "ChannelLogo", "ChannelNumberName",
+ "ChannelNumber", "ChannelName", "Language", "Timebar", "PresentTime",
+ "PresentTitle", "PresentShortText", "FollowingTime", "FollowingTitle",
+ "FollowingShortText", "SymbolTeletext", "SymbolAudio", "SymbolDolby",
+ "SymbolEncrypted", "SymbolRecording", "SymbolRadio", "Volumebar", "Mute",
+ "Replaybar", "ReplayTitle", "ReplayCurrent", "ReplayTotal", "ReplayJump",
+ "SymbolPlay", "SymbolPause", "SymbolFastFwd", "SymbolFastRew",
+ "SymbolSlowFwd", "SymbolSlowRew", "MessageStatus", "MessageInfo",
+ "MessageWarning", "MessageError", "MenuArea", "MenuItem", "MenuCurrent",
+ "MenuTitle", "MenuRed", "MenuGreen", "MenuYellow", "MenuBlue", "MenuText",
+ "SymbolScrollUp", "SymbolScrollDown", "MenuEventTitle",
+ "MenuEventShortText", "MenuEventDescription", "MenuEventTime",
+ "SymbolEventRunning", "SymbolEventTimer", "SymbolEventVPS",
+ "MenuRecording" };
cText2SkinItem::cText2SkinItem(void) {
mItem = itemUnknown;
@@ -17,40 +34,17 @@ cText2SkinItem::cText2SkinItem(void) {
mSize.h = 0;
mBpp = 4;
mArc = 0;
- //mFg = NULL;
- //mBg = NULL;
mFont = cFont::GetFont(fontOsd);
mAlign = taDefault;
}
cText2SkinItem::~cText2SkinItem() {
- //delete mBg;
- //delete mFg;
}
bool cText2SkinItem::Parse(const char *Text) {
char *text = strdup(Text);
char *ptr = text;
- /*ptr = text + strlen(text) - 1;
- for (; ptr >= text && *ptr == ' '; --ptr)
- *ptr = '\0';
- ptr = skipspace(text);
- if (*ptr == '\0' || *ptr == '#') // empty line or comment
- return true;
- else if (*ptr == '[' && ptr[strlen(ptr)-1] == ']') { // section
- ++ptr;
- ptr[strlen(ptr)-1] = '\0';
- if (strcmp(ptr, "Channel") == 0) mParseSection = sectionChannel;
- else if (strcmp(ptr, "ChannelSmall") == 0) mParseSection = sectionChannelSmall;
- else if (strcmp(ptr, "Menu") == 0) mParseSection = sectionMenu;
- else if (strcmp(ptr, "Volume") == 0) mParseSection = sectionVolume;
- else if (strcmp(ptr, "ReplayMode") == 0) mParseSection = sectionReplayMode;
- else if (strcmp(ptr, "Replay") == 0) mParseSection = sectionReplay;
- else if (strcmp(ptr, "Message") == 0) mParseSection = sectionMessage;
- return true;
- }*/
-
// check if this is an item
string item;
if (ParseVar(ptr, "Item", item)) {
@@ -59,62 +53,19 @@ bool cText2SkinItem::Parse(const char *Text) {
mItem = itemSkin;
else
esyslog("ERROR: text2skin: Skin doesn't contain Item=Skin keyphrase");
+ } else {
+ int i;
+ // valid items begin at index two
+ for (i = 2; i < __ITEM_COUNT__; ++i) {
+ if (ItemNames[i] == item) {
+ mItem = (eSkinItem)i;
+ break;
+ }
+ }
+ if (i == __ITEM_COUNT__)
+ esyslog("ERROR: text2skin: %s is not a valid theme item\n", item.c_str());
}
- else if (item == "Background") mItem = itemBackground;
- else if (item == "ChannelLogo") mItem = itemChannelLogo;
- else if (item == "Language") mItem = itemLanguage;
- else if (item == "Text") mItem = itemText;
- else if (item == "Image") mItem = itemImage;
- else if (item == "DateTime") mItem = itemDateTime;
- else if (item == "Date") mItem = itemDate;
- else if (item == "Time") mItem = itemTime;
- else if (item == "ChannelNumberName") mItem = itemChannelNumberName;
- else if (item == "ChannelNumber") mItem = itemChannelNumber;
- else if (item == "ChannelName") mItem = itemChannelName;
- else if (item == "Rectangle") mItem = itemRectangle;
- else if (item == "Ellipse") mItem = itemEllipse;
- else if (item == "Slope") mItem = itemSlope;
- else if (item == "Timebar") mItem = itemTimebar;
- else if (item == "PresentTime") mItem = itemPresentTime;
- else if (item == "PresentTitle") mItem = itemPresentTitle;
- else if (item == "PresentShortText") mItem = itemPresentShortText;
- else if (item == "FollowingTime") mItem = itemFollowingTime;
- else if (item == "FollowingTitle") mItem = itemFollowingTitle;
- else if (item == "FollowingShortText") mItem = itemFollowingShortText;
- else if (item == "SymbolTeletext") mItem = itemSymbolTeletext;
- else if (item == "SymbolAudio") mItem = itemSymbolAudio;
- else if (item == "SymbolDolby") mItem = itemSymbolDolby;
- else if (item == "SymbolEncrypted") mItem = itemSymbolEncrypted;
- else if (item == "SymbolRecording") mItem = itemSymbolRecording;
- else if (item == "SymbolRadio") mItem = itemSymbolRadio;
- else if (item == "Volumebar") mItem = itemVolumebar;
- else if (item == "Mute") mItem = itemMute;
- else if (item == "Replaybar") mItem = itemReplaybar;
- else if (item == "ReplayTitle") mItem = itemReplayTitle;
- else if (item == "ReplayCurrent") mItem = itemReplayCurrent;
- else if (item == "ReplayTotal") mItem = itemReplayTotal;
- else if (item == "ReplayJump") mItem = itemReplayJump;
- else if (item == "SymbolPlay") mItem = itemSymbolPlay;
- else if (item == "SymbolPause") mItem = itemSymbolPause;
- else if (item == "SymbolFastFwd") mItem = itemSymbolFastFwd;
- else if (item == "SymbolFastRew") mItem = itemSymbolFastRew;
- else if (item == "SymbolSlowFwd") mItem = itemSymbolSlowFwd;
- else if (item == "SymbolFastFwd") mItem = itemSymbolFastFwd;
- else if (item == "MessageStatus") mItem = itemMessageStatus;
- else if (item == "MessageInfo") mItem = itemMessageInfo;
- else if (item == "MessageWarning") mItem = itemMessageWarning;
- else if (item == "MessageError") mItem = itemMessageError;
- else if (item == "MenuArea") mItem = itemMenuArea;
- else if (item == "MenuItem") mItem = itemMenuItem;
- else if (item == "MenuCurrent") mItem = itemMenuCurrent;
- else if (item == "MenuTitle") mItem = itemMenuTitle;
- else if (item == "MenuRed") mItem = itemMenuRed;
- else if (item == "MenuGreen") mItem = itemMenuGreen;
- else if (item == "MenuYellow") mItem = itemMenuYellow;
- else if (item == "MenuBlue") mItem = itemMenuBlue;
- else
- esyslog("ERROR: text2skin: %s is not a valid theme item\n", item.c_str());
-
+
if (mItem != itemUnknown) {
if (mItem != itemSkin)
ParseItem(ptr);
diff --git a/data.h b/data.h
index a8dbd43..d3f59a0 100644
--- a/data.h
+++ b/data.h
@@ -1,5 +1,5 @@
/*
- * $Id: data.h,v 1.10 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: data.h,v 1.11 2004/06/05 01:39:36 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_DATA_H
@@ -80,6 +80,18 @@ enum eSkinItem {
itemMenuGreen,
itemMenuYellow,
itemMenuBlue,
+ itemMenuText,
+ itemSymbolScrollUp,
+ itemSymbolScrollDown,
+ itemMenuEventTitle,
+ itemMenuEventShortText,
+ itemMenuEventDescription,
+ itemMenuEventTime,
+ itemSymbolEventRunning,
+ itemSymbolEventTimer,
+ itemSymbolEventVPS,
+ itemMenuRecording,
+ __ITEM_COUNT__
};
struct POINT {
@@ -124,8 +136,6 @@ public:
const SIZE &Size(void) const { return mSize; }
int Bpp(void) const { return mBpp; }
int Arc(void) const { return mArc; }
- //const tColor *Fg(void) const { return mFg; }
- //const tColor *Bg(void) const { return mBg; }
const string &Fg(void) const { return mFg; }
const string &Bg(void) const { return mBg; }
const cFont *Font(void) const { return mFont; }
diff --git a/display.c b/display.c
index 88abfa1..93ccb32 100644
--- a/display.c
+++ b/display.c
@@ -1,5 +1,5 @@
/*
- * $Id: display.c,v 1.9 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: display.c,v 1.12 2004/06/05 18:04:29 lordjaxom Exp $
*/
#include "render.h"
@@ -81,6 +81,7 @@ void cText2SkinDisplayVolume::Flush(void) {
// --- cText2SkinDisplayReplay ------------------------------------------------
cText2SkinDisplayReplay::cText2SkinDisplayReplay(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool ModeOnly) {
+ Dprintf("ModeOnly: %d\n", ModeOnly);
mRender = new cText2SkinRender(Data, I18n, Theme, ModeOnly ? sectionReplayMode : sectionReplay);
mDirty = false;
}
@@ -98,7 +99,7 @@ void cText2SkinDisplayReplay::SetTitle(const char *Title) {
}
void cText2SkinDisplayReplay::SetMode(bool Play, bool Forward, int Speed) {
- if (mRender->mReplayPlay != Play || mRender->mReplayPlay != Forward || mRender->mReplaySpeed != Speed) {
+ if (mRender->mReplayPlay != Play || mRender->mReplayForward != Forward || mRender->mReplaySpeed != Speed) {
mRender->mReplayPlay = Play;
mRender->mReplayForward = Forward;
mRender->mReplaySpeed = Speed;
@@ -209,7 +210,15 @@ cText2SkinDisplayMenu::~cText2SkinDisplayMenu() {
void cText2SkinDisplayMenu::Clear(void) {
mRender->mMenuItems.clear();
- mRender->mMenuCurrent = -1;
+ mRender->mMenuTitle = "";
+ mRender->mMenuCurrent = -1;
+ mRender->mMenuRed = "";
+ mRender->mMenuGreen = "";
+ mRender->mMenuYellow = "";
+ mRender->mMenuBlue = "";
+ mRender->mMenuEvent = NULL;
+ mRender->mMenuRecording = NULL;
+ mRender->mMenuText = "";
mDirty = true;
}
@@ -245,7 +254,17 @@ void cText2SkinDisplayMenu::SetMessage(eMessageType Type, const char *Text) {
}
void cText2SkinDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) {
- cText2SkinRender::MenuItem item = { Text, Selectable };
+ cText2SkinRender::MenuItem item;
+ item.text = Text;
+ item.sel = Selectable;
+ for (int i = 0; i < MaxTabs; ++i) {
+ const char *tab = GetTabbedText(Text, i);
+ if (tab)
+ item.tabs[i] = tab;
+ if (!Tab(i + 1))
+ break;
+ }
+ SetEditableWidth(mRender->GetEditableWidth(item, Current));
if ((int)mRender->mMenuItems.size() <= Index) {
mRender->mMenuItems.push_back(item);
mDirty = true;
@@ -282,6 +301,25 @@ void cText2SkinDisplayMenu::SetText(const char *Text, bool FixedFont) {
}
}
+void cText2SkinDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5) {
+ cSkinDisplayMenu::SetTabs(Tab1, Tab2, Tab3, Tab4, Tab5);
+ mRender->mMenuTabs[0] = Tab(0);
+ mRender->mMenuTabs[1] = Tab(1);
+ mRender->mMenuTabs[2] = Tab(2);
+ mRender->mMenuTabs[3] = Tab(3);
+ mRender->mMenuTabs[4] = Tab(4);
+ mRender->mMenuTabs[5] = Tab(5);
+}
+
+void cText2SkinDisplayMenu::Scroll(bool Up, bool Page) {
+ if (mRender->mScroller && (Up ? mRender->mScroller->CanScrollUp() : mRender->mScroller->CanScrollDown())) {
+ mRender->mMenuScroll = true;
+ mRender->mMenuScrollUp = Up;
+ mRender->mMenuScrollPage = Page;
+ mDirty = true;
+ }
+}
+
void cText2SkinDisplayMenu::Flush(void) {
if (mDirty) {
mRender->Flush();
diff --git a/display.h b/display.h
index e7d7926..afb24db 100644
--- a/display.h
+++ b/display.h
@@ -1,5 +1,5 @@
/*
- * $Id: display.h,v 1.3 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: display.h,v 1.5 2004/06/05 18:04:29 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_SKIN_H
@@ -89,6 +89,8 @@ public:
virtual void SetEvent(const cEvent *Event);
virtual void SetRecording(const cRecording *Recording);
virtual void SetText(const char *Text, bool FixedFont);
+ virtual void SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5);
+ virtual void Scroll(bool Up, bool Page);
virtual void Flush(void);
};
diff --git a/i18n.c b/i18n.c
index 0583ae1..7c28ca6 100644
--- a/i18n.c
+++ b/i18n.c
@@ -1,5 +1,5 @@
/*
- * $Id: i18n.c,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: i18n.c,v 1.2 2004/06/05 16:52:44 lordjaxom Exp $
*/
#include "i18n.h"
@@ -24,12 +24,20 @@ bool cText2SkinI18n::Parse(const char *Text) {
memset(&p, 0, sizeof(tI18nPhrase));
Text += 17;
+
for (i = 0; i < I18nNumLanguages; ++i) {
+ char *langs = strdup(I18nLanguageCode(i));
+ char *ptr = langs, *ep;
string text;
- if (ParseVar(Text, I18nLanguageCode(i), text))
- p[i] = strdup(text.c_str());
- else
- p[i] = "";
+ p[i] = "";
+ do {
+ if ((ep = strchr(ptr, ',')) != NULL)
+ *ep = '\0';
+ if (ParseVar(Text, ptr, text))
+ p[i] = strdup(text.c_str());
+ ptr = ep + 1;
+ } while (ep != NULL);
+ free(langs);
}
int idx = mNumPhrases++;
diff --git a/loader.c b/loader.c
index 3ec9052..3523bf9 100644
--- a/loader.c
+++ b/loader.c
@@ -1,5 +1,5 @@
/*
- * $Id: loader.c,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: loader.c,v 1.8 2004/06/05 16:52:44 lordjaxom Exp $
*/
#include "loader.h"
@@ -34,9 +34,8 @@ void cText2SkinLoader::Load(const char *Skin) {
string transfile = (string)SkinPath() + "/" + Skin + "/" + Skin + ".trans";
if (access(transfile.c_str(), F_OK) == 0) {
translations = new cText2SkinI18n(Skin);
- if (!translations->Load(transfile)) {
+ if (!translations->Load(transfile))
DELETENULL(translations);
- }
}
cText2SkinTheme *theme = new cText2SkinTheme(Skin);
@@ -74,7 +73,7 @@ cText2SkinLoader::~cText2SkinLoader() {
}
cSkinDisplayChannel *cText2SkinLoader::DisplayChannel(bool WithInfo) {
- printf("WithInfo: %d\n", WithInfo);
+ Dprintf("WithInfo: %d\n", WithInfo);
return new cText2SkinDisplayChannel(mData, mI18n, mTheme, WithInfo);
}
diff --git a/patches/vdr-1.3.9-osd.diff b/patches/vdr-1.3.9-osd.diff
new file mode 100644
index 0000000..0da295b
--- /dev/null
+++ b/patches/vdr-1.3.9-osd.diff
@@ -0,0 +1,106 @@
+diff -Nru -x PLUGINS o/vdr-1.3.9/osd.c vdr-1.3.9/osd.c
+--- o/vdr-1.3.9/osd.c 2004-05-28 17:33:22.000000000 +0200
++++ vdr-1.3.9/osd.c 2004-06-05 17:25:33.036994648 +0200
+@@ -244,7 +246,7 @@
+ return Result;
+ }
+
+-bool cBitmap::SetXpm(char *Xpm[])
++bool cBitmap::SetXpm(char *Xpm[], bool IgnoreNone)
+ {
+ char **p = Xpm;
+ int w, h, n, c;
+@@ -257,10 +259,11 @@
+ return false;
+ }
+ int b = 0;
+- while (1 << (1 << b) < n)
++ while (1 << (1 << b) < (IgnoreNone ? n - 1 : n))
+ b++;
+ SetBpp(1 << b);
+ SetSize(w, h);
++ int NoneColorIndex = MAXNUMCOLORS;
+ for (int i = 0; i < n; i++) {
+ const char *s = *++p;
+ if (int(strlen(s)) < c) {
+@@ -273,14 +276,18 @@
+ return false;
+ }
+ s = skipspace(s + 1);
+- if (strcasecmp(s, "none") == 0)
+- s = "#00000000";
++ if (strcasecmp(s, "none") == 0) {
++ s = "#00000000";
++ NoneColorIndex = i;
++ if (IgnoreNone)
++ continue;
++ }
+ if (*s != '#') {
+ esyslog("ERROR: unknown color code in XPM: '%c'", *s);
+ return false;
+ }
+ tColor color = strtoul(++s, NULL, 16) | 0xFF000000;
+- SetColor(i, color);
++ SetColor((IgnoreNone && i > NoneColorIndex) ? i - 1 : i, color);
+ }
+ for (int y = 0; y < h; y++) {
+ const char *s = *++p;
+@@ -295,13 +302,17 @@
+ return false;
+ }
+ if (strncmp(Xpm[i + 1], s, c) == 0) {
+- SetIndex(x, y, i);
++ if (i == NoneColorIndex)
++ NoneColorIndex = MAXNUMCOLORS;
++ SetIndex(x, y, (IgnoreNone && i > NoneColorIndex) ? i - 1 : i);
+ break;
+ }
+ }
+ s += c;
+ }
+ }
++ if (NoneColorIndex < MAXNUMCOLORS && !IgnoreNone)
++ return SetXpm(Xpm, true);
+ return true;
+ }
+
+@@ -354,7 +365,8 @@
+ int ch = Height ? Height : h;
+ if (!Intersects(x, y, x + cw - 1, y + ch - 1))
+ return;
+- DrawRectangle(x, y, x + cw - 1, y + ch - 1, ColorBg);
++ if (ColorBg != clrTransparent)
++ DrawRectangle(x, y, x + cw - 1, y + ch - 1, ColorBg);
+ limit = x + cw - x0;
+ if (Width) {
+ if ((Alignment & taLeft) != 0)
+@@ -395,7 +408,8 @@
+ for (int row = 0; row < h; row++) {
+ cFont::tPixelData PixelData = CharData->lines[row];
+ for (int col = CharData->width; col-- > 0; ) {
+- SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg);
++ if (ColorBg != clrTransparent || (PixelData & 1))
++ SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg);
+ PixelData >>= 1;
+ }
+ }
+diff -Nru -x PLUGINS o/vdr-1.3.9/osd.h vdr-1.3.9/osd.h
+--- o/vdr-1.3.9/osd.h 2004-05-29 16:02:47.000000000 +0200
++++ vdr-1.3.9/osd.h 2004-06-05 17:15:17.809523440 +0200
+@@ -136,9 +136,15 @@
+ bool LoadXpm(const char *FileName);
+ ///< Calls SetXpm() with the data from the file FileName.
+ ///< Returns true if the operation was successful.
+- bool SetXpm(char *Xpm[]);
++ bool SetXpm(char *Xpm[], bool IgnoreNone = false);
+ ///< Sets this bitmap to the given XPM data. Any previous bitmap or
+ ///< palette data will be overwritten with the new data.
++ ///< If IgnoreNone is true, a "none" color entry will be ignored.
++ ///< Only set IgnoreNone to true if you know that there is a "none"
++ ///< color entry in the XPM data and that this entry is not used!
++ ///< If SetXpm() is called with IgnoreNone set to false and the XPM
++ ///< data contains an unused "none" entry, it will be automatically
++ ///< called again with IgnoreNone set to true.
+ ///< Returns true if the operation was successful.
+ void SetIndex(int x, int y, tIndex Index);
+ ///< Sets the index at the given coordinates to Index.
diff --git a/render.c b/render.c
index 0437c84..b12b5e9 100644
--- a/render.c
+++ b/render.c
@@ -1,5 +1,5 @@
/*
- * $Id: render.c,v 1.16 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: render.c,v 1.19 2004/06/05 18:04:29 lordjaxom Exp $
*/
#include "render.h"
@@ -18,6 +18,7 @@ cText2SkinRender::cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, c
mTheme = Theme;
mSection = Section;
mOsd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop);
+ mScroller = NULL;
mChannel = NULL;
mChannelNumber = 0;
mVolumeCurrent = 0;
@@ -36,6 +37,9 @@ cText2SkinRender::cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, c
mMenuEvent = NULL;
mMenuRecording = NULL;
mMenuTextFixedFont = false;
+ mMenuScroll = false;
+ mMenuScrollUp = false;
+ mMenuScrollPage = false;
cText2SkinData::tIterator it = Data->First(mSection);
for (; it != Data->Last(mSection); ++it) {
@@ -81,6 +85,7 @@ cText2SkinRender::cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, c
}
cText2SkinRender::~cText2SkinRender() {
+ delete mScroller;
delete mOsd;
}
@@ -143,6 +148,11 @@ void cText2SkinRender::Flush(void) {
case itemSymbolFastRew:
case itemSymbolSlowFwd:
case itemSymbolSlowRew:
+ case itemSymbolScrollUp:
+ case itemSymbolScrollDown:
+ case itemSymbolEventRunning:
+ case itemSymbolEventTimer:
+ case itemSymbolEventVPS:
DisplaySymbol(item); break;
case itemVolumebar:
DisplayVolumebar(item); break;
@@ -172,6 +182,18 @@ void cText2SkinRender::Flush(void) {
case itemMenuYellow:
case itemMenuBlue:
DisplayMenuColorbutton(item); break;
+ case itemMenuText:
+ DisplayMenuText(item); break;
+ case itemMenuEventTitle:
+ DisplayMenuEventTitle(item); break;
+ case itemMenuEventShortText:
+ DisplayMenuEventShortText(item); break;
+ case itemMenuEventDescription:
+ DisplayMenuEventDescription(item); break;
+ case itemMenuEventTime:
+ DisplayMenuEventTime(item); break;
+ case itemMenuRecording:
+ DisplayMenuRecording(item); break;
default:
break;
}
@@ -180,41 +202,39 @@ void cText2SkinRender::Flush(void) {
}
void cText2SkinRender::DrawBackground(const POINT &Pos, const SIZE &Size, const tColor *Bg, const tColor *Fg, const string &Path) {
- bool image = false;
- cText2SkinBitmap bm;
+ cText2SkinBitmap *bmp = NULL;
if (Path != "") {
char *p;
asprintf(&p, "%s/%s/%s", SkinPath(), mData->Skin().c_str(), Path.c_str());
- if (bm.Load(p)) {
- if (Bg) bm.SetColor(0, *Bg);
- if (Fg) bm.SetColor(1, *Fg);
- image = true;
+ if ((bmp = cText2SkinBitmap::Load(p)) != NULL) {
+ if (Bg) bmp->SetColor(0, *Bg);
+ if (Fg) bmp->SetColor(1, *Fg);
}
free(p);
}
- if (image)
- DrawBitmap(mOsd, Pos.x, Pos.y, bm);
+ if (bmp)
+ mOsd->DrawBitmap(Pos.x, Pos.y, *bmp);
else
mOsd->DrawRectangle(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, Bg ? *Bg : 0);
}
void cText2SkinRender::DrawImage(const POINT &Pos, const SIZE &Size, const tColor *Bg, const tColor *Fg, const string &Path) {
- cText2SkinBitmap bm;
+ cText2SkinBitmap *bmp;
char *p;
asprintf(&p, "%s/%s/%s", SkinPath(), mData->Skin().c_str(), Path.c_str());
- printf("Trying to load image: %s\n", p);
- if (bm.Load(p)) {
- if (Bg) bm.SetColor(0, *Bg);
- if (Fg) bm.SetColor(1, *Fg);
+ Dprintf("Trying to load image: %s\n", p);
+ if ((bmp = cText2SkinBitmap::Load(p)) != NULL) {
+ if (Bg) bmp->SetColor(0, *Bg);
+ if (Fg) bmp->SetColor(1, *Fg);
//mOsd->DrawRectangle(Pos.x, Pos.y, Pos.x + Size.w - 1, Pos.y + Size.h - 1, bm.Color(0));
- DrawBitmap(mOsd, Pos.x, Pos.y, bm);
+ mOsd->DrawBitmap(Pos.x, Pos.y, *bmp);
}
free(p);
}
void cText2SkinRender::DrawText(const POINT &Pos, const SIZE &Size, const tColor *Fg, const string &Text, const cFont *Font, int Align) {
- DrawTextTransparent(mOsd, Pos.x, Pos.y, Text.c_str(), Fg ? *Fg : 0, 0, Font, Size.w, Size.h, Align);
+ mOsd->DrawText(Pos.x, Pos.y, Text.c_str(), Fg ? *Fg : 0, 0, Font, Size.w, Size.h, Align);
}
void cText2SkinRender::DrawRectangle(const POINT &Pos, const SIZE &Size, const tColor *Fg) {
@@ -300,6 +320,15 @@ void cText2SkinRender::DrawMark(const POINT &Pos, const SIZE &Size, bool Start,
}
}
+void cText2SkinRender::DrawScrollText(const POINT &Pos, const SIZE &Size, const tColor *Fg, const string &Text, const cFont *Font, int Align) {
+ if (mScroller == NULL)
+ mScroller = new cTextScroller(mOsd, Pos.x, Pos.y, Size.w, Size.h, Text.c_str(), Font, Fg ? *Fg : 0, clrTransparent);
+ else if (mMenuScroll) {
+ mScroller->Scroll(mMenuScrollUp, mMenuScrollPage);
+ mMenuScroll = false;
+ }
+}
+
void cText2SkinRender::DisplayBackground(cText2SkinItem *Item) {
DrawBackground(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), Item->Path());
}
@@ -315,13 +344,13 @@ void cText2SkinRender::DisplayLanguage(cText2SkinItem *Item) {
int current;
const char **tracks = cDevice::PrimaryDevice()->GetAudioTracks(&current);
if (Item->Path() != "" && Item->Type() != "" && tracks) {
- printf("Languages: ");
+ Dprintf("Languages: ");
int i = 0;
while (tracks[i]) {
- printf("%s%s, ", tracks[i], i == current ? " (current)" : "");
+ Dprintf("%s%s, ", tracks[i], i == current ? " (current)" : "");
++i;
}
- printf("\n");
+ Dprintf("\n");
if (current < i) {
string path = Item->Path() + "/" + tracks[current] + "." + Item->Type();
DrawImage(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), path);
@@ -444,22 +473,45 @@ void cText2SkinRender::DisplaySymbol(cText2SkinItem *Item) {
default:
break;
}
- } else if (mSection == sectionReplay) {
+ } else if (mSection == sectionReplay || mSection == sectionReplayMode) {
switch (Item->Item()) {
- case itemSymbolPlay:
- image = (mReplaySpeed == -1 && mReplayPlay) ? Item->Path() : Item->AltPath(); break;
- case itemSymbolPause:
- image = (mReplaySpeed == -1 && !mReplayPlay) ? Item->Path() : Item->AltPath(); break;
- case itemSymbolFastFwd:
- image = (mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); break;
- case itemSymbolFastRew:
- image = (mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); break;
- case itemSymbolSlowFwd:
- image = (!mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); break;
- case itemSymbolSlowRew:
- image = (!mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolPlay:
+ image = (mReplaySpeed == -1 && mReplayPlay) ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolPause:
+ image = (mReplaySpeed == -1 && !mReplayPlay) ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolFastFwd:
+ image = (mReplaySpeed != -1 && mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolFastRew:
+ image = (mReplaySpeed != -1 && mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolSlowFwd:
+ image = (mReplaySpeed != -1 && !mReplayPlay && mReplayForward) ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolSlowRew:
+ image = (mReplaySpeed != -1 && !mReplayPlay && !mReplayForward) ? Item->Path() : Item->AltPath(); break;
+ default:
+ break;
+ }
+ } else if (mSection == sectionMenu) {
+ if (mScroller) {
+ switch (Item->Item()) {
+ case itemSymbolScrollUp:
+ image = mScroller->CanScrollUp() ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolScrollDown:
+ image = mScroller->CanScrollDown() ? Item->Path() : Item->AltPath(); break;
+ default:
+ break;
+ }
+ }
+ if (mMenuEvent) {
+ switch (Item->Item()) {
+ case itemSymbolEventRunning:
+ image = mMenuEvent->IsRunning() ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolEventTimer:
+ image = mMenuEvent->HasTimer() ? Item->Path() : Item->AltPath(); break;
+ case itemSymbolEventVPS:
+ image = mMenuEvent->Vps() > 0 ? Item->Path() : Item->AltPath(); break;
default:
break;
+ }
}
}
if (image != "")
@@ -543,21 +595,26 @@ void cText2SkinRender::DisplayMenuItems(cText2SkinItem *Item) {
int index = 0;
while (yoffs < area->Pos().y + area->Size().h && index < (int)mMenuItems.size()) {
- if (index == mMenuCurrent) {
- POINT pt = { xoffs, yoffs };
- if (current->Pos().x != -1)
- pt.x += current->Pos().x;
- if (current->Pos().y != -1)
- pt.y += current->Pos().y;
- SIZE size = { current->Size().w, current->Size().h };
- if (ItemBg(current))
- DrawRectangle(pt, size, ItemBg(current));
- DrawText(pt, size, ItemFg(current), mMenuItems[index].name.c_str(), current->Font(), current->Align());
- } else {
- POINT pt = { xoffs + Item->Pos().x, yoffs + Item->Pos().y };
- SIZE size = { Item->Size().w, Item->Size().h };
- DrawText(pt, size, ItemFg(Item), mMenuItems[index].name.c_str(), Item->Font(), Item->Align());
+ cText2SkinItem *item = (index == mMenuCurrent) ? current : Item;
+ POINT pt = { xoffs, yoffs };
+ SIZE size = item->Size();
+ if (item->Pos().x != -1)
+ pt.x += item->Pos().x;
+ if (item->Pos().y != -1)
+ pt.y += item->Pos().y;
+ if (ItemBg(item))
+ DrawRectangle(pt, size, ItemBg(item));
+
+ for (int i = 0; i < cSkinDisplayMenu::MaxTabs; ++i) {
+ if (mMenuItems[index].tabs[i] != "") {
+ POINT pt2 = { pt.x + mMenuTabs[i], pt.y };
+ SIZE sz = { size.w - mMenuTabs[i], size.h };
+ DrawText(pt2, sz, ItemFg(item), mMenuItems[index].tabs[i], item->Font(), item->Align());
+ }
+ if (!mMenuTabs[i + 1])
+ break;
}
+
yoffs += Item->Size().h;
++index;
}
@@ -585,6 +642,40 @@ void cText2SkinRender::DisplayMenuColorbutton(cText2SkinItem *Item) {
DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text), Item->Font(), Item->Align());
}
+void cText2SkinRender::DisplayMenuText(cText2SkinItem *Item) {
+ if (mMenuText != "")
+ DrawScrollText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mMenuText), Item->Font(), Item->Align());
+ else
+ DELETENULL(mScroller);
+}
+
+void cText2SkinRender::DisplayMenuEventTitle(cText2SkinItem *Item) {
+ if (mMenuEvent && mMenuEvent->Title())
+ DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mMenuEvent->Title()), Item->Font(), Item->Align());
+}
+
+void cText2SkinRender::DisplayMenuEventShortText(cText2SkinItem *Item) {
+ if (mMenuEvent && mMenuEvent->ShortText())
+ DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mMenuEvent->ShortText()), Item->Font(), Item->Align());
+}
+
+void cText2SkinRender::DisplayMenuEventDescription(cText2SkinItem *Item) {
+ if (mMenuEvent && mMenuEvent->Description())
+ DrawScrollText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mMenuEvent->Description()), Item->Font(), Item->Align());
+}
+
+void cText2SkinRender::DisplayMenuEventTime(cText2SkinItem *Item) {
+ if (mMenuEvent) {
+ const char *text = DayDateTime(mMenuEvent->StartTime());
+ DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text + 10), Item->Font(), Item->Align());
+ }
+}
+
+void cText2SkinRender::DisplayMenuRecording(cText2SkinItem *Item) {
+ if (mMenuRecording)
+ DrawScrollText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mMenuRecording->Summary()), Item->Font(), Item->Align());
+}
+
string cText2SkinRender::ItemText(cText2SkinItem *Item) {
return mI18n ? mI18n->Translate(Item->Text()) : Item->Text();
}
@@ -624,3 +715,12 @@ tColor *cText2SkinRender::ItemBg(cText2SkinItem *Item) {
return NULL;
return &Bg;
}
+
+int cText2SkinRender::GetEditableWidth(MenuItem Item, bool Current) {
+ cText2SkinItem *current;
+ if (Current)
+ current = mData->Get(sectionMenu, itemMenuCurrent);
+ else
+ current = mData->Get(sectionMenu, itemMenuItem);
+ return current->Size().w - mMenuTabs[1];
+}
diff --git a/render.h b/render.h
index e96fd08..e27ac5b 100644
--- a/render.h
+++ b/render.h
@@ -1,5 +1,5 @@
/*
- * $Id: render.h,v 1.12 2004/06/02 20:43:05 lordjaxom Exp $
+ * $Id: render.h,v 1.15 2004/06/05 18:04:29 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_RENDER_H
@@ -28,6 +28,7 @@ private:
cText2SkinTheme *mTheme;
eSkinSection mSection;
cOsd *mOsd;
+ cTextScroller *mScroller;
// channel display
const cChannel *mChannel;
@@ -58,9 +59,10 @@ private:
// menu
struct MenuItem {
- string name;
+ string text;
+ string tabs[cSkinDisplayMenu::MaxTabs];
bool sel;
- bool operator!=(const MenuItem &b) { return b.name != name || b.sel != sel; }
+ bool operator!=(const MenuItem &b) { return b.text != text || b.sel != sel; }
};
string mMenuTitle;
vector<MenuItem> mMenuItems;
@@ -73,7 +75,11 @@ private:
const cRecording *mMenuRecording;
string mMenuText;
bool mMenuTextFixedFont;
-
+ bool mMenuScroll;
+ bool mMenuScrollUp;
+ bool mMenuScrollPage;
+ int mMenuTabs[cSkinDisplayMenu::MaxTabs];
+
protected:
// Basic operations
void DrawBackground(const POINT &Pos, const SIZE &Size, const tColor *Bg, const tColor *Fg, const string &Path);
@@ -84,6 +90,7 @@ protected:
void DrawSlope(const POINT &Pos, const SIZE &Size, const tColor *Fg, int Arc);
void DrawProgressbar(const POINT &Pos, const SIZE &Size, int Current, int Total, const tColor *Fg, const tColor *Bg, const cMarks *Marks = NULL);
void DrawMark(const POINT &Pos, const SIZE &Size, bool Start, bool Current, bool Horizontal);
+ void DrawScrollText(const POINT &Pos, const SIZE &Size, const tColor *Fg, const string &Text, const cFont *Font, int Align);
// High-level operations
void DisplayBackground(cText2SkinItem *Item);
@@ -119,13 +126,19 @@ protected:
void DisplayMenuItems(cText2SkinItem *Item);
void DisplayMenuTitle(cText2SkinItem *Item);
void DisplayMenuColorbutton(cText2SkinItem *Item);
- void DisplayMenuMessage(cText2SkinItem *Item);
+ void DisplayMenuText(cText2SkinItem *Item);
+ void DisplayMenuEventTitle(cText2SkinItem *Item);
+ void DisplayMenuEventShortText(cText2SkinItem *Item);
+ void DisplayMenuEventDescription(cText2SkinItem *Item);
+ void DisplayMenuEventTime(cText2SkinItem *Item);
+ void DisplayMenuRecording(cText2SkinItem *Item);
// Helpers
string ItemText(cText2SkinItem *Item);
string ItemText(cText2SkinItem *Item, const string &Content);
tColor *ItemFg(cText2SkinItem *Item);
tColor *ItemBg(cText2SkinItem *Item);
+ int GetEditableWidth(MenuItem Item, bool Current);
public:
cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, eSkinSection Section);
diff --git a/text2skin.c b/text2skin.c
index 68602d2..bd52294 100644
--- a/text2skin.c
+++ b/text2skin.c
@@ -3,26 +3,15 @@
*
* See the README file for copyright information and how to reach the author.
*
- * $Id: text2skin.c,v 1.9 2004/06/02 19:55:55 lordjaxom Exp $
+ * $Id: text2skin.c,v 1.10 2004/06/05 16:52:44 lordjaxom Exp $
*/
+#include "text2skin.h"
#include "loader.h"
-#include <vdr/plugin.h>
-
-static const char *VERSION = "0.0.1-rc4";
-static const char *DESCRIPTION = "Loader for text-based skins";
-
-class cText2SkinPlugin : public cPlugin {
-private:
-public:
- cText2SkinPlugin(void);
- virtual ~cText2SkinPlugin();
- virtual const char *Version(void) { return VERSION; }
- virtual const char *Description(void) { return DESCRIPTION; }
- virtual bool Start(void);
- virtual cMenuSetupPage *SetupMenu(void);
- virtual bool SetupParse(const char *Name, const char *Value);
- };
+
+const char *cText2SkinPlugin::VERSION = "0.0.1";
+const char *cText2SkinPlugin::THEMEVERSION = "0.0.1";
+const char *cText2SkinPlugin::DESCRIPTION = "Loader for text-based skins";
cText2SkinPlugin::cText2SkinPlugin(void)
{
diff --git a/text2skin.h b/text2skin.h
new file mode 100644
index 0000000..a42faf1
--- /dev/null
+++ b/text2skin.h
@@ -0,0 +1,27 @@
+/*
+ * $Id: text2skin.h,v 1.2 2004/06/05 16:53:14 lordjaxom Exp $
+ */
+
+#ifndef VDR_TEXT2SKIN_H
+#define VDR_TEXT2SKIN_H
+
+#include "common.h"
+#include <vdr/plugin.h>
+
+class cText2SkinPlugin : public cPlugin {
+private:
+ static const char *VERSION;
+ static const char *THEMEVERSION;
+ static const char *DESCRIPTION;
+public:
+ cText2SkinPlugin(void);
+ virtual ~cText2SkinPlugin();
+ virtual const char *Version(void) { return VERSION; }
+ virtual const char *ThemeVersion(void) { return THEMEVERSION; }
+ virtual const char *Description(void) { return DESCRIPTION; }
+ virtual bool Start(void);
+ virtual cMenuSetupPage *SetupMenu(void);
+ virtual bool SetupParse(const char *Name, const char *Value);
+};
+
+#endif // VDR_TEXT2SKIN_H