diff options
author | lordjaxom <lordjaxom> | 2004-06-07 19:09:34 +0000 |
---|---|---|
committer | lordjaxom <lordjaxom> | 2004-06-07 19:09:34 +0000 |
commit | e0de96fc7168daeaf414fb6196e08969468427d2 (patch) | |
tree | de7f2dfb83796a7c77e5600a23b8b6b26f284796 | |
parent | 6094765d94e4caaf0813039dff826b731f277753 (diff) | |
download | vdr-plugin-text2skin-e0de96fc7168daeaf414fb6196e08969468427d2.tar.gz vdr-plugin-text2skin-e0de96fc7168daeaf414fb6196e08969468427d2.tar.bz2 |
- fixed Timebar which sometimes displayed something beyond 100%v0.0.2
- fixed scrolling in EPG detail display
- added "MenuEventEndTime", "MenuEventVPSTime" and "MenuEventDate"
- added "DateTimeF" and "MenuEventDateTimeF" for free formattable dates
- added parameter format that holds the format string for the above items
- implemented setup menu to flush image cache
-rw-r--r-- | HISTORY | 9 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | SKINS | 34 | ||||
-rw-r--r-- | bitmap.h | 3 | ||||
-rw-r--r-- | cache.h | 18 | ||||
-rw-r--r-- | data.c | 12 | ||||
-rw-r--r-- | data.h | 12 | ||||
-rw-r--r-- | display.c | 75 | ||||
-rw-r--r-- | display.h | 13 | ||||
-rw-r--r-- | i18n.c | 44 | ||||
-rw-r--r-- | i18n.h | 4 | ||||
-rw-r--r-- | loader.c | 12 | ||||
-rw-r--r-- | loader.h | 6 | ||||
-rw-r--r-- | render.c | 137 | ||||
-rw-r--r-- | render.h | 27 | ||||
-rw-r--r-- | setup.c | 23 | ||||
-rw-r--r-- | setup.h | 20 | ||||
-rw-r--r-- | text2skin.c | 9 |
18 files changed, 371 insertions, 91 deletions
@@ -1,6 +1,15 @@ VDR Plugin 'text2skin' Revision History --------------------------------------- +2004-06-07: Version 0.0.2 + +- fixed Timebar which sometimes displayed something beyond 100% +- fixed scrolling in EPG detail display +- added "MenuEventEndTime", "MenuEventVPSTime" and "MenuEventDate" +- added "DateTimeF" and "MenuEventDateTimeF" for free formattable dates +- added parameter format that holds the format string for the above items +- implemented setup menu to flush image cache + 2004-06-05: Version 0.0.1 - added scrollable texts and "SymbolScrollUp" and "SymbolScrollDown" @@ -9,7 +9,7 @@ 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 $ +# $Id: Makefile,v 1.8 2004/06/07 18:23:11 lordjaxom Exp $ # # The official name of this plugin. @@ -70,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 cache.o + file.o i18n.o theme.o cache.o setup.o ### Implicit rules: @@ -155,6 +155,13 @@ Item: Item=Time Description: Draws a time string into the given area. Otherwise, see Item=Text Parameters: x, y, width, height, fg, font, align, text +Item: Item=DateTimeF +Description: Draws a string expressing some details of the current date and + time. What is to be displayed will be decided by the skin author. + The paremeter "format" holds a format string according to the + manpage of strftime. +Parameters: x, y, width, height, fg, font, align, text, format + Item: Item=ChannelLogo Description: Draws a logo for the current channel (if present). The logo's filename will be the channel name, and the parameter type @@ -445,6 +452,29 @@ 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=MenuEventEndTime +Description: Draws the end time of the currently selected event when viewing + EPG entries. +Parameters: x, y, width, height, fg, font, align, text + +Item: Item=MenuEventVPSTime +Description: Draws the vps time of the currently selected event when viewing + EPG entries, if that is different from the start time. +Parameters: x, y, width, height, fg, font, align, text + +Item: Item=MenuEventDate +Description: Draws the date of the currently selected event when viewing + EPG entries. +Parameters: x, y, width, height, fg, font, align, text + +Item: Item=MenuEventDateTimeF +Description: Draws a string expressing some details of the start time of the + currently selected event when viewing EPG entries. What is to + be displayed will be decided by the skin author. The paremeter + "format" holds a format string according to the manpage of + strftime. +Parameters: x, y, width, height, fg, font, align, text, format + Item: Item=MenuRecording Description: Draws the summary of the currently selected recording when browsing recordings in a scrollable text-area. If this item is @@ -520,6 +550,10 @@ Parameter: type Description: The string giving the file extensions for logos. Default: not given +Parameter: type +Description: The format string for a date/time display according to strftime. +Default: "" + Parameter: align Description: A number describing the text alignment. Possible values are '0' for left aligned, '1' for centered and '2' for right aligned. @@ -1,5 +1,5 @@ /* - * $Id: bitmap.h,v 1.7 2004/06/05 01:39:36 lordjaxom Exp $ + * $Id: bitmap.h,v 1.8 2004/06/07 18:23:11 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_BITMAP_H @@ -21,6 +21,7 @@ private: public: static cText2SkinBitmap *Load(const char *Filename); + static void FlushCache(void) { mCache.Flush(); } virtual ~cText2SkinBitmap(); @@ -1,5 +1,5 @@ /* - * $Id: cache.h,v 1.1 2004/06/05 01:40:13 lordjaxom Exp $ + * $Id: cache.h,v 1.2 2004/06/07 18:23:11 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_CACHE_HPP @@ -29,7 +29,7 @@ private: int _maxItems; Item *_first; Item *_last; - + void Unlink(Item *item); void Update(Item *item); void Delete(Item *item); @@ -39,6 +39,7 @@ public: cText2SkinCache(int maxItems); ~cText2SkinCache(); + void Flush(void); bool Contains(const K &key); D &operator[](const K &key); }; @@ -105,6 +106,19 @@ cText2SkinCache<K,D>::cText2SkinCache(int maxItems) { template<class K,class D> cText2SkinCache<K,D>::~cText2SkinCache() { + Flush(); +} + +template<class K,class D> +void cText2SkinCache<K,D>::Flush(void) { + Item *cur = _first; + while (cur) { + Item *tmp = cur->_next; + _items.erase(cur->_key); + Unlink(cur); + Delete(cur); + cur = tmp; + } } template<class K,class D> @@ -1,15 +1,15 @@ /* - * $Id: data.c,v 1.13 2004/06/05 01:39:36 lordjaxom Exp $ + * $Id: data.c,v 1.16 2004/06/07 19:08:42 lordjaxom Exp $ */ #include "data.h" #include "common.h" -static string SectionNames[__SECTION_COUNT__] = +const string cText2SkinData::SectionNames[__SECTION_COUNT__] = { "Skin", "ChannelSmall", "Channel", "Volume", "ReplayMode", "Replay", "Message", "Menu" }; -static string ItemNames[__ITEM_COUNT__] = +const string cText2SkinData::ItemNames[__ITEM_COUNT__] = { "Unknown", "Skin", "Background", "Text", "Image", "Rectangle", "Ellipse", "Slope", "DateTime", "Date", "Time", "ChannelLogo", "ChannelNumberName", "ChannelNumber", "ChannelName", "Language", "Timebar", "PresentTime", @@ -24,7 +24,8 @@ static string ItemNames[__ITEM_COUNT__] = "SymbolScrollUp", "SymbolScrollDown", "MenuEventTitle", "MenuEventShortText", "MenuEventDescription", "MenuEventTime", "SymbolEventRunning", "SymbolEventTimer", "SymbolEventVPS", - "MenuRecording" }; + "MenuRecording", "MenuEventEndTime", "MenuEventVPSTime", "MenuEventDate", + "MenuEventDateTimeF", "DateTimeF" }; cText2SkinItem::cText2SkinItem(void) { mItem = itemUnknown; @@ -57,7 +58,7 @@ bool cText2SkinItem::Parse(const char *Text) { int i; // valid items begin at index two for (i = 2; i < __ITEM_COUNT__; ++i) { - if (ItemNames[i] == item) { + if (cText2SkinData::ItemNames[i] == item) { mItem = (eSkinItem)i; break; } @@ -92,6 +93,7 @@ bool cText2SkinItem::ParseItem(const char *Text) { ParseVar(Text, "altpath", mAltPath); ParseVar(Text, "text", mText); ParseVar(Text, "type", mType); + ParseVar(Text, "format", mFormat); ParseVar(Text, "align", &mAlign); return true; } @@ -1,5 +1,5 @@ /* - * $Id: data.h,v 1.11 2004/06/05 01:39:36 lordjaxom Exp $ + * $Id: data.h,v 1.14 2004/06/07 19:08:42 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_DATA_H @@ -91,6 +91,11 @@ enum eSkinItem { itemSymbolEventTimer, itemSymbolEventVPS, itemMenuRecording, + itemMenuEventEndTime, + itemMenuEventVPSTime, + itemMenuEventDate, + itemMenuEventDateTimeF, + itemDateTimeF, __ITEM_COUNT__ }; @@ -120,6 +125,7 @@ private: string mAltPath; string mText; string mType; + string mFormat; eTextAlignment mAlign; protected: @@ -145,6 +151,7 @@ public: const string &AltPath(void) const { return mAltPath; } const string &Text(void) const { return mText; } const string &Type(void) const { return mType; } + const string &Format(void) const { return mFormat; } eTextAlignment Align(void) const { return mAlign; } }; @@ -153,6 +160,9 @@ public: typedef vector<cText2SkinItem*> tSection; typedef tSection::iterator tIterator; + static const string SectionNames[__SECTION_COUNT__]; + static const string ItemNames[__ITEM_COUNT__]; + private: eSkinSection mCurrentSection; tSection mSections[__SECTION_COUNT__]; @@ -1,17 +1,17 @@ /* - * $Id: display.c,v 1.12 2004/06/05 18:04:29 lordjaxom Exp $ + * $Id: display.c,v 1.15 2004/06/07 19:08:42 lordjaxom Exp $ */ #include "render.h" #include "data.h" -#include "i18n.h" +#include "loader.h" #include "display.h" // --- cText2SkinDisplayChannel ----------------------------------------------- -cText2SkinDisplayChannel::cText2SkinDisplayChannel(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool WithInfo) { +cText2SkinDisplayChannel::cText2SkinDisplayChannel(cText2SkinLoader *Loader, bool WithInfo) { mWithInfo = WithInfo; - mRender = new cText2SkinRender(Data, I18n, Theme, WithInfo ? sectionChannel : sectionChannelSmall); + mRender = new cText2SkinRender(Loader, WithInfo ? sectionChannel : sectionChannelSmall); mDirty = false; } @@ -20,28 +20,34 @@ cText2SkinDisplayChannel::~cText2SkinDisplayChannel() { } void cText2SkinDisplayChannel::SetChannel(const cChannel *Channel, int Number) { + mRender->Lock(); if (mRender->mChannel != Channel || mRender->mChannelNumber != Number) { mRender->mChannel = Channel; mRender->mChannelNumber = Number; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following) { + mRender->Lock(); if (mRender->mChannelPresent != Present || mRender->mChannelFollowing != Following) { mRender->mChannelPresent = Present; mRender->mChannelFollowing = Following; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayChannel::SetMessage(eMessageType Type, const char *Text) { if (Text == NULL) Text = ""; + mRender->Lock(); if (mRender->mMessageType != Type || mRender->mMessageText != Text) { mRender->mMessageType = Type; mRender->mMessageText = Text; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayChannel::Flush(void) { @@ -53,8 +59,8 @@ void cText2SkinDisplayChannel::Flush(void) { // --- cText2SkinDisplayVolume ------------------------------------------------ -cText2SkinDisplayVolume::cText2SkinDisplayVolume(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme) { - mRender = new cText2SkinRender(Data, I18n, Theme, sectionVolume); +cText2SkinDisplayVolume::cText2SkinDisplayVolume(cText2SkinLoader *Loader) { + mRender = new cText2SkinRender(Loader, sectionVolume); mDirty = false; } @@ -63,12 +69,14 @@ cText2SkinDisplayVolume::~cText2SkinDisplayVolume() { } void cText2SkinDisplayVolume::SetVolume(int Current, int Total, bool Mute) { + mRender->Lock(); if (mRender->mVolumeCurrent != Current || mRender->mVolumeTotal != Total || mRender->mVolumeMute != Mute) { mRender->mVolumeCurrent = Current; mRender->mVolumeTotal = Total; mRender->mVolumeMute = Mute; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayVolume::Flush(void) { @@ -80,9 +88,9 @@ void cText2SkinDisplayVolume::Flush(void) { // --- cText2SkinDisplayReplay ------------------------------------------------ -cText2SkinDisplayReplay::cText2SkinDisplayReplay(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool ModeOnly) { +cText2SkinDisplayReplay::cText2SkinDisplayReplay(cText2SkinLoader *Loader, bool ModeOnly) { Dprintf("ModeOnly: %d\n", ModeOnly); - mRender = new cText2SkinRender(Data, I18n, Theme, ModeOnly ? sectionReplayMode : sectionReplay); + mRender = new cText2SkinRender(Loader, ModeOnly ? sectionReplayMode : sectionReplay); mDirty = false; } @@ -92,67 +100,83 @@ cText2SkinDisplayReplay::~cText2SkinDisplayReplay() { void cText2SkinDisplayReplay::SetTitle(const char *Title) { if (Title == NULL) Title = ""; + mRender->Lock(); if (mRender->mReplayTitle != Title) { mRender->mReplayTitle = Title; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::SetMode(bool Play, bool Forward, int Speed) { + mRender->Lock(); if (mRender->mReplayPlay != Play || mRender->mReplayForward != Forward || mRender->mReplaySpeed != Speed) { mRender->mReplayPlay = Play; mRender->mReplayForward = Forward; mRender->mReplaySpeed = Speed; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::SetProgress(int Current, int Total) { + mRender->Lock(); if (mRender->mReplayCurrent != Current || mRender->mReplayTotal != Total) { mRender->mReplayCurrent = Current; mRender->mReplayTotal = Total; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::SetMarks(const cMarks *Marks) { + mRender->Lock(); if (mRender->mReplayMarks != Marks) { mRender->mReplayMarks = Marks; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::SetCurrent(const char *Current) { if (Current == NULL) Current = ""; + mRender->Lock(); if (mRender->mReplayCurrentText != Current) { mRender->mReplayCurrentText = Current; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::SetTotal(const char *Total) { if (Total == NULL) Total = ""; + mRender->Lock(); if (mRender->mReplayTotalText != Total) { mRender->mReplayTotalText = Total; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::SetJump(const char *Jump) { if (Jump == NULL) Jump = ""; + mRender->Lock(); if (mRender->mReplayJump != Jump) { mRender->mReplayJump = Jump; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::SetMessage(eMessageType Type, const char *Text) { if (Text == NULL) Text = ""; + mRender->Lock(); if (mRender->mMessageType != Type || mRender->mMessageText != Text) { mRender->mMessageType = Type; mRender->mMessageText = Text; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayReplay::Flush(void) { @@ -164,8 +188,8 @@ void cText2SkinDisplayReplay::Flush(void) { // --- cText2SkinDisplayMessage ----------------------------------------------- -cText2SkinDisplayMessage::cText2SkinDisplayMessage(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme) { - mRender = new cText2SkinRender(Data, I18n, Theme, sectionMessage); +cText2SkinDisplayMessage::cText2SkinDisplayMessage(cText2SkinLoader *Loader) { + mRender = new cText2SkinRender(Loader, sectionMessage); mDirty = false; } @@ -175,11 +199,13 @@ cText2SkinDisplayMessage::~cText2SkinDisplayMessage() { void cText2SkinDisplayMessage::SetMessage(eMessageType Type, const char *Text) { if (Text == NULL) Text = ""; + mRender->Lock(); if (mRender->mMessageType != Type || mRender->mMessageText != Text) { mRender->mMessageType = Type; mRender->mMessageText = Text; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMessage::Flush(void) { @@ -191,13 +217,13 @@ void cText2SkinDisplayMessage::Flush(void) { // --- cText2SkinDisplayMenu -------------------------------------------------- -cText2SkinDisplayMenu::cText2SkinDisplayMenu(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme) { - mRender = new cText2SkinRender(Data, I18n, Theme, sectionMenu); +cText2SkinDisplayMenu::cText2SkinDisplayMenu(cText2SkinLoader *Loader) { + mRender = new cText2SkinRender(Loader, sectionMenu); mDirty = false; mMaxItems = 0; - cText2SkinItem *area = Data->Get(sectionMenu, itemMenuArea); - cText2SkinItem *item = Data->Get(sectionMenu, itemMenuItem); + cText2SkinItem *area = Loader->Data()->Get(sectionMenu, itemMenuArea); + cText2SkinItem *item = Loader->Data()->Get(sectionMenu, itemMenuItem); if (area && item) mMaxItems = area->Size().h / item->Size().h; else @@ -209,6 +235,7 @@ cText2SkinDisplayMenu::~cText2SkinDisplayMenu() { } void cText2SkinDisplayMenu::Clear(void) { + mRender->Lock(); mRender->mMenuItems.clear(); mRender->mMenuTitle = ""; mRender->mMenuCurrent = -1; @@ -219,15 +246,19 @@ void cText2SkinDisplayMenu::Clear(void) { mRender->mMenuEvent = NULL; mRender->mMenuRecording = NULL; mRender->mMenuText = ""; + DELETENULL(mRender->mScroller); + mRender->Unlock(); mDirty = true; } void cText2SkinDisplayMenu::SetTitle(const char *Title) { if (Title == NULL) Title = ""; + mRender->Lock(); if (mRender->mMenuTitle != Title) { mRender->mMenuTitle = Title; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) { @@ -235,6 +266,7 @@ void cText2SkinDisplayMenu::SetButtons(const char *Red, const char *Green, const if (Green == NULL) Green = ""; if (Yellow == NULL) Yellow = ""; if (Blue == NULL) Blue = ""; + mRender->Lock(); if (mRender->mMenuRed != Red || mRender->mMenuGreen != Green || mRender->mMenuYellow != Yellow || mRender->mMenuBlue != Blue) { mRender->mMenuRed = Red; mRender->mMenuGreen = Green; @@ -242,15 +274,18 @@ void cText2SkinDisplayMenu::SetButtons(const char *Red, const char *Green, const mRender->mMenuBlue = Blue; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::SetMessage(eMessageType Type, const char *Text) { if (Text == NULL) Text = ""; + mRender->Lock(); if (mRender->mMessageType != Type || mRender->mMessageText != Text) { mRender->mMessageType = Type; mRender->mMessageText = Text; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) { @@ -265,6 +300,7 @@ void cText2SkinDisplayMenu::SetItem(const char *Text, int Index, bool Current, b break; } SetEditableWidth(mRender->GetEditableWidth(item, Current)); + mRender->Lock(); if ((int)mRender->mMenuItems.size() <= Index) { mRender->mMenuItems.push_back(item); mDirty = true; @@ -276,48 +312,59 @@ void cText2SkinDisplayMenu::SetItem(const char *Text, int Index, bool Current, b mRender->mMenuCurrent = Index; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::SetEvent(const cEvent *Event) { + mRender->Lock(); if (mRender->mMenuEvent != Event) { mRender->mMenuEvent = Event; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::SetRecording(const cRecording *Recording) { + mRender->Lock(); if (mRender->mMenuRecording != Recording) { mRender->mMenuRecording = Recording; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::SetText(const char *Text, bool FixedFont) { if (Text == NULL) Text = ""; + mRender->Lock(); if (mRender->mMenuText != Text || mRender->mMenuTextFixedFont != FixedFont) { mRender->mMenuText = Text; mRender->mMenuTextFixedFont = FixedFont; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5) { cSkinDisplayMenu::SetTabs(Tab1, Tab2, Tab3, Tab4, Tab5); + mRender->Lock(); 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); + mRender->Unlock(); } void cText2SkinDisplayMenu::Scroll(bool Up, bool Page) { + mRender->Lock(); if (mRender->mScroller && (Up ? mRender->mScroller->CanScrollUp() : mRender->mScroller->CanScrollDown())) { mRender->mMenuScroll = true; mRender->mMenuScrollUp = Up; mRender->mMenuScrollPage = Page; mDirty = true; } + mRender->Unlock(); } void cText2SkinDisplayMenu::Flush(void) { @@ -1,5 +1,5 @@ /* - * $Id: display.h,v 1.5 2004/06/05 18:04:29 lordjaxom Exp $ + * $Id: display.h,v 1.6 2004/06/07 18:23:11 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_SKIN_H @@ -11,6 +11,7 @@ class cText2SkinData; class cText2SkinI18n; class cText2SkinRender; +class cText2SkinLoader; class cText2SkinDisplayChannel: public cSkinDisplayChannel { private: @@ -19,7 +20,7 @@ private: bool mDirty; public: - cText2SkinDisplayChannel(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool WithInfo); + cText2SkinDisplayChannel(cText2SkinLoader *Loader, bool WithInfo); virtual ~cText2SkinDisplayChannel(); virtual void SetChannel(const cChannel *Channel, int Number); @@ -34,7 +35,7 @@ private: bool mDirty; public: - cText2SkinDisplayVolume(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme); + cText2SkinDisplayVolume(cText2SkinLoader *Loader); virtual ~cText2SkinDisplayVolume(); virtual void SetVolume(int Current, int Total, bool Mute); virtual void Flush(void); @@ -45,7 +46,7 @@ private: cText2SkinRender *mRender; bool mDirty; public: - cText2SkinDisplayReplay(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, bool ModeOnly); + cText2SkinDisplayReplay(cText2SkinLoader *Loader, bool ModeOnly); virtual ~cText2SkinDisplayReplay(); virtual void SetTitle(const char *Title); virtual void SetMode(bool Play, bool Forward, int Speed); @@ -64,7 +65,7 @@ private: bool mDirty; public: - cText2SkinDisplayMessage(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme); + cText2SkinDisplayMessage(cText2SkinLoader *Loader); virtual ~cText2SkinDisplayMessage(); virtual void SetMessage(eMessageType Type, const char *Text); virtual void Flush(void); @@ -77,7 +78,7 @@ private: int mMaxItems; public: - cText2SkinDisplayMenu(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme); + cText2SkinDisplayMenu(cText2SkinLoader *Loader); virtual ~cText2SkinDisplayMenu(); virtual int MaxItems(void) { return mMaxItems; } @@ -1,9 +1,51 @@ /* - * $Id: i18n.c,v 1.2 2004/06/05 16:52:44 lordjaxom Exp $ + * $Id: i18n.c,v 1.3 2004/06/07 18:23:11 lordjaxom Exp $ */ #include "i18n.h" +const tI18nPhrase Phrases[] = { + { "Flush image cache", + "Bildspeicher leeren", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + }, + { "Flushing image cache...", + "Bildspeicher wird geleert...", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + }, + { NULL } +}; + cText2SkinI18n::cText2SkinI18n(const char *Skin): cText2SkinFile(Skin) { mIdentity = (string)"text2skin_" + Skin; mNumPhrases = 0; @@ -1,5 +1,5 @@ /* - * $Id: i18n.h,v 1.1 2004/06/02 20:43:05 lordjaxom Exp $ + * $Id: i18n.h,v 1.2 2004/06/07 18:23:11 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_I18N_H @@ -9,6 +9,8 @@ #include "file.h" #include <vdr/i18n.h> +extern const tI18nPhrase Phrases[]; + class cText2SkinI18n: public cText2SkinFile { private: string mIdentity; @@ -1,5 +1,5 @@ /* - * $Id: loader.c,v 1.8 2004/06/05 16:52:44 lordjaxom Exp $ + * $Id: loader.c,v 1.9 2004/06/07 18:23:11 lordjaxom Exp $ */ #include "loader.h" @@ -74,21 +74,21 @@ cText2SkinLoader::~cText2SkinLoader() { cSkinDisplayChannel *cText2SkinLoader::DisplayChannel(bool WithInfo) { Dprintf("WithInfo: %d\n", WithInfo); - return new cText2SkinDisplayChannel(mData, mI18n, mTheme, WithInfo); + return new cText2SkinDisplayChannel(this, WithInfo); } cSkinDisplayMenu *cText2SkinLoader::DisplayMenu(void) { - return new cText2SkinDisplayMenu(mData, mI18n, mTheme); + return new cText2SkinDisplayMenu(this); } cSkinDisplayVolume *cText2SkinLoader::DisplayVolume(void) { - return new cText2SkinDisplayVolume(mData, mI18n, mTheme); + return new cText2SkinDisplayVolume(this); } cSkinDisplayReplay *cText2SkinLoader::DisplayReplay(bool ModeOnly) { - return new cText2SkinDisplayReplay(mData, mI18n, mTheme, ModeOnly); + return new cText2SkinDisplayReplay(this, ModeOnly); } cSkinDisplayMessage *cText2SkinLoader::DisplayMessage(void) { - return new cText2SkinDisplayMessage(mData, mI18n, mTheme); + return new cText2SkinDisplayMessage(this); } @@ -1,5 +1,5 @@ /* - * $Id: loader.h,v 1.4 2004/06/02 20:43:05 lordjaxom Exp $ + * $Id: loader.h,v 1.5 2004/06/07 18:23:11 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_LOADER_H @@ -32,6 +32,10 @@ public: virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly); virtual cSkinDisplayVolume *DisplayVolume(void); virtual cSkinDisplayMessage *DisplayMessage(void); + + cText2SkinData *Data(void) const { return mData; } + cText2SkinI18n *I18n(void) const { return mI18n; } + cText2SkinTheme *Theme(void) const { return mTheme; } }; #endif // VDR_TEXT2SKIN_LOADER_H @@ -1,21 +1,25 @@ /* - * $Id: render.c,v 1.19 2004/06/05 18:04:29 lordjaxom Exp $ + * $Id: render.c,v 1.22 2004/06/07 19:08:42 lordjaxom Exp $ */ #include "render.h" -#include "data.h" +#include "loader.h" +#include "i18n.h" +#include "theme.h" #include "bitmap.h" #include <vdr/channels.h> #include <vdr/epg.h> #include <vdr/menu.h> -cText2SkinRender::cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, eSkinSection Section) { +cText2SkinRender::cText2SkinRender(cText2SkinLoader *Loader, eSkinSection Section) { tArea areas[MAXOSDAREAS]; int numAreas = 0; - mData = Data; - mI18n = I18n; - mTheme = Theme; + SetDescription("Text2Skin: %s display update", cText2SkinData::SectionNames[Section].c_str()); + + mData = Loader->Data(); + mI18n = Loader->I18n(); + mTheme = Loader->Theme(); mSection = Section; mOsd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop); mScroller = NULL; @@ -40,17 +44,17 @@ cText2SkinRender::cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, c mMenuScroll = false; mMenuScrollUp = false; mMenuScrollPage = false; + mActive = false; - cText2SkinData::tIterator it = Data->First(mSection); - for (; it != Data->Last(mSection); ++it) { - cText2SkinItem *item = (*it); - if (item->Item() == itemBackground) { + cText2SkinData::tIterator it = mData->First(mSection); + for (; it != mData->Last(mSection); ++it) { + if ((*it)->Item() == itemBackground) { if (numAreas < MAXOSDAREAS) { - areas[numAreas].x1 = item->Pos().x; - areas[numAreas].y1 = item->Pos().y; - areas[numAreas].x2 = item->Pos().x + item->Size().w - 1; - areas[numAreas].y2 = item->Pos().y + item->Size().h - 1; - areas[numAreas].bpp = item->Bpp(); + areas[numAreas].x1 = (*it)->Pos().x; + areas[numAreas].y1 = (*it)->Pos().y; + areas[numAreas].x2 = (*it)->Pos().x + (*it)->Size().w - 1; + areas[numAreas].y2 = (*it)->Pos().y + (*it)->Size().h - 1; + areas[numAreas].bpp = (*it)->Bpp(); ++numAreas; } else esyslog("ERROR: text2skin: too many background areas\n"); @@ -82,13 +86,31 @@ cText2SkinRender::cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, c } esyslog("ERROR: text2skin: OSD provider can't handle skin: %s\n", emsg); } + + //Start(); } cText2SkinRender::~cText2SkinRender() { + if (mActive) { + mMutex.Lock(); + mActive = false; + mDoUpdate.Broadcast(); + mMutex.Unlock(); + Cancel(3); + } delete mScroller; delete mOsd; } +void cText2SkinRender::Action(void) { + mActive = true; + Lock(); + while (mActive) { + mDoUpdate.Wait(mMutex); + } + Unlock(); +} + void cText2SkinRender::Flush(void) { cText2SkinData::tIterator it = mData->First(mSection); for (; it != mData->Last(mSection); ++it) { @@ -105,11 +127,10 @@ void cText2SkinRender::Flush(void) { case itemImage: DisplayImage(item); break; case itemDateTime: - DisplayDateTime(item); break; case itemDate: - DisplayDate(item); break; case itemTime: - DisplayTime(item); break; + case itemDateTimeF: + DisplayDateTime(item); break; case itemChannelNumberName: DisplayChannelNumberName(item); break; case itemChannelNumber: @@ -191,6 +212,10 @@ void cText2SkinRender::Flush(void) { case itemMenuEventDescription: DisplayMenuEventDescription(item); break; case itemMenuEventTime: + case itemMenuEventEndTime: + case itemMenuEventVPSTime: + case itemMenuEventDate: + case itemMenuEventDateTimeF: DisplayMenuEventTime(item); break; case itemMenuRecording: DisplayMenuRecording(item); break; @@ -227,7 +252,6 @@ void cText2SkinRender::DrawImage(const POINT &Pos, const SIZE &Size, const tColo 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)); mOsd->DrawBitmap(Pos.x, Pos.y, *bmp); } free(p); @@ -252,6 +276,8 @@ void cText2SkinRender::DrawSlope(const POINT &Pos, const SIZE &Size, const tColo void cText2SkinRender::DrawProgressbar(const POINT &Pos, const SIZE &Size, int Current, int Total, const tColor *Bg, const tColor *Fg, const cMarks *Marks) { if (Bg) DrawRectangle(Pos, Size, Bg); + if (Current > Total) + Current = Total; if (Size.w > Size.h) { SIZE size = { Size.w * Current / Total, Size.h }; DrawRectangle(Pos, size, Fg); @@ -367,23 +393,31 @@ void cText2SkinRender::DisplayImage(cText2SkinItem *Item) { } void cText2SkinRender::DisplayDateTime(cText2SkinItem *Item) { - const char *text = DayDateTime(time(NULL)); - 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(), 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(), ItemFg(Item), ItemText(Item, text + 13), Item->Font(), Item->Align()); - free(text); + char *text = NULL; + time_t t; + t = time(NULL); + switch (Item->Item()) { + case itemDateTime: + text = strdup(DayDateTime(t)); break; + case itemDate: + text = strdup(DayDateTime(t) + 4); text[5] = '\0'; break; + case itemTime: + text = strdup(DayDateTime(t) + 13); text[5] = '\0'; break; + case itemDateTimeF: + { + struct tm tm_r, *tm; + tm = localtime_r(&t, &tm_r); + text = MALLOC(char, 1000); + strftime(text, 1000, Item->Format().c_str(), tm); + } + break; + default: + break; + } + if (text) { + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text), Item->Font(), Item->Align()); + free(text); + } } void cText2SkinRender::DisplayChannelNumberName(cText2SkinItem *Item) { @@ -645,8 +679,6 @@ void cText2SkinRender::DisplayMenuColorbutton(cText2SkinItem *Item) { 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) { @@ -666,8 +698,33 @@ void cText2SkinRender::DisplayMenuEventDescription(cText2SkinItem *Item) { 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()); + char *text = NULL; + Dprintf("DATE: %s\n", DayDateTime(mMenuEvent->StartTime())); + switch (Item->Item()) { + case itemMenuEventTime: + text = strdup(DayDateTime(mMenuEvent->StartTime()) + 10); break; + case itemMenuEventEndTime: + text = strdup(DayDateTime(mMenuEvent->EndTime()) + 10); break; + case itemMenuEventVPSTime: + text = mMenuEvent->Vps() != mMenuEvent->StartTime() ? strdup(DayDateTime(mMenuEvent->Vps()) + 10) : NULL; break; + case itemMenuEventDate: + text = strdup(DayDateTime(mMenuEvent->StartTime()) + 4); text[5] = '\0'; break; + case itemMenuEventDateTimeF: + { + time_t t = mMenuEvent->StartTime(); + struct tm tm_r, *tm; + tm = localtime_r(&t, &tm_r); + text = MALLOC(char, 1000); + strftime(text, 1000, Item->Format().c_str(), tm); + } + break; + default: + break; + } + if (text) { + DrawText(Item->Pos(), Item->Size(), ItemFg(Item), ItemText(Item, text), Item->Font(), Item->Align()); + free(text); + } } } @@ -1,5 +1,5 @@ /* - * $Id: render.h,v 1.15 2004/06/05 18:04:29 lordjaxom Exp $ + * $Id: render.h,v 1.17 2004/06/07 19:08:42 lordjaxom Exp $ */ #ifndef VDR_TEXT2SKIN_RENDER_H @@ -7,15 +7,18 @@ #include "common.h" #include "data.h" -#include "i18n.h" -#include "theme.h" #include <vdr/osd.h> #include <vdr/skins.h> +#include <vdr/thread.h> class cChannel; class cEvent; +class cText2SkinLoader; +class cText2SkinData; +class cText2SkinI18n; +class cText2SkinTheme; -class cText2SkinRender { +class cText2SkinRender: public cThread { friend class cText2SkinDisplayChannel; friend class cText2SkinDisplayVolume; friend class cText2SkinDisplayReplay; @@ -80,7 +83,17 @@ private: bool mMenuScrollPage; int mMenuTabs[cSkinDisplayMenu::MaxTabs]; + // update thread + bool mActive; + cCondVar mDoUpdate; + cMutex mMutex; + protected: + // Update thread + void Lock(void) { mMutex.Lock(); } + void Unlock(void) { mMutex.Unlock(); } + virtual void Action(void); + // Basic operations void DrawBackground(const POINT &Pos, const SIZE &Size, const tColor *Bg, const tColor *Fg, const string &Path); void DrawImage(const POINT &Pos, const SIZE &Size, const tColor *Bg, const tColor *Fg, const string &Path); @@ -99,8 +112,6 @@ protected: void DisplayText(cText2SkinItem *Item); void DisplayImage(cText2SkinItem *Item); void DisplayDateTime(cText2SkinItem *Item); - void DisplayDate(cText2SkinItem *Item); - void DisplayTime(cText2SkinItem *Item); void DisplayChannelNumberName(cText2SkinItem *Item); void DisplayChannelNumber(cText2SkinItem *Item); void DisplayChannelName(cText2SkinItem *Item); @@ -141,8 +152,8 @@ protected: int GetEditableWidth(MenuItem Item, bool Current); public: - cText2SkinRender(cText2SkinData *Data, cText2SkinI18n *I18n, cText2SkinTheme *Theme, eSkinSection Section); - ~cText2SkinRender(); + cText2SkinRender(cText2SkinLoader *Loader, eSkinSection Section); + virtual ~cText2SkinRender(); void Flush(void); }; @@ -0,0 +1,23 @@ +/* + * $Id: setup.c,v 1.1 2004/06/07 19:09:20 lordjaxom Exp $ + */ + +#include "setup.h" +#include "bitmap.h" + +cText2SkinSetupPage::cText2SkinSetupPage(void) { + Add(new cOsdItem(tr("Flush image cache"), osUser1)); +} + +cText2SkinSetupPage::~cText2SkinSetupPage() { +} + +eOSState cText2SkinSetupPage::ProcessKey(eKeys Key) { + eOSState state = cMenuSetupPage::ProcessKey(Key); + if (state == osUser1) { + Skins.Message(mtInfo, tr("Flushing image cache...")); + cText2SkinBitmap::FlushCache(); + return osContinue; + } + return state; +} @@ -0,0 +1,20 @@ +/* + * $Id: setup.h,v 1.1 2004/06/07 19:09:20 lordjaxom Exp $ + */ + +#ifndef VDR_TEXT2SKIN_SETUP_H +#define VDR_TEXT2SKIN_SETUP_H + +#include "common.h" +#include <vdr/menuitems.h> + +class cText2SkinSetupPage: public cMenuSetupPage { +public: + cText2SkinSetupPage(void); + virtual ~cText2SkinSetupPage(); + + virtual void Store(void) {} + virtual eOSState ProcessKey(eKeys Key); +}; + +#endif // VDR_TEXT2SKIN_SETUP_H diff --git a/text2skin.c b/text2skin.c index bd52294..efd236a 100644 --- a/text2skin.c +++ b/text2skin.c @@ -3,13 +3,15 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: text2skin.c,v 1.10 2004/06/05 16:52:44 lordjaxom Exp $ + * $Id: text2skin.c,v 1.13 2004/06/07 19:08:42 lordjaxom Exp $ */ #include "text2skin.h" +#include "setup.h" +#include "i18n.h" #include "loader.h" -const char *cText2SkinPlugin::VERSION = "0.0.1"; +const char *cText2SkinPlugin::VERSION = "0.0.2"; const char *cText2SkinPlugin::THEMEVERSION = "0.0.1"; const char *cText2SkinPlugin::DESCRIPTION = "Loader for text-based skins"; @@ -23,13 +25,14 @@ cText2SkinPlugin::~cText2SkinPlugin() bool cText2SkinPlugin::Start(void) { + RegisterI18n(Phrases); cText2SkinLoader::Start(); return true; } cMenuSetupPage *cText2SkinPlugin::SetupMenu(void) { - return NULL; + return new cText2SkinSetupPage; } bool cText2SkinPlugin::SetupParse(const char *Name, const char *Value) |