diff options
author | lordjaxom <lordjaxom> | 2004-06-02 19:56:58 +0000 |
---|---|---|
committer | lordjaxom <lordjaxom> | 2004-06-02 19:56:58 +0000 |
commit | e0c2ee1d37c0f213f22a04df71710bebe3526f85 (patch) | |
tree | 8bfd3a4fa065abeb016134466523a1152202e597 | |
parent | e535cdbe09d9c13d79cd6722aafca5798b7d1e35 (diff) | |
download | vdr-plugin-text2skin-e0c2ee1d37c0f213f22a04df71710bebe3526f85.tar.gz vdr-plugin-text2skin-e0c2ee1d37c0f213f22a04df71710bebe3526f85.tar.bz2 |
- implemented image loading through ImageMagick (fixes crashes when runningv0.0.1-rc4
together with GraphTFT)
- implemented Theme support (see file demo.colors in the demo skin)
- implemented translations for texts used in skins (see file demo.trans in the
demo skin)
-rw-r--r-- | HISTORY | 8 | ||||
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | bitmap.c | 44 | ||||
-rw-r--r-- | bitmap.h | 5 | ||||
-rw-r--r-- | common.c | 66 | ||||
-rw-r--r-- | common.h | 19 | ||||
-rw-r--r-- | data.c | 129 | ||||
-rw-r--r-- | data.h | 52 | ||||
-rw-r--r-- | display.c | 32 | ||||
-rw-r--r-- | display.h | 21 | ||||
-rw-r--r-- | file.c | 44 | ||||
-rw-r--r-- | file.h | 28 | ||||
-rw-r--r-- | font.h | 8 | ||||
-rw-r--r-- | i18n.c | 58 | ||||
-rw-r--r-- | i18n.h | 30 | ||||
-rw-r--r-- | loader.c | 52 | ||||
-rw-r--r-- | loader.h | 18 | ||||
-rw-r--r-- | render.c | 324 | ||||
-rw-r--r-- | render.h | 25 | ||||
-rw-r--r-- | text2skin.c | 8 | ||||
-rw-r--r-- | theme.c | 31 | ||||
-rw-r--r-- | theme.h | 35 |
22 files changed, 704 insertions, 347 deletions
@@ -1,6 +1,14 @@ VDR Plugin 'text2skin' Revision History --------------------------------------- +2004-06-02: Version 0.0.1-rc4 + +- implemented image loading through ImageMagick (fixes crashes when running + together with GraphTFT) +- implemented Theme support (see file demo.colors in the demo skin) +- implemented translations for texts used in skins (see file demo.trans in the + demo skin) + 2004-06-01: Version 0.0.1-rc3 - fixed possible segfault when showing language logo (happened when channel @@ -1,16 +1,15 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile,v 1.3 2004/06/01 21:02:38 lordjaxom Exp $ +# $Id: Makefile,v 1.5 2004/06/02 20:43:05 lordjaxom Exp $ # 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_IMLIB2=1 +# HAVE_IMLIB2=1 -# !!!!THIS DOESN'T WORK YET!!!! # 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 +HAVE_IMAGEMAGICK=1 # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -51,10 +50,12 @@ PACKAGE = vdr-$(ARCHIVE) ifdef HAVE_IMLIB2 DEFINES += -DHAVE_IMLIB2 + LIBS += -lImlib2 endif ifdef HAVE_IMAGEMAGICK DEFINES += -DHAVE_IMAGEMAGICK + LIBS += -lMagick++ endif INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include @@ -63,7 +64,8 @@ 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 +OBJS = $(PLUGIN).o loader.o data.o display.o render.o common.o bitmap.o \ + file.o i18n.o theme.o ### Implicit rules: @@ -84,7 +86,7 @@ $(DEPFILE): Makefile all: libvdr-$(PLUGIN).so libvdr-$(PLUGIN).so: $(OBJS) - $(CXX) $(CXXFLAGS) -shared $(OBJS) -lImlib2 -o $@ + $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LIBS) -o $@ @cp $@ $(LIBDIR)/$@.$(VDRVERSION) dist: clean @@ -1,20 +1,27 @@ /* - * $Id: bitmap.c,v 1.6 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: bitmap.c,v 1.9 2004/06/02 20:43:05 lordjaxom Exp $ */ -#define __STL_CONFIG_H -#include <vdr/tools.h> -#undef __STL_CONFIG_H #include "bitmap.h" +#include <vdr/tools.h> #define X_DISPLAY_MISSING +#ifdef HAVE_IMLIB2 #include <Imlib2.h> +#endif +#ifdef HAVE_IMAGEMAGICK +#include <Magick++.h> +#endif cText2SkinBitmap::cText2SkinBitmap(void): cBitmap(1, 1, 1) { +#ifdef HAVE_IMLIB2 imlib_set_cache_size(4096 * 1024); +#endif } cText2SkinBitmap::cText2SkinBitmap(const char *Filename): cBitmap(1, 1, 1) { +#ifdef HAVE_IMLIB2 imlib_set_cache_size(4096 * 1024); +#endif Load(Filename); } @@ -29,6 +36,11 @@ bool cText2SkinBitmap::Load(const char *Filename) { #ifdef HAVE_IMLIB2 else if (strcmp(Filename + len - 4, ".png") == 0) return LoadImlib(Filename); +#else +# ifdef HAVE_IMAGEMAGICK + else if (strcmp(Filename + len - 4, ".png") == 0) + return LoadMagick(Filename); +# endif #endif else esyslog("ERROR: text2skin: unknown file format for %s", Filename); @@ -70,7 +82,27 @@ bool cText2SkinBitmap::LoadImlib(const char *Filename) { #ifdef HAVE_IMAGEMAGICK bool cText2SkinBitmap::LoadMagick(const char *Filename) { - Image image; - image.read(Filename); + Magick::Image image; + try { + int w, h; + image.read(Filename); + w = image.columns(); + h = image.rows(); + SetSize(w, h); + SetBpp(8); + + const Magick::PixelPacket *ptr = image.getConstPixels(0, 0, w, h); + for (int iy = 0; iy < h; ++iy) { + for (int ix = 0; ix < w; ++ix) { + tColor col = (((~ptr->opacity & 0xFF00) << 16) | ((ptr->red & 0xFF00) << 8) | (ptr->green & 0xFF00) | ((ptr->blue & 0xFF00) >> 8)); + DrawPixel(ix, iy, col); + ++ptr; + } + } + } catch (Magick::Exception &e) { + esyslog("ERROR: text2skin: Couldn't load %s: %s", Filename, e.what()); + return false; + } + return true; } #endif @@ -1,13 +1,12 @@ /* - * $Id: bitmap.h,v 1.5 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: bitmap.h,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_BITMAP_H #define VDR_TEXT2SKIN_BITMAP_H -#define __STL_CONFIG_H +#include "common.h" #include <vdr/osd.h> -#undef __STL_CONFIG_H class cText2SkinBitmap: public cBitmap { public: @@ -1,12 +1,10 @@ /* - * $Id: common.c,v 1.5 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: common.c,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $ */ -#define __STL_CONFIG_H -#include <vdr/plugin.h> -#undef __STL_CONFIG_H #include "data.h" #include "common.h" +#include <vdr/plugin.h> const char *SkinPath(void) { return cPlugin::ConfigDirectory(PLUGIN_NAME_I18N); @@ -113,3 +111,63 @@ string ItemText(cText2SkinItem *Item, const string &Content) { return s; } +bool ParseVar(const char *Text, const char *Name, int *Value) { + string value; + if (ParseVar(Text, Name, value)) { + *Value = atoi(value.c_str()); + return true; + } + return false; +} + +bool ParseVar(const char *Text, const char *Name, string &Value){ + char *ptr1, *ptr2; + char *str; + bool res = false; + asprintf(&str, "%s=", Name); + if ((ptr1 = strstr(Text, str))) { + ptr1 += strlen(str); + if ((ptr2 = strchr(ptr1, ',')) || (ptr2 = strchr(ptr1, ';'))) { + Value = ptr1; + Value.erase(ptr2 - ptr1); + res = true; + } + } + free(str); + return res; +} + +bool ParseVar(const char *Text, const char *Name, tColor **Value) { + string value; + if (ParseVar(Text, Name, value) && value[0] == '#') { + *Value = new tColor(strtoul(value.c_str() + 1, NULL, 16)); + return true; + } + return false; +} + +bool ParseVar(const char *Text, const char *Name, eTextAlignment *Value) { + string value; + if (ParseVar(Text, Name, value)) { + int v = atoi(value.c_str()); + if (v == 0) + *Value = (eTextAlignment)(taTop|taLeft); + else if (v == 1) + *Value = (eTextAlignment)(taTop|taCenter); + else if (v == 2) + *Value = (eTextAlignment)(taTop|taRight); + return true; + } + return false; +} + +bool ParseVar(const char *Text, const char *Name, const cFont **Value) { + string value; + if (ParseVar(Text, Name, value)) { + if (value == "Sml") *Value = cFont::GetFont(fontSml); + else if (value == "Fix") *Value = cFont::GetFont(fontFix); + return true; + } + return false; +} + @@ -1,21 +1,34 @@ /* - * $Id: common.h,v 1.5 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: common.h,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_COMMON_H #define VDR_TEXT2SKIN_COMMON_H #include <string> +#include <vector> +#include <map> +#include <vdr/osd.h> -class cText2SkinItem; +using std::string; +using std::vector; +using std::map; #define precond(x) if ((x)) { esyslog("ERROR: text2skin: "#x " not given"); return; } +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); -string ItemText(cText2SkinItem *Item, const string &Content); + +bool ParseVar(const char *Text, const char *Name, int *Value); +bool ParseVar(const char *Text, const char *Name, const cFont **Value); +bool ParseVar(const char *Text, const char *Name, string &Value); +bool ParseVar(const char *Text, const char *Name, tColor **Value); +bool ParseVar(const char *Text, const char *Name, eTextAlignment *Value); #endif // VDR_TEXT2SKIN_COMMON_H @@ -1,13 +1,15 @@ /* - * $Id: data.c,v 1.11 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: data.c,v 1.12 2004/06/02 20:43:05 lordjaxom Exp $ */ #include "data.h" +#include "common.h" -eSkinSection cText2SkinItem::mParseSection = sectionUnknown; +static string SectionNames[__SECTION_COUNT__] = + { "Skin", "ChannelSmall", "Channel", "Volume", + "ReplayMode", "Replay", "Message", "Menu" }; cText2SkinItem::cText2SkinItem(void) { - mSection = sectionUnknown; mItem = itemUnknown; mPos.x = -1; mPos.y = -1; @@ -15,22 +17,22 @@ cText2SkinItem::cText2SkinItem(void) { mSize.h = 0; mBpp = 4; mArc = 0; - mFg = NULL; - mBg = NULL; + //mFg = NULL; + //mBg = NULL; mFont = cFont::GetFont(fontOsd); mAlign = taDefault; } cText2SkinItem::~cText2SkinItem() { - delete mBg; - delete mFg; + //delete mBg; + //delete mFg; } bool cText2SkinItem::Parse(const char *Text) { char *text = strdup(Text); char *ptr = text; - ptr = text + strlen(text) - 1; + /*ptr = text + strlen(text) - 1; for (; ptr >= text && *ptr == ' '; --ptr) *ptr = '\0'; ptr = skipspace(text); @@ -47,12 +49,11 @@ bool cText2SkinItem::Parse(const char *Text) { 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)) { - mSection = mParseSection; if (item == "Skin") { // the Skin item if (ParseVar(ptr, "name", mName) && ParseVar(ptr, "version", mVersion)) mItem = itemSkin; @@ -133,8 +134,8 @@ bool cText2SkinItem::ParseItem(const char *Text) { ParseVar(Text, "height", &mSize.h); ParseVar(Text, "bpp", &mBpp); ParseVar(Text, "arc", &mArc); - ParseVar(Text, "fg", &mFg); - ParseVar(Text, "bg", &mBg); + ParseVar(Text, "fg", mFg); + ParseVar(Text, "bg", mBg); ParseVar(Text, "font", &mFont); ParseVar(Text, "path", mPath); ParseVar(Text, "altpath", mAltPath); @@ -144,78 +145,52 @@ bool cText2SkinItem::ParseItem(const char *Text) { return true; } -bool cText2SkinItem::ParseVar(const char *Text, const char *Name, int *Value) { - string value; - if (ParseVar(Text, Name, value)) { - *Value = atoi(value.c_str()); - return true; - } - return false; -} - -bool cText2SkinItem::ParseVar(const char *Text, const char *Name, string &Value){ - char *ptr1, *ptr2; - char *str; - bool res = false; - asprintf(&str, "%s=", Name); - if ((ptr1 = strstr(Text, str))) { - ptr1 += strlen(str); - if ((ptr2 = strchr(ptr1, ',')) || (ptr2 = strchr(ptr1, ';'))) { - Value = ptr1; - Value.erase(ptr2 - ptr1); - res = true; - } - } - free(str); - return res; -} - -bool cText2SkinItem::ParseVar(const char *Text, const char *Name, tColor **Value) { - string value; - if (ParseVar(Text, Name, value) && value[0] == '#') { - *Value = new tColor(strtoul(value.c_str() + 1, NULL, 16)); - return true; - } - return false; +// --- cText2SkinData --------------------------------------------------------- + +cText2SkinData::cText2SkinData(const char *Skin): cText2SkinFile(Skin) { + mCurrentSection = sectionSkin; } -bool cText2SkinItem::ParseVar(const char *Text, const char *Name, eTextAlignment *Value) { - string value; - if (ParseVar(Text, Name, value)) { - int v = atoi(value.c_str()); - if (v == 0) - *Value = (eTextAlignment)(taTop|taLeft); - else if (v == 1) - *Value = (eTextAlignment)(taTop|taCenter); - else if (v == 2) - *Value = (eTextAlignment)(taTop|taRight); - return true; - } - return false; +cText2SkinData::~cText2SkinData() { } -bool cText2SkinItem::ParseVar(const char *Text, const char *Name, const cFont **Value) { - string value; - if (ParseVar(Text, Name, value)) { - if (value == "Sml") *Value = cFont::GetFont(fontSml); - else if (value == "Fix") *Value = cFont::GetFont(fontFix); - return true; +bool cText2SkinData::Parse(const char *Text) { + int l = strlen(Text); + bool result = false; + if (l) { + if (Text[0] == '#') // comment + result = true; + else if (Text[0] == '[' && Text[l - 1] == ']') { // section + char *s; + int i; + asprintf(&s, "%.*s", l - 2, Text + 1); + for (i = 0; i < __SECTION_COUNT__; ++i) { + if (SectionNames[i] == s) { + mCurrentSection = (eSkinSection)i; + result = true; + break; + } + } + if (i == __SECTION_COUNT__) + esyslog("ERROR: text2skin: Unknown section %s", s); + free(s); + } else { + cText2SkinItem *item = new cText2SkinItem; + if (item->Parse(Text)) { + mSections[mCurrentSection].push_back(item); + result = true; + } else + delete item; + } } - return false; -} - -cText2SkinData::cText2SkinData(const char *Skin) { - mSkin = strdup(Skin); -} - -cText2SkinData::~cText2SkinData() { - free(mSkin); + return result; } -cText2SkinItem *cText2SkinData::Get(eSkinItem Item) { - for (cText2SkinItem *it = First(); it; it = Next(it)) { - if (it->Item() == Item) - return it; +cText2SkinItem *cText2SkinData::Get(eSkinSection Section, eSkinItem Item) { + vector<cText2SkinItem*>::iterator it = mSections[Section].begin(); + for (; it != mSections[Section].end(); ++it) { + if ((*it)->Item() == Item) + return (*it); } return NULL; } @@ -1,23 +1,20 @@ /* - * $Id: data.h,v 1.9 2004/05/31 19:54:12 lordjaxom Exp $ + * $Id: data.h,v 1.10 2004/06/02 20:43:05 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_DATA_H #define VDR_TEXT2SKIN_DATA_H -#define __STL_CONFIG_H +#include "common.h" +#include "file.h" #include <vdr/tools.h> #include <vdr/osd.h> #include <vdr/config.h> -#undef __STL_CONFIG_H -#include <string> - -using std::string; // sections and items known by skin files enum eSkinSection { - sectionUnknown, + sectionSkin, sectionChannelSmall, sectionChannel, sectionVolume, @@ -25,6 +22,7 @@ enum eSkinSection { sectionReplay, sectionMessage, sectionMenu, + __SECTION_COUNT__ }; enum eSkinItem { @@ -92,20 +90,17 @@ struct SIZE { int w, h; }; -class cText2SkinItem: public cListObject { +class cText2SkinItem { friend class cText2SkinRender; private: - static eSkinSection mParseSection; - - eSkinSection mSection; eSkinItem mItem; POINT mPos; SIZE mSize; int mBpp; int mArc; - tColor *mFg; - tColor *mBg; + string mFg; + string mBg; const cFont *mFont; string mName; string mVersion; @@ -117,11 +112,6 @@ private: protected: bool ParseItem(const char *Text); - bool ParseVar(const char *Text, const char *Name, int *Value); - bool ParseVar(const char *Text, const char *Name, const cFont **Value); - bool ParseVar(const char *Text, const char *Name, string &Value); - bool ParseVar(const char *Text, const char *Name, tColor **Value); - bool ParseVar(const char *Text, const char *Name, eTextAlignment *Value); public: cText2SkinItem(void); @@ -129,14 +119,15 @@ public: bool Parse(const char *Text); - eSkinSection Section(void) const { return mSection; } eSkinItem Item(void) const { return mItem; } const POINT &Pos(void) const { return mPos; } 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 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; } const string &Name(void) const { return mName; } const string &Version(void) const { return mVersion; } @@ -147,17 +138,26 @@ public: eTextAlignment Align(void) const { return mAlign; } }; -class cText2SkinData: public cConfig<cText2SkinItem> { +class cText2SkinData: public cText2SkinFile { +public: + typedef vector<cText2SkinItem*> tSection; + typedef tSection::iterator tIterator; + private: - char *mSkin; + eSkinSection mCurrentSection; + tSection mSections[__SECTION_COUNT__]; + +protected: + virtual bool Parse(const char *Text); public: cText2SkinData(const char *Skin); - ~cText2SkinData(); + virtual ~cText2SkinData(); - cText2SkinItem *Get(eSkinItem Item); + tIterator First(eSkinSection Section) { return mSections[Section].begin(); } + tIterator Last(eSkinSection Section) { return mSections[Section].end(); } - const char *Skin(void) const { return mSkin; } + cText2SkinItem *Get(eSkinSection Section, eSkinItem Item); }; #endif // VDR_TEXT2SKIN_DATA_H @@ -1,17 +1,17 @@ /* - * $Id: display.c,v 1.8 2004/06/01 17:25:38 lordjaxom Exp $ + * $Id: display.c,v 1.9 2004/06/02 20:43:05 lordjaxom Exp $ */ #include "render.h" #include "data.h" +#include "i18n.h" #include "display.h" // --- cText2SkinDisplayChannel ----------------------------------------------- -cText2SkinDisplayChannel::cText2SkinDisplayChannel(cText2SkinData *Data, bool WithInfo) { - mData = Data; +cText2SkinDisplayChannel::cText2SkinDisplayChannel(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool WithInfo) { mWithInfo = WithInfo; - mRender = new cText2SkinRender(mData, WithInfo ? sectionChannel : sectionChannelSmall); + mRender = new cText2SkinRender(Data, I18n, Theme, WithInfo ? sectionChannel : sectionChannelSmall); mDirty = false; } @@ -53,9 +53,8 @@ void cText2SkinDisplayChannel::Flush(void) { // --- cText2SkinDisplayVolume ------------------------------------------------ -cText2SkinDisplayVolume::cText2SkinDisplayVolume(cText2SkinData *Data) { - mData = Data; - mRender = new cText2SkinRender(mData, sectionVolume); +cText2SkinDisplayVolume::cText2SkinDisplayVolume(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme) { + mRender = new cText2SkinRender(Data, I18n, Theme, sectionVolume); mDirty = false; } @@ -81,9 +80,8 @@ void cText2SkinDisplayVolume::Flush(void) { // --- cText2SkinDisplayReplay ------------------------------------------------ -cText2SkinDisplayReplay::cText2SkinDisplayReplay(cText2SkinData *Data, bool ModeOnly) { - mData = Data; - mRender = new cText2SkinRender(mData, ModeOnly ? sectionReplayMode : sectionReplay); +cText2SkinDisplayReplay::cText2SkinDisplayReplay(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool ModeOnly) { + mRender = new cText2SkinRender(Data, I18n, Theme, ModeOnly ? sectionReplayMode : sectionReplay); mDirty = false; } @@ -165,9 +163,8 @@ void cText2SkinDisplayReplay::Flush(void) { // --- cText2SkinDisplayMessage ----------------------------------------------- -cText2SkinDisplayMessage::cText2SkinDisplayMessage(cText2SkinData *Data) { - mData = Data; - mRender = new cText2SkinRender(mData, sectionMessage); +cText2SkinDisplayMessage::cText2SkinDisplayMessage(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme) { + mRender = new cText2SkinRender(Data, I18n, Theme, sectionMessage); mDirty = false; } @@ -193,14 +190,13 @@ void cText2SkinDisplayMessage::Flush(void) { // --- cText2SkinDisplayMenu -------------------------------------------------- -cText2SkinDisplayMenu::cText2SkinDisplayMenu(cText2SkinData *Data) { - mData = Data; - mRender = new cText2SkinRender(mData, sectionMenu); +cText2SkinDisplayMenu::cText2SkinDisplayMenu(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme) { + mRender = new cText2SkinRender(Data, I18n, Theme, sectionMenu); mDirty = false; mMaxItems = 0; - cText2SkinItem *area = mData->Get(itemMenuArea); - cText2SkinItem *item = mData->Get(itemMenuItem); + cText2SkinItem *area = Data->Get(sectionMenu, itemMenuArea); + cText2SkinItem *item = Data->Get(sectionMenu, itemMenuItem); if (area && item) mMaxItems = area->Size().h / item->Size().h; else @@ -1,26 +1,25 @@ /* - * $Id: display.h,v 1.2 2004/05/31 19:54:12 lordjaxom Exp $ + * $Id: display.h,v 1.3 2004/06/02 20:43:05 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_SKIN_H #define VDR_TEXT2SKIN_SKIN_H -#define __STL_CONFIG_H +#include "common.h" #include <vdr/skins.h> -#undef __STL_CONFIG_H class cText2SkinData; +class cText2SkinI18n; class cText2SkinRender; class cText2SkinDisplayChannel: public cSkinDisplayChannel { private: - cText2SkinData *mData; bool mWithInfo; cText2SkinRender *mRender; bool mDirty; public: - cText2SkinDisplayChannel(cText2SkinData *Data, bool WithInfo); + cText2SkinDisplayChannel(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool WithInfo); virtual ~cText2SkinDisplayChannel(); virtual void SetChannel(const cChannel *Channel, int Number); @@ -31,12 +30,11 @@ public: class cText2SkinDisplayVolume: public cSkinDisplayVolume { private: - cText2SkinData *mData; cText2SkinRender *mRender; bool mDirty; public: - cText2SkinDisplayVolume(cText2SkinData *Data); + cText2SkinDisplayVolume(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme); virtual ~cText2SkinDisplayVolume(); virtual void SetVolume(int Current, int Total, bool Mute); virtual void Flush(void); @@ -44,11 +42,10 @@ public: class cText2SkinDisplayReplay: public cSkinDisplayReplay { private: - cText2SkinData *mData; cText2SkinRender *mRender; bool mDirty; public: - cText2SkinDisplayReplay(cText2SkinData *Data, bool ModeOnly); + cText2SkinDisplayReplay(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool ModeOnly); virtual ~cText2SkinDisplayReplay(); virtual void SetTitle(const char *Title); virtual void SetMode(bool Play, bool Forward, int Speed); @@ -63,12 +60,11 @@ public: class cText2SkinDisplayMessage: public cSkinDisplayMessage { private: - cText2SkinData *mData; cText2SkinRender *mRender; bool mDirty; public: - cText2SkinDisplayMessage(cText2SkinData *Data); + cText2SkinDisplayMessage(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme); virtual ~cText2SkinDisplayMessage(); virtual void SetMessage(eMessageType Type, const char *Text); virtual void Flush(void); @@ -76,13 +72,12 @@ public: class cText2SkinDisplayMenu: public cSkinDisplayMenu { private: - cText2SkinData *mData; cText2SkinRender *mRender; bool mDirty; int mMaxItems; public: - cText2SkinDisplayMenu(cText2SkinData *Data); + cText2SkinDisplayMenu(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme); virtual ~cText2SkinDisplayMenu(); virtual int MaxItems(void) { return mMaxItems; } @@ -0,0 +1,44 @@ +/* + * $Id: file.c,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $ + */ + +#include "file.h" +#include <unistd.h> + +cText2SkinFile::cText2SkinFile(const char *Skin) { + mSkin = Skin; +} + +cText2SkinFile::~cText2SkinFile() { +} + +bool cText2SkinFile::Load(const string &Filename) { + bool result = true; + if (access(Filename.c_str(), F_OK) == 0) { + isyslog("text2skin: loading %s", Filename.c_str()); + FILE *f = fopen(Filename.c_str(), "r"); + if (f) { + int line = 0; + char buffer[MAXPARSEBUFFER]; + result = true; + while (fgets(buffer, sizeof(buffer), f) > 0) { + line++; + char *ptr = skipspace(stripspace(buffer)); + if (!isempty(ptr) && ptr[0] != '#') { + if (!Parse(ptr)) { + esyslog("ERROR: error in %s, line %d\n", Filename.c_str(), line); + result = false; + break; + } + } + } + fclose(f); + } else { + LOG_ERROR_STR(Filename.c_str()); + result = false; + } + } + return result; +} + + @@ -0,0 +1,28 @@ +/* + * $Id: file.h,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $ + */ + +#ifndef VDR_TEXT2SKIN_FILE_H +#define VDR_TEXT2SKIN_FILE_H + +#include "common.h" +#include <vdr/tools.h> + +class cText2SkinFile { +private: + string mSkin; + +protected: + virtual bool Parse(const char *Text) = 0; + +public: + cText2SkinFile(const char *Skin); + virtual ~cText2SkinFile(); + + virtual bool Load(const string &Filename); + + const string &Skin(void) const { return mSkin; } +}; + +#endif // VDR_TEXT2SKIN_FILE_H + @@ -1,17 +1,15 @@ /* - * $Id: font.h,v 1.3 2004/05/29 00:27:22 lordjaxom Exp $ + * $Id: font.h,v 1.4 2004/06/02 20:43:05 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_FREETYPE_H #define VDR_TEXT2SKIN_FREETYPE_H +#include "common.h" +#include "data.h" #include <ft2build.h> #include FT_FREETYPE_H -#include <string> -using std::string; - -#include "data.h" // kannst noch einbauen, dass er die fonts "fontOsd" "fontSml" und "fontFix" aus VDR statt aus freetype nimmt @@ -0,0 +1,58 @@ +/* + * $Id: i18n.c,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $ + */ + +#include "i18n.h" + +cText2SkinI18n::cText2SkinI18n(const char *Skin): cText2SkinFile(Skin) { + mIdentity = (string)"text2skin_" + Skin; + mNumPhrases = 0; + mPhrases = (tI18nPhrase*)malloc(sizeof(tI18nPhrase)); + memset(mPhrases[mNumPhrases], 0, sizeof(tI18nPhrase)); +} + +cText2SkinI18n::~cText2SkinI18n() { +} + +bool cText2SkinI18n::Parse(const char *Text) { + int l = strlen(Text); + bool result = false; + if (l) { + if (strncmp(Text, "Item=Translation,", 17) == 0) { + int i; + tI18nPhrase p; + memset(&p, 0, sizeof(tI18nPhrase)); + Text += 17; + + for (i = 0; i < I18nNumLanguages; ++i) { + string text; + if (ParseVar(Text, I18nLanguageCode(i), text)) + p[i] = strdup(text.c_str()); + else + p[i] = ""; + } + + int idx = mNumPhrases++; + for (i = 0; i < I18nNumLanguages; ++i) + if (!p[i]) p[i] = ""; + mPhrases = (tI18nPhrase*)realloc(mPhrases, (mNumPhrases + 1) * sizeof(tI18nPhrase)); + memcpy(mPhrases[idx], p, sizeof(tI18nPhrase)); + memset(mPhrases[mNumPhrases], 0, sizeof(tI18nPhrase)); + result = true; + } else + esyslog("ERROR: text2skin: syntax error"); + } + return result; +} + +bool cText2SkinI18n::Load(const string &Filename) { + if (cText2SkinFile::Load(Filename)) { + I18nRegister(mPhrases, mIdentity.c_str()); + return true; + } + return false; +} + +string cText2SkinI18n::Translate(const string &Text) { + return I18nTranslate(Text.c_str(), mIdentity.c_str()); +} @@ -0,0 +1,30 @@ +/* + * $Id: i18n.h,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $ + */ + +#ifndef VDR_TEXT2SKIN_I18N_H +#define VDR_TEXT2SKIN_I18N_H + +#include "common.h" +#include "file.h" +#include <vdr/i18n.h> + +class cText2SkinI18n: public cText2SkinFile { +private: + string mIdentity; + tI18nPhrase *mPhrases; + int mNumPhrases; + +protected: + virtual bool Parse(const char *Text); + +public: + cText2SkinI18n(const char *Skin); + virtual ~cText2SkinI18n(); + + virtual bool Load(const string &Filename); + string Translate(const string &Text); +}; + +#endif // VDR_TEXT2SKIN_I18N_H + @@ -1,19 +1,16 @@ /* - * $Id: loader.c,v 1.5 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: loader.c,v 1.6 2004/06/02 20:43:05 lordjaxom Exp $ */ -#define __STL_CONFIG_H -#include <vdr/plugin.h> -#undef __STL_CONFIG_H #include "loader.h" #include "data.h" +#include "i18n.h" +#include "theme.h" #include "display.h" -#include "common.h" +#include <vdr/plugin.h> #include <sys/types.h> #include <dirent.h> -static cTheme Theme; - void cText2SkinLoader::Start(void) { DIR *d = opendir(SkinPath()); if (d) { @@ -33,14 +30,26 @@ void cText2SkinLoader::Start(void) { } void cText2SkinLoader::Load(const char *Skin) { - struct stat buf; - string file = (string)SkinPath() + "/" + Skin + "/" + Skin + ".skin"; - if (stat(file.c_str(), &buf) == 0) { + cText2SkinI18n *translations = NULL; + string transfile = (string)SkinPath() + "/" + Skin + "/" + Skin + ".trans"; + if (access(transfile.c_str(), F_OK) == 0) { + translations = new cText2SkinI18n(Skin); + if (!translations->Load(transfile)) { + DELETENULL(translations); + } + } + + cText2SkinTheme *theme = new cText2SkinTheme(Skin); + string themefile = (string)SkinPath() + "/" + Skin + "/" + Skin + ".colors"; + theme->Load(themefile); + + string skinfile = (string)SkinPath() + "/" + Skin + "/" + Skin + ".skin"; + if (access(skinfile.c_str(), F_OK) == 0) { cText2SkinData *data = new cText2SkinData(Skin); - if (data->Load(file.c_str())) { - cText2SkinItem *skin = data->Get(itemSkin); + if (data->Load(skinfile)) { + cText2SkinItem *skin = data->Get(sectionSkin, itemSkin); if (skin) { - new cText2SkinLoader(data, Skin, skin->Name()); + new cText2SkinLoader(data, translations, theme, Skin, skin->Name()); return; } else esyslog("ERROR: Item=Skin is missing in Skin\n"); @@ -50,32 +59,37 @@ void cText2SkinLoader::Load(const char *Skin) { esyslog("ERROR: text2skin: %s/%s is not a valid skin directory\n", SkinPath(), Skin); } -cText2SkinLoader::cText2SkinLoader(cText2SkinData *Data, const string &Skin, const string &Description): cSkin(Skin.c_str(), &::Theme) { +cText2SkinLoader::cText2SkinLoader(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, const string &Skin, const string &Description): cSkin(Skin.c_str(), Theme->Theme()) { mData = Data; + mI18n = I18n; + mTheme = Theme; mDescription = Description; } cText2SkinLoader::~cText2SkinLoader() { delete mData; + delete mI18n; + delete mTheme; // mDescription is part of mData } cSkinDisplayChannel *cText2SkinLoader::DisplayChannel(bool WithInfo) { printf("WithInfo: %d\n", WithInfo); - return new cText2SkinDisplayChannel(mData, WithInfo); + return new cText2SkinDisplayChannel(mData, mI18n, mTheme, WithInfo); } cSkinDisplayMenu *cText2SkinLoader::DisplayMenu(void) { - return new cText2SkinDisplayMenu(mData); + return new cText2SkinDisplayMenu(mData, mI18n, mTheme); } cSkinDisplayVolume *cText2SkinLoader::DisplayVolume(void) { - return new cText2SkinDisplayVolume(mData); + return new cText2SkinDisplayVolume(mData, mI18n, mTheme); } cSkinDisplayReplay *cText2SkinLoader::DisplayReplay(bool ModeOnly) { - return new cText2SkinDisplayReplay(mData, ModeOnly); + return new cText2SkinDisplayReplay(mData, mI18n, mTheme, ModeOnly); } + cSkinDisplayMessage *cText2SkinLoader::DisplayMessage(void) { - return new cText2SkinDisplayMessage(mData); + return new cText2SkinDisplayMessage(mData, mI18n, mTheme); } @@ -1,29 +1,29 @@ /* - * $Id: loader.h,v 1.3 2004/05/31 19:54:12 lordjaxom Exp $ + * $Id: loader.h,v 1.4 2004/06/02 20:43:05 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_LOADER_H #define VDR_TEXT2SKIN_LOADER_H -#define __STL_CONFIG_H +#include "common.h" #include <vdr/skins.h> -#undef __STL_CONFIG_H -#include <string> - -using std::string; class cText2SkinData; +class cText2SkinI18n; +class cText2SkinTheme; class cText2SkinLoader: public cSkin { private: - cText2SkinData *mData; - string mDescription; + cText2SkinData *mData; + cText2SkinI18n *mI18n; + cText2SkinTheme *mTheme; + string mDescription; public: static void Start(void); static void Load(const char *Skin); - cText2SkinLoader(cText2SkinData *Data, const string &Skin, const string &Description); + cText2SkinLoader(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, const string &Skin, const string &Description); ~cText2SkinLoader(); virtual const char *Description(void) { return mDescription.c_str(); } @@ -1,22 +1,21 @@ /* - * $Id: render.c,v 1.15 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: render.c,v 1.16 2004/06/02 20:43:05 lordjaxom Exp $ */ #include "render.h" -#define __STL_CONFIG_H +#include "data.h" +#include "bitmap.h" #include <vdr/channels.h> #include <vdr/epg.h> #include <vdr/menu.h> -#undef __STL_CONFIG_H -#include "data.h" -#include "bitmap.h" -#include "common.h" -cText2SkinRender::cText2SkinRender(cText2SkinData *Data, eSkinSection Section) { +cText2SkinRender::cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, eSkinSection Section) { tArea areas[MAXOSDAREAS]; int numAreas = 0; mData = Data; + mI18n = I18n; + mTheme = Theme; mSection = Section; mOsd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop); mChannel = NULL; @@ -38,9 +37,10 @@ cText2SkinRender::cText2SkinRender(cText2SkinData *Data, eSkinSection Section) { mMenuRecording = NULL; mMenuTextFixedFont = false; - cText2SkinItem *item; - for (item = Data->First(); item; item = Data->Next(item)) { - if (item->Section() == Section && item->Item() == itemBackground) { + cText2SkinData::tIterator it = Data->First(mSection); + for (; it != Data->Last(mSection); ++it) { + cText2SkinItem *item = (*it); + if (item->Item() == itemBackground) { if (numAreas < MAXOSDAREAS) { areas[numAreas].x1 = item->Pos().x; areas[numAreas].y1 = item->Pos().y; @@ -85,96 +85,95 @@ cText2SkinRender::~cText2SkinRender() { } void cText2SkinRender::Flush(void) { - cText2SkinItem *item; - for (item = mData->First(); item; item = mData->Next(item)) { - if (item->Section() == mSection) { - switch (item->Item()) { - case itemBackground: - DisplayBackground(item); break; - case itemChannelLogo: - DisplayChannelLogo(item); break; - case itemLanguage: - DisplayLanguage(item); break; - case itemText: - DisplayText(item); break; - case itemImage: - DisplayImage(item); break; - case itemDateTime: - DisplayDateTime(item); break; - case itemDate: - DisplayDate(item); break; - case itemTime: - DisplayTime(item); break; - case itemChannelNumberName: - DisplayChannelNumberName(item); break; - case itemChannelNumber: - DisplayChannelNumber(item); break; - case itemChannelName: - DisplayChannelName(item); break; - case itemRectangle: - DisplayRectangle(item); break; - case itemEllipse: - DisplayEllipse(item); break; - case itemSlope: - DisplaySlope(item); break; - case itemTimebar: - DisplayTimebar(item); break; - case itemPresentTime: - DisplayPresentTime(item); break; - case itemPresentTitle: - DisplayPresentTitle(item); break; - case itemPresentShortText: - DisplayPresentShortText(item); break; - case itemFollowingTime: - DisplayFollowingTime(item); break; - case itemFollowingTitle: - DisplayFollowingTitle(item); break; - case itemFollowingShortText: - DisplayFollowingShortText(item); break; - case itemSymbolTeletext: - case itemSymbolAudio: - case itemSymbolDolby: - case itemSymbolEncrypted: - case itemSymbolRecording: - case itemSymbolRadio: - case itemSymbolPlay: - case itemSymbolPause: - case itemSymbolFastFwd: - case itemSymbolFastRew: - case itemSymbolSlowFwd: - case itemSymbolSlowRew: - DisplaySymbol(item); break; - case itemVolumebar: - DisplayVolumebar(item); break; - case itemMute: - DisplayMute(item); break; - case itemReplaybar: - DisplayReplaybar(item); break; - case itemReplayTitle: - DisplayReplayTitle(item); break; - case itemReplayCurrent: - DisplayReplayCurrent(item); break; - case itemReplayTotal: - DisplayReplayTotal(item); break; - case itemReplayJump: - DisplayReplayJump(item); break; - case itemMessageInfo: - case itemMessageStatus: - case itemMessageWarning: - case itemMessageError: - DisplayMessage(item); break; - case itemMenuItem: - DisplayMenuItems(item); break; - case itemMenuTitle: - DisplayMenuTitle(item); break; - case itemMenuRed: - case itemMenuGreen: - case itemMenuYellow: - case itemMenuBlue: - DisplayMenuColorbutton(item); break; - default: - break; - } + cText2SkinData::tIterator it = mData->First(mSection); + for (; it != mData->Last(mSection); ++it) { + cText2SkinItem *item = (*it); + switch (item->Item()) { + case itemBackground: + DisplayBackground(item); break; + case itemChannelLogo: + DisplayChannelLogo(item); break; + case itemLanguage: + DisplayLanguage(item); break; + case itemText: + DisplayText(item); break; + case itemImage: + DisplayImage(item); break; + case itemDateTime: + DisplayDateTime(item); break; + case itemDate: + DisplayDate(item); break; + case itemTime: + DisplayTime(item); break; + case itemChannelNumberName: + DisplayChannelNumberName(item); break; + case itemChannelNumber: + DisplayChannelNumber(item); break; + case itemChannelName: + DisplayChannelName(item); break; + case itemRectangle: + DisplayRectangle(item); break; + case itemEllipse: + DisplayEllipse(item); break; + case itemSlope: + DisplaySlope(item); break; + case itemTimebar: + DisplayTimebar(item); break; + case itemPresentTime: + DisplayPresentTime(item); break; + case itemPresentTitle: + DisplayPresentTitle(item); break; + case itemPresentShortText: + DisplayPresentShortText(item); break; + case itemFollowingTime: + DisplayFollowingTime(item); break; + case itemFollowingTitle: + DisplayFollowingTitle(item); break; + case itemFollowingShortText: + DisplayFollowingShortText(item); break; + case itemSymbolTeletext: + case itemSymbolAudio: + case itemSymbolDolby: + case itemSymbolEncrypted: + case itemSymbolRecording: + case itemSymbolRadio: + case itemSymbolPlay: + case itemSymbolPause: + case itemSymbolFastFwd: + case itemSymbolFastRew: + case itemSymbolSlowFwd: + case itemSymbolSlowRew: + DisplaySymbol(item); break; + case itemVolumebar: + DisplayVolumebar(item); break; + case itemMute: + DisplayMute(item); break; + case itemReplaybar: + DisplayReplaybar(item); break; + case itemReplayTitle: + DisplayReplayTitle(item); break; + case itemReplayCurrent: + DisplayReplayCurrent(item); break; + case itemReplayTotal: + DisplayReplayTotal(item); break; + case itemReplayJump: + DisplayReplayJump(item); break; + case itemMessageInfo: + case itemMessageStatus: + case itemMessageWarning: + case itemMessageError: + DisplayMessage(item); break; + case itemMenuItem: + DisplayMenuItems(item); break; + case itemMenuTitle: + DisplayMenuTitle(item); break; + case itemMenuRed: + case itemMenuGreen: + case itemMenuYellow: + case itemMenuBlue: + DisplayMenuColorbutton(item); break; + default: + break; } } mOsd->Flush(); @@ -185,7 +184,7 @@ void cText2SkinRender::DrawBackground(const POINT &Pos, const SIZE &Size, const cText2SkinBitmap bm; if (Path != "") { char *p; - asprintf(&p, "%s/%s/%s", SkinPath(), mData->Skin(), Path.c_str()); + 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); @@ -203,7 +202,7 @@ void cText2SkinRender::DrawBackground(const POINT &Pos, const SIZE &Size, const void cText2SkinRender::DrawImage(const POINT &Pos, const SIZE &Size, const tColor *Bg, const tColor *Fg, const string &Path) { cText2SkinBitmap bm; char *p; - asprintf(&p, "%s/%s/%s", SkinPath(), mData->Skin(), Path.c_str()); + 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); @@ -302,13 +301,13 @@ void cText2SkinRender::DrawMark(const POINT &Pos, const SIZE &Size, bool Start, } void cText2SkinRender::DisplayBackground(cText2SkinItem *Item) { - DrawBackground(Item->Pos(), Item->Size(), Item->Bg(), Item->Fg(), Item->Path()); + DrawBackground(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), Item->Path()); } void cText2SkinRender::DisplayChannelLogo(cText2SkinItem *Item) { if (Item->Type() != "" && mChannel) { string path = Item->Path() + "/" + ChannelName(mChannel, mChannelNumber) + "." + Item->Type(); - DrawImage(Item->Pos(), Item->Size(), Item->Bg(), Item->Fg(), path); + DrawImage(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), path); } } @@ -325,62 +324,62 @@ void cText2SkinRender::DisplayLanguage(cText2SkinItem *Item) { printf("\n"); if (current < i) { string path = Item->Path() + "/" + tracks[current] + "." + Item->Type(); - DrawImage(Item->Pos(), Item->Size(), Item->Bg(), Item->Fg(), path); + DrawImage(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), path); } } } void cText2SkinRender::DisplayText(cText2SkinItem *Item) { - DrawText(Item->Pos(), Item->Size(), Item->Fg(), Item->Text(), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayImage(cText2SkinItem *Item) { - DrawImage(Item->Pos(), Item->Size(), Item->Bg(), Item->Fg(), Item->Path()); + DrawImage(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), Item->Path()); } void cText2SkinRender::DisplayDateTime(cText2SkinItem *Item) { const char *text = DayDateTime(time(NULL)); - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, text), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayDate(cText2SkinItem *Item) { char *text = strdup(DayDateTime(time(NULL))); text[9] = '.'; text[10] = '\0'; - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, text + 4), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text + 4), Item->Font(), Item->Align()); free(text); } void cText2SkinRender::DisplayTime(cText2SkinItem *Item) { char *text = strdup(DayDateTime(time(NULL))); text[18] = '\0'; - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, text + 13), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text + 13), Item->Font(), Item->Align()); free(text); } void cText2SkinRender::DisplayChannelNumberName(cText2SkinItem *Item) { - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, ChannelString(mChannel, mChannelNumber)), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, ChannelString(mChannel, mChannelNumber)), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayChannelNumber(cText2SkinItem *Item) { - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, ChannelNumber(mChannel, mChannelNumber)), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, ChannelNumber(mChannel, mChannelNumber)), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayChannelName(cText2SkinItem *Item) { - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, ChannelName(mChannel, mChannelNumber)), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, ChannelName(mChannel, mChannelNumber)), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayRectangle(cText2SkinItem *Item) { - DrawRectangle(Item->Pos(), Item->Size(), Item->Fg()); + DrawRectangle(Item->Pos(), Item->Size(), ItemFg(Item)); } void cText2SkinRender::DisplayEllipse(cText2SkinItem *Item) { - DrawEllipse(Item->Pos(), Item->Size(), Item->Fg(), Item->Arc()); + DrawEllipse(Item->Pos(), Item->Size(), ItemFg(Item), Item->Arc()); } void cText2SkinRender::DisplaySlope(cText2SkinItem *Item) { - DrawSlope(Item->Pos(), Item->Size(), Item->Fg(), Item->Arc()); + DrawSlope(Item->Pos(), Item->Size(), ItemFg(Item), Item->Arc()); } void cText2SkinRender::DisplayTimebar(cText2SkinItem *Item) { @@ -388,42 +387,42 @@ void cText2SkinRender::DisplayTimebar(cText2SkinItem *Item) { if (mChannelPresent && mChannelPresent->StartTime() && mChannelPresent->Duration() && now > mChannelPresent->StartTime()) { int total = mChannelPresent->Duration(); int current = now - mChannelPresent->StartTime(); - DrawProgressbar(Item->Pos(), Item->Size(), current, total, Item->Bg(), Item->Fg()); + DrawProgressbar(Item->Pos(), Item->Size(), current, total, ItemBg(Item), ItemFg(Item)); } } void cText2SkinRender::DisplayPresentTime(cText2SkinItem *Item) { if (mChannelPresent) { const char *text = DayDateTime(mChannelPresent->StartTime()); - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, text + 10), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text + 10), Item->Font(), Item->Align()); } } void cText2SkinRender::DisplayPresentTitle(cText2SkinItem *Item) { if (mChannelPresent && mChannelPresent->Title()) - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mChannelPresent->Title()), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mChannelPresent->Title()), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayPresentShortText(cText2SkinItem *Item) { if (mChannelPresent && mChannelPresent->ShortText()) - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mChannelPresent->ShortText()), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mChannelPresent->ShortText()), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayFollowingTime(cText2SkinItem *Item) { if (mChannelFollowing) { const char *text = DayDateTime(mChannelFollowing->StartTime()); - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, text + 10), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text + 10), Item->Font(), Item->Align()); } } void cText2SkinRender::DisplayFollowingTitle(cText2SkinItem *Item) { if (mChannelFollowing && mChannelFollowing->Title()) - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mChannelFollowing->Title()), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mChannelFollowing->Title()), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayFollowingShortText(cText2SkinItem *Item) { if (mChannelFollowing && mChannelFollowing->ShortText()) - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mChannelFollowing->ShortText()), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mChannelFollowing->ShortText()), Item->Font(), Item->Align()); } void cText2SkinRender::DisplaySymbol(cText2SkinItem *Item) { @@ -464,53 +463,53 @@ void cText2SkinRender::DisplaySymbol(cText2SkinItem *Item) { } } if (image != "") - DrawImage(Item->Pos(), Item->Size(), Item->Bg(), Item->Fg(), image); + DrawImage(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), image); } void cText2SkinRender::DisplayVolumebar(cText2SkinItem *Item) { if (mVolumeTotal && mVolumeCurrent <= mVolumeTotal) { int total = mVolumeTotal; int current = mVolumeCurrent; - DrawProgressbar(Item->Pos(), Item->Size(), current, total, Item->Bg(), Item->Fg()); + DrawProgressbar(Item->Pos(), Item->Size(), current, total, ItemBg(Item), ItemFg(Item)); } } void cText2SkinRender::DisplayMute(cText2SkinItem *Item) { if (mVolumeMute) { if (Item->Path() != "") - DrawImage(Item->Pos(), Item->Size(), Item->Bg(), Item->Fg(), Item->Path()); + DrawImage(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), Item->Path()); if (Item->Text() != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), Item->Text(), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), Item->Text(), Item->Font(), Item->Align()); } else if (Item->Path() != "") - DrawImage(Item->Pos(), Item->Size(), Item->Bg(), Item->Fg(), Item->AltPath()); + DrawImage(Item->Pos(), Item->Size(), ItemBg(Item), ItemFg(Item), Item->AltPath()); } void cText2SkinRender::DisplayReplaybar(cText2SkinItem *Item) { if (mReplayTotal && mReplayCurrent <= mReplayTotal) { int total = mReplayTotal; int current = mReplayCurrent; - DrawProgressbar(Item->Pos(), Item->Size(), current, total, Item->Bg(), Item->Fg(), mReplayMarks); + DrawProgressbar(Item->Pos(), Item->Size(), current, total, ItemBg(Item), ItemFg(Item), mReplayMarks); } } void cText2SkinRender::DisplayReplayTitle(cText2SkinItem *Item) { if (mReplayTitle != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mReplayTitle), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mReplayTitle), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayReplayCurrent(cText2SkinItem *Item) { if (mReplayCurrentText != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mReplayCurrentText), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mReplayCurrentText), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayReplayTotal(cText2SkinItem *Item) { if (mReplayTotalText != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mReplayTotalText), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mReplayTotalText), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayReplayJump(cText2SkinItem *Item) { if (mReplayJump != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mReplayJump), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mReplayJump), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayMessage(cText2SkinItem *Item) { @@ -528,12 +527,12 @@ void cText2SkinRender::DisplayMessage(cText2SkinItem *Item) { break; } if (text != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, text), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayMenuItems(cText2SkinItem *Item) { - cText2SkinItem *area = mData->Get(itemMenuArea); - cText2SkinItem *current = mData->Get(itemMenuCurrent); + cText2SkinItem *area = mData->Get(sectionMenu, itemMenuArea); + cText2SkinItem *current = mData->Get(sectionMenu, itemMenuCurrent); int xoffs = area->Pos().x; int yoffs = area->Pos().y; @@ -551,13 +550,13 @@ void cText2SkinRender::DisplayMenuItems(cText2SkinItem *Item) { if (current->Pos().y != -1) pt.y += current->Pos().y; SIZE size = { current->Size().w, current->Size().h }; - if (current->Bg()) - DrawRectangle(pt, size, current->Bg()); - DrawText(pt, size, current->Fg(), mMenuItems[index].name.c_str(), current->Font(), current->Align()); + 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, Item->Fg(), mMenuItems[index].name.c_str(), Item->Font(), Item->Align()); + DrawText(pt, size, ItemFg(Item), mMenuItems[index].name.c_str(), Item->Font(), Item->Align()); } yoffs += Item->Size().h; ++index; @@ -566,7 +565,7 @@ void cText2SkinRender::DisplayMenuItems(cText2SkinItem *Item) { void cText2SkinRender::DisplayMenuTitle(cText2SkinItem *Item) { if (mMenuTitle != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, mMenuTitle), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, mMenuTitle), Item->Font(), Item->Align()); } void cText2SkinRender::DisplayMenuColorbutton(cText2SkinItem *Item) { @@ -583,6 +582,45 @@ void cText2SkinRender::DisplayMenuColorbutton(cText2SkinItem *Item) { default: break; } if (text != "") - DrawText(Item->Pos(), Item->Size(), Item->Fg(), ItemText(Item, text), Item->Font(), Item->Align()); + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text), Item->Font(), Item->Align()); +} + +string cText2SkinRender::ItemText(cText2SkinItem *Item) { + return mI18n ? mI18n->Translate(Item->Text()) : Item->Text(); +} + +string cText2SkinRender::ItemText(cText2SkinItem *Item, const string &Content) { + string s; + if (Item->Text() != "") { + s = mI18n ? mI18n->Translate(Item->Text()) : Item->Text(); + int pos; + while ((pos = s.find('$')) != -1) + s.replace(pos, 1, Content); + } else + s = Content; + return s; +} + +tColor *cText2SkinRender::ItemFg(cText2SkinItem *Item) { + static tColor Fg; + if (Item->Fg() != "") { + if (Item->Fg()[0] == '#') + Fg = strtoul(Item->Fg().c_str() + 1, NULL, 16); + else + Fg = mTheme->Color(Item->Fg()); + } else + return NULL; + return &Fg; +} + +tColor *cText2SkinRender::ItemBg(cText2SkinItem *Item) { + static tColor Bg; + if (Item->Bg() != "") { + if (Item->Bg()[0] == '#') + Bg = strtoul(Item->Bg().c_str() + 1, NULL, 16); + else + Bg = mTheme->Color(Item->Bg()); + } else + return NULL; + return &Bg; } - @@ -1,20 +1,16 @@ /* - * $Id: render.h,v 1.11 2004/06/01 14:32:46 lordjaxom Exp $ + * $Id: render.h,v 1.12 2004/06/02 20:43:05 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_RENDER_H #define VDR_TEXT2SKIN_RENDER_H -#define __STL_CONFIG_H +#include "common.h" +#include "data.h" +#include "i18n.h" +#include "theme.h" #include <vdr/osd.h> #include <vdr/skins.h> -#undef __STL_CONFIG_H -#include "data.h" -#include <vector> -#include <string> - -using std::vector; -using std::string; class cChannel; class cEvent; @@ -28,6 +24,8 @@ class cText2SkinRender { private: cText2SkinData *mData; + cText2SkinI18n *mI18n; + cText2SkinTheme *mTheme; eSkinSection mSection; cOsd *mOsd; @@ -87,6 +85,7 @@ protected: 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); + // High-level operations void DisplayBackground(cText2SkinItem *Item); void DisplayChannelLogo(cText2SkinItem *Item); void DisplayLanguage(cText2SkinItem *Item); @@ -122,8 +121,14 @@ protected: void DisplayMenuColorbutton(cText2SkinItem *Item); void DisplayMenuMessage(cText2SkinItem *Item); + // Helpers + string ItemText(cText2SkinItem *Item); + string ItemText(cText2SkinItem *Item, const string &Content); + tColor *ItemFg(cText2SkinItem *Item); + tColor *ItemBg(cText2SkinItem *Item); + public: - cText2SkinRender(cText2SkinData *Data, eSkinSection Section); + cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, eSkinSection Section); ~cText2SkinRender(); void Flush(void); diff --git a/text2skin.c b/text2skin.c index e2b0b9a..68602d2 100644 --- a/text2skin.c +++ b/text2skin.c @@ -3,15 +3,13 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: text2skin.c,v 1.7 2004/06/01 21:02:38 lordjaxom Exp $ + * $Id: text2skin.c,v 1.9 2004/06/02 19:55:55 lordjaxom Exp $ */ -#define __STL_CONFIG_H -#include <vdr/plugin.h> -#undef __STL_CONFIG_H #include "loader.h" +#include <vdr/plugin.h> -static const char *VERSION = "0.0.1-rc3"; +static const char *VERSION = "0.0.1-rc4"; static const char *DESCRIPTION = "Loader for text-based skins"; class cText2SkinPlugin : public cPlugin { @@ -0,0 +1,31 @@ +/* + * $Id: theme.c,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $ + */ +#include "theme.h" +#include <vdr/osd.h> + +cText2SkinTheme::cText2SkinTheme(const char *Skin): cText2SkinFile(Skin) { +} + +cText2SkinTheme::~cText2SkinTheme() { +} + +bool cText2SkinTheme::Parse(const char *Text) { + int l = strlen(Text); + bool result = false; + if (l) { + if (strncmp(Text, "Item=Color,", 11) == 0) { + Text += 11; + string name; + tColor *value; + if (ParseVar(Text, "name", name) && ParseVar(Text, "default", &value)) { + mMap[name] = mTheme.AddColor(name.c_str(), *value); + result = true; + } else + esyslog("ERROR: text2skin: Parameters name and default must be present\n"); + } else + esyslog("ERROR: text2skin: syntax error"); + } + return result; +} + @@ -0,0 +1,35 @@ +/* + * $Id: theme.h,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $ + */ + +#ifndef VDR_TEXT2SKIN_THEME_H +#define VDR_TEXT2SKIN_THEME_H + +#include "common.h" +#include "file.h" +#include <vdr/themes.h> + +class cText2SkinTheme: public cText2SkinFile { +private: + cTheme mTheme; + map<string,int> mMap; + +protected: + bool Parse(const char *Text); + +public: + cText2SkinTheme(const char *Skin); + virtual ~cText2SkinTheme(); + + cTheme *Theme(void) { return &mTheme; } + tColor Color(const string &Name); +}; + +inline tColor cText2SkinTheme::Color(const string &Name) { + if (mMap.find(Name) != mMap.end()) + return mTheme.Color(mMap[Name]); + else + return 0x00000000; +} + +#endif // VDR_TEXT2SKIN_THEME_H |