/** * GraphTFT plugin for the Video Disk Recorder * * theme.h - A plugin for the Video Disk Recorder * * (c) 2004 Lars Tegeler, Sascha Volkenandt * (c) 2006-2011 Jörg Wendel * * This code is distributed under the terms and conditions of the * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details. * * $Id: theme.h,v 1.14 2012/09/27 13:07:11 wendel Exp $ * **/ #ifndef __GTFT_THEME_H #define __GTFT_THEME_H #include #include #include #include #include #include #include #include #define SECONDS(x) (((uint64_t)x)*1000) using std::string; using std::map; class cDisplayItem; class cGraphTFTDisplay; class cThemeSection; //*************************************************************************** // Variable Provider //*************************************************************************** class VariableProvider { public: VariableProvider() {}; virtual ~VariableProvider() {}; virtual string channelLogoPath(const char* channel, const char* format = 0, int classic = yes); virtual int variableOf(string& name, const char* expression, char*& e); virtual int evaluate(string& buf, const char* var); virtual const char* splitFormatValue(const char* data, char* value, char* format); virtual int lookupVariable(const char* name, string& value, const char* fmt = 0) = 0; }; //*************************************************************************** // Theme Service //*************************************************************************** class cThemeService { public: enum ReplayMode { rmUnknown = na, rmPlay, rmForward, rmSpeed }; enum ItemUnit { iuUnknown = na, iuAbsolute, iuRelative, iuPercent }; enum ConditionArgumentType { catUnknown, catInteger, catString }; enum MenuItemType { itNormal, itPartingLine }; // groups enum eThmeGroup { groupUnknown = 1, groupChannel = 2, groupVolume = 4, groupButton = 8, groupRecording = 16, groupReplay = 32, groupMessage = 64, groupMenu = 128, groupMusic = 256, groupTextList = 512, groupCalibrate = 1024, groupAll = 0xFFFF }; // items enum eThemeItem { itemUnknown = na, itemSectionInclude, // = 0 itemTheme, itemBegin, // = 2 itemText = itemBegin, // = 2 itemImage, // = 3 itemImageFile, itemRectangle, // = itemTimebar, itemSym2ch, itemSymDD, itemSymVTX, itemSymCrypt, itemMailSymbol, itemMailCount, itemMessage, itemVolumeMuteSymbol, itemVolumebar, itemMenu, itemMenuSelected, itemMenuButton, itemMenuButtonRed = itemMenuButton, // = itemMenuButtonGreen, itemMenuButtonYellow, itemMenuButtonBlue, itemMenuButtonBackground, // = itemMenuButtonBackgroundRed = itemMenuButtonBackground, // = itemMenuButtonBackgroundGreen, itemMenuButtonBackgroundYellow, itemMenuButtonBackgroundBlue, itemMenuImageMap, // = itemSpectrumAnalyzer, itemPartingLine, // = itemSysinfo, itemBackground, itemTextList, itemProgressbar, itemClickArea, itemMenuNavigationArea, itemCalibrationCursor, itemColumn, itemColumnSelected, itemEventColumn, itemEventColumnSelected, itemDefaults, itemCount }; enum Misc { maxPathCount = 10 }; enum Align { algLeft, algCenter, algRight }; enum ScrollModes { smOff, smMarquee, smTicker }; struct Translation { int denum; const char* name; }; static int toDenum(Translation t[], const char* value); static Translation alignments[]; static Translation scrollmodes[]; static const char* toName(eThemeItem aItem); static eThemeItem toItem(const char* aName); static int isValid(eThemeItem aItem) { return aItem > itemUnknown && aItem < itemCount; } static const char* items[itemCount+1]; }; typedef cThemeService Ts; //*************************************************************************** // Class cThemeItem // - represents a theme item //*************************************************************************** class cThemeItem : public cListObject, public cThemeService, public VariableProvider { public: cThemeItem(); virtual ~cThemeItem(); bool Parse(const char *s); int parseDirectives(string& toParse); int parseVariable(string& toParse, cThemeSection* section = 0); // int lookupVariable(const char* name, string& value, const char* fmt = 0); int setVariable(const char* name, int value); // statics static cDisplayItem* newDisplayItem(int item); // temporary buffer used by the parser ::Parse() static cThemeSection* currentSection; static string lineBuffer; static string condition; protected: // functions bool ParseText(string toParse); bool ParseVar(string toParse, string name, int* value); bool ParseVarTime(string toParse, string name, uint64_t* value); bool ParseVar(string toParse, string name, string* value); bool ParseVarExt(string toParse, string name, string* value); bool ParseVarExt(string toParse, string name, int* value); bool ParseDirective(string toParse, string name, string* value); bool ParseVar(string toParse, string name, int* value, Translation t[]); // item properties int _item; string _debug; string _sectionInclude; int _x, _y, _width, _height,_red, _green, _blue, _transparent; int _lines, _line, _size, _switch; string _start_line; int _menu_x, _menu_y, _menu_width, _menu_height; int _bg_x, _bg_y, _bg_width, _bg_height; int _bg_red, _bg_green, _bg_blue, _bg_transparent; int _stat_pic, _stat_x, _stat_y, _image_map; int _stat_text, _stat_width, _stat_height; int _align, _align_v, _animated, _count, _number; uint64_t _delay; int _index, _spacing, _bar_height, _bar_height_unit; int _scroll, _scroll_count, _dots; int _permanent, _factor, _aspect_ratio, _fit, _foreground; int _whipe_res; string _value; string _total; string _unit; string _reference; string _onClick; string _onDblClick; string _onUp; string _onDown; string _font; string _name; string _path; string _focus; string _path2; string _type; string _format; string _text; string _condition; int pathCount; string pathList[maxPathCount]; cThemeSection* section; // my section }; //*************************************************************************** // Display Items //*************************************************************************** class cDisplayItem : public cThemeItem { public: cDisplayItem(); virtual ~cDisplayItem(); // functions virtual const char* nameOf() { return toName((eThemeItem)_item); } virtual int groupOf() { return groupUnknown; } virtual int clear(); virtual int draw(); virtual int refresh(); virtual int reset(); // virtual string channelLogoPath(const char* channel, int classic = yes); virtual int drawText(const char* text, int y = 0, int height = 0, int clear = yes, int skipLines = 0); virtual int drawRectangle(); virtual int drawBackRect(int y = 0, int height = 0); virtual int drawImage(const char* path = 0, int fit = na, int aspectRatio = na); virtual int drawImageOnBack(const char* path = 0, int fit = no); virtual int drawProgressBar(double current, double total, string path, int y = na, int height = na, int withFrame = yes, int clear = yes); virtual int drawPartingLine(string text, int y, int height); virtual void setBackgroundItem(cDisplayItem* p) { backgroundItem = p; } virtual void setNextDraw() { nextDraw = msNow(); } virtual uint64_t getNextDraw() { return nextDraw; } virtual int isForegroundItem() { return no; } void scheduleDrawAt(uint64_t aTime); void scheduleDrawIn(int aTime); void scheduleDrawNextFullMinute(); void setSection(cThemeSection* s) { section = s; } // statics static void scheduleForce(uint64_t aTime); static void clearSelectedItem() { selectedItem = 0; } static void setForce(int flag) { forceDraw = flag; } static int getForce() { return forceDraw; } static void setRenderer(Renderer* aRender) { render = aRender; } static void setVdrStatus(cGraphTFTDisplay* aVdrStatus) { vdrStatus = aVdrStatus; } // Item getter/setter int Item() { return _item; } int Index(int value = na) { if (value != na) _index = value; return _index; } int X(int value = na) { if (value != na) _x = value; return _x; } int Width(int value = na) { if (value != na) _width = value; return _width; } string Name(const char* value = 0) { if (value) _name = value; return _name; } int Number(int value = na) { if (value != na) _number = value; return _number; } // item options int BgX() { return _bg_x; } int Y() { return _y; } int BgY() { return _bg_y; } int ImageMap() { return _image_map; } int StaticPicture() { return _stat_pic; } int StaticText() { return _stat_text; } int StaticWidth() { return _stat_width; } int StaticHeight() { return _stat_height; } int StaticX() { return _stat_x; } int StaticY() { return _stat_y; } int BgWidth() { return _bg_width; } int Height() { return _height; } int BgHeight() { return _bg_height; } int Red() { return _red; } int BgRed() { return _bg_red; } int Green() { return _green; } int BgGreen() { return _bg_green; } int Blue() { return _blue; } int BgBlue() { return _bg_blue; } int Transparent() { return _transparent; } int BgTransparent() { return _bg_transparent; } int Lines() { return _lines; } int StartLine(int value = na) { return optionVariable(_start_line.c_str(), value); } int Line() { return _line; } int Size() { return _size; } int Switch() { return _switch; } int Align() { return _align; } int AlignV() { return _align_v; } uint64_t Delay() { return _delay; } int Foreground() { return _foreground; } int Count() { return _count; } int Spacing() { return _spacing; } int BarHeight() { return _bar_height; } int BarHeightUnit() { return _bar_height_unit; } int Fit() { return _fit; } int AspectRatio() { return _aspect_ratio; } int Scroll() { return _scroll; } int MenuX() { return _menu_x; } int MenuY() { return _menu_y; } int MenuWidth() { return _menu_width; } int MenuHeight() { return _menu_height; } int WhipeRes() { return _whipe_res; } string Value() { return _value; } string Total() { return _total; } string Font() { return _font; } string Focus() { return _focus; } string Path() { return _path; } string Path2() { return _path2; } string Type() { return _type; } string Format() { return _format; } string Text() { return _text; } string OnClick() { return _onClick; } string OnDblClick() { return _onDblClick; } string OnUp() { return _onUp; } string OnDown() { return _onDown; } string Condition() { return _condition; } string SectionInclude() { return _sectionInclude; } string Debug() { return _debug; } // int optionVariable(const char* exp, int value = na) { string p; string name; char* e; if (value != na && variableOf(name, exp, e) == success) setVariable(name.c_str(), value); if (evaluate(p, exp) == success) return atoi(p.c_str()); return 0; } int evaluateCondition(int recurse = no); string evaluatePath(); int lookupVariable(const char* name, string& value, const char* fmt = 0); int lineCount() { return actLineCount; } protected: const char* variable(const char* name, const char* fmt, int& status); const char* formatDateTime(time_t time, const char* fmt, char* date, int len, int absolut = no); int replayModeValue(ReplayMode rm); int condition(int left, int right, const char* op); int condition(string* left, string* right, const char* op); // data uint64_t nextDraw; cDisplayItem* backgroundItem; int visible; // scroll mode int marquee_active; int marquee_left; unsigned int marquee_idx; int marquee_count; int marquee_strip; int animation; uint64_t nextAnimationAt; string animationImage; int actLineCount; int lastConditionState; int textWidth; // statics static int forceDraw; static Renderer* render; static cGraphTFTDisplay* vdrStatus; static cDisplayItem* selectedItem; static uint64_t nextForce; }; class cDisplayText : public cDisplayItem { public: cDisplayText() { lastText = ""; } int groupOf() { int group = groupUnknown; if (strstr(_text.c_str(), "{replay") || strstr(_condition.c_str(), "{replay")) group |= groupReplay; if (strstr(_text.c_str(), "{recording")|| strstr(_condition.c_str(), "{recording")) group |= groupRecording; if (strstr(_text.c_str(), "{event") || strstr(_condition.c_str(), "{event")) group |= groupChannel; if (strstr(_text.c_str(), "{present") || strstr(_condition.c_str(), "{present")) group |= groupChannel; if (strstr(_text.c_str(), "{following") || strstr(_condition.c_str(), "{following")) group |= groupChannel; if (strstr(_condition.c_str(), "{volume")) group |= groupVolume; if (strstr(_condition.c_str(), "{calibration")) group |= groupCalibrate; return group; } int draw(); protected: string lastText; }; class cDisplayTextList : public cDisplayItem { public: int groupOf() { int group = groupTextList; if (strstr(_text.c_str(), "{music")) group |= groupMusic; if (strstr(_text.c_str(), "{actRecording")|| strstr(_condition.c_str(), "{actRecording")) group |= groupRecording; return group; } int draw(); }; class cDisplayRectangle : public cDisplayItem { public: int draw(); }; class cDisplayImage : public cDisplayItem { public: int groupOf() { int group = groupUnknown; if (strstr(_path.c_str(), "{replay") || strstr(_condition.c_str(), "{replay")) group |= groupReplay; if (strstr(_path.c_str(), "{recording")|| strstr(_condition.c_str(), "{recording")) group |= groupRecording; if (strstr(_path.c_str(), "{event") || strstr(_condition.c_str(), "{event")) group |= groupChannel; if (strstr(_path.c_str(), "{present") || strstr(_condition.c_str(), "{present")) group |= groupChannel; if (strstr(_path.c_str(), "{following") || strstr(_condition.c_str(), "{following")) group |= groupChannel; return group; } int draw(); }; class cDisplayBackground : public cDisplayImage { public: int groupOf() { return groupUnknown; } int draw(); }; class cDisplayImageFile : public cDisplayItem { public: int groupOf() { return groupReplay; } int draw(); }; class cDisplayCalibrationCursor : public cDisplayItem { public: int groupOf() { return groupCalibrate; } int draw(); }; class cDisplayMenuButton : public cDisplayItem { public: int groupOf() { return groupButton; } int draw(); }; class cDisplayMenuButtonBackground : public cDisplayItem { public: int groupOf() { return groupButton; } int draw(); }; class cDisplayMessage : public cDisplayItem { public: cDisplayMessage() : cDisplayItem() { visible = no; } int groupOf() { return groupMessage; } int isForegroundItem() { return yes; } int draw(); }; class cDisplayMailCount : public cDisplayItem { public: int groupOf() { return groupChannel; } int draw(); }; class cDisplayVolumeMuteSymbol : public cDisplayItem { public: cDisplayVolumeMuteSymbol() : cDisplayItem() { visible = no; } int groupOf() { return groupVolume; } int isForegroundItem() { return yes; } int draw(); }; class cDisplayVolumebar : public cDisplayItem { public: cDisplayVolumebar() : cDisplayItem() { visible = no; } int groupOf() { return groupVolume; } int isForegroundItem() { return yes; } int draw(); }; class cDisplayTimebar : public cDisplayItem { public: int groupOf() { return groupChannel; } int draw(); }; class cDisplayProgressBar : public cDisplayItem { public: int draw(); }; class cDisplaySymbol : public cDisplayItem { public: int groupOf() { return groupChannel; } int draw(); }; class cDisplayMenu : public cDisplayItem { public: int draw(); }; class cDisplayMenuSelected : public cDisplayItem { public: int draw(); }; class cDisplayMenuColumn : public cDisplayItem { public: int groupOf() { return groupMenu; } int draw(); }; class cDisplayMenuColumnSelected : public cDisplayItem { public: int groupOf() { return groupMenu; } int draw(); }; class cDisplayMenuEventColumn : public cDisplayItem { public: int groupOf() { return groupMenu; } int draw(); }; class cDisplayMenuEventColumnSelected : public cDisplayItem { public: int groupOf() { return groupMenu; } int draw(); }; class cDisplayPartingLine : public cDisplayItem { public: int draw() { return cDisplayItem::draw(); } }; class cDisplaySpectrumAnalyzer : public cDisplayItem { public: int draw(); }; class cDisplaySysinfo : public cDisplayItem { public: int draw(); protected: int lastCpuLoad; unsigned long lastUsedMem; unsigned long lastUsedDisk; }; //*************************************************************************** // Lists //*************************************************************************** //*************************************************************************** // Class cThemeItems //*************************************************************************** class cDisplayItems : public cList { public: cDisplayItem* getItem(int id); protected: }; //*************************************************************************** // Class cThemeSection // - represents a section of a theme //*************************************************************************** class cThemeSection : public cListObject, cThemeService { public: cThemeSection(string aName = "unnamed") { name = aName; defaultsItem = 0; } ~cThemeSection() { if (defaultsItem) delete defaultsItem; } string getName() { return name; } cDisplayItems* getItems() { return &items; } cDisplayItem* getItem(int itemId) { return items.getItem(itemId); } cDisplayItem* First() { return items.First(); } cDisplayItem* Next(cDisplayItem* item) { return items.Next(item); } void Ins(cDisplayItem* item, cDisplayItem* before = 0) { items.Ins(item, before); item->setSection(this); } void Add(cDisplayItem* item, cDisplayItem* after = 0) { items.Add(item, after); } cDisplayItem* getDefaultsItem() { return defaultsItem; } void setDefaultsItem(cDisplayItem* item) { if (defaultsItem) delete defaultsItem; defaultsItem = item; } int lookupVar(string name, string& value) { value = ""; map::iterator iter = variables.find(name); if (iter != variables.end()) { value = iter->second.c_str(); return success; } return fail; } uint64_t getNextUpdateTime(); int reset(); int updateGroup(int group); map variables; protected: string name; cDisplayItems items; cDisplayItem* defaultsItem; // Item holding default values }; //*************************************************************************** // Class cThemeSections // - holding all sections //*************************************************************************** class cThemeSections : public cList { public: cThemeSection* getSection(string name); protected: }; //*************************************************************************** // Class cGraphTFTTheme // - holding all Items included in the theme configuration file //*************************************************************************** class cGraphTFTTheme : public cConfig, public cListObject, cThemeService { public: cGraphTFTTheme(); virtual ~cGraphTFTTheme() { exit(); } // functions int init(); int exit(); int check(const char* theVersion); int load(const char* path); int checkViewMode(); // get string getName() { return name; } string getThemeVersion() { return themeVersion; } string getSyntaxVersion() { return syntaxVersion; } string getDir() { return dir; } string getStartImage() { return startImage; } string getEndImage() { return endImage; } int getWidth() { return width; } int getHeight() { return height; } string getFontPath() { return fontPath; } int isInitialized() { return initialized; } // set void setName(string aValue) { name = aValue; } void setThemeVersion(string aValue) { themeVersion = aValue; } void setSyntaxVersion(string aValue) { syntaxVersion = aValue; } void setDir(string aValue) { dir = aValue; } void setStartImage(string aValue) { startImage = aValue; } void setEndImage(string aValue) { endImage = aValue; } void setWidth(int aValue) { width = aValue; } void setHeight(int aValue) { height = aValue; } void setFontPath(string aValue) { fontPath = aValue; } void AddMapItem(cDisplayItem* item, cDisplayItem* after = 0) { mapSection.Add(item, after); } // void addNormalSection(string section); int isNormalMode(const char* modeName); const char* nextNormalMode(const char* modeName); const char* prevNormalMode(const char* modeName); char** getNormalSections() { return normalModes; } int getNormalSectionsCount() { return normalModesCount; } // the sections cThemeSection* getSection(string name) { return sections.getSection(name); } cThemeSections* getSections() { return §ions; } cThemeSection* FirstSection() { return sections.First(); } cThemeSection* NextSection(cThemeSection* sect) { return sections.Next(sect); } string getPathFromImageMap(const char* name); void resetDefines() { defineCount = 0; clearIfdefs();} void clearIfdefs() { while (!skipContent.empty()) skipContent.pop(); } int isSkipContent() { return !skipContent.empty() && skipContent.top(); } int lookupVar(string name, string& value) { value = ""; map::iterator iter; iter = menuVariables.find(name); if (iter != menuVariables.end()) { value = iter->second.c_str(); return success; } iter = variables.find(name); if (iter != variables.end()) { value = iter->second.c_str(); return success; } return fail; } // data string defines[100]; int defineCount; std::stack skipContent; map variables; map menuVariables; protected: // data int width; int height; string dir; string name; string themeVersion; string syntaxVersion; string startImage; string endImage; string fontPath; int initialized; cThemeSections sections; cThemeSection mapSection; char* normalModes[100]; int normalModesCount; }; //*************************************************************************** // Class cGraphTFTThemes // - holding all themes //*************************************************************************** class cGraphTFTThemes : public cList { public: cGraphTFTTheme* getTheme(string aTheme); static cGraphTFTTheme* theTheme; protected: }; //*************************************************************************** // //*************************************************************************** typedef cGraphTFTThemes Thms; //*************************************************************************** // External //*************************************************************************** extern cGraphTFTThemes themes; //*************************************************************************** #endif //__GTFT_THEME_H