// // Theme.hh for pekwm // Copyright © 2003-2009 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifndef _THEME_HH_ #define _THEME_HH_ #ifdef HAVE_CONFIG_H #include "config.h" #endif // HAVE_CONFIG_H #include "pekwm.hh" #include "CfgParser.hh" #include "Action.hh" // ActionEvent #include "PFont.hh" // PFont::Color #include "ParseUtil.hh" class PScreen; class PTexture; class Button; class ButtonData; class ImageHandler; #include #include //! @brief Theme data parser and container. class Theme { public: /** * Base class for all theme data objects, provides interface for * loading and un-loading of decoration data. */ class ThemeData { public: virtual ~ThemeData() {} virtual bool load(CfgParser::Entry *section) = 0; virtual void unload(void) = 0; virtual void check(void) = 0; }; //! @brief Theme data parser and container for PDecor::Button class PDecorButtonData : public ThemeData { public: PDecorButtonData(void); virtual ~PDecorButtonData(void); //! @brief Returns wheter the button is positioned relative to the left title edge. inline bool isLeft(void) const { return _left; } //! @brief Returns width of button. inline uint getWidth(void) const { return _width; } //! @brief Returns height of button. inline uint getHeight(void) const { return _height; } //! @brief Returns PTexture used in ButtonState state. inline PTexture *getTexture(ButtonState state) { return _texture[(state != BUTTON_STATE_NO) ? state : 0]; } //! @brief Returns iterator to the first ActionEvent. inline std::list::iterator begin(void) { return _ae_list.begin(); } //! @brief Return iterator to the last+1 ActionEvent. inline std::list::iterator end(void) { return _ae_list.end(); } virtual bool load(CfgParser::Entry *section); virtual void unload(void); virtual void check(void); private: std::list _ae_list; PTexture *_texture[BUTTON_STATE_NO]; bool _left; uint _width, _height; }; //! @brief PDecor theme data container and parser. class PDecorData : public ThemeData { public: PDecorData(const char *name=0); virtual ~PDecorData(void); //! @brief Returns decor name. inline const std::string &getName(void) const { return _name; } //! @brief Sets decor name. inline void setName(const std::string &name) { _name = name; } //! @brief Returns title height. inline int getTitleHeight(void) const { return _title_height; } //! @brief Returns title minimum width (0 for full width title). inline int getTitleWidthMin(void) const { return _title_width_min; } //! @brief Returns title maximum width in procent. inline int getTitleWidthMax(void) const { return _title_width_max; } //! @brief Returns title text pad for dir. inline int getPad(PadType pad) const { return _pad[(pad != PAD_NO) ? pad : 0]; } //! @brief Returns wheter all items in the title have same width. inline bool isTitleWidthSymetric(void) const { return _title_width_symetric; } //! @brief Returns wheter titlebar height should be relative the font height inline bool isTitleHeightAdapt(void) const { return _title_height_adapt; } // Title textures //! @brief Returns background PTexture used in FocusedState state. inline PTexture *getTextureMain(FocusedState state) { return _texture_main[(state < FOCUSED_STATE_FOCUSED_SELECTED) ? state : 0]; } //! @brief Returns tab PTexture used in FocusedState state. inline PTexture *getTextureTab(FocusedState state) { return _texture_tab[(state != FOCUSED_STATE_NO) ? state : 0]; } //! @brief Returns separator PTexture used in FocusedState state. inline PTexture *getTextureSeparator(FocusedState state) { return _texture_separator[(state < FOCUSED_STATE_FOCUSED_SELECTED) ? state : 0]; } // font //! @brief Returns PFont used in FocusedState state. inline PFont *getFont(FocusedState state) const { return _font[((state == FOCUSED_STATE_NO) || ! _font[state]) ? FOCUSED_STATE_FOCUSED : state]; } //! @brief Return PFont::Color used in FocusedState state. inline PFont::Color *getFontColor(FocusedState state) { return _font_color[(state != FOCUSED_STATE_NO) ? state : 0]; } // border //! @brief Return border PTexture used in FocusedState state for pos. inline PTexture *getBorderTexture(FocusedState state, BorderPosition pos) { return _texture_border[(state < FOCUSED_STATE_FOCUSED_SELECTED) ? state : 0][pos]; } // button //! @brief Return iterator to the first Theme::PDecorButtonData. inline std::list::iterator buttonBegin(void) { return _button_list.begin(); } //! @brief Return iterator to the last+1 Theme::PDecorButtonData. inline std::list::iterator buttonEnd(void) { return _button_list.end(); } virtual bool load(CfgParser::Entry *section); virtual void unload(void); virtual void check(void); private: void loadBorder(CfgParser::Entry *cs); void loadButtons(CfgParser::Entry *cs); void checkTextures(void); void checkFonts(void); void checkBorder(void); void checkColors(void); private: std::string _name; // size, padding etc int _title_height; int _title_width_min, _title_width_max; int _pad[PAD_NO]; bool _title_width_symetric; bool _title_height_adapt; // title PTexture *_texture_main[FOCUSED_STATE_FOCUSED_SELECTED]; PTexture *_texture_tab[FOCUSED_STATE_NO]; PTexture *_texture_separator[FOCUSED_STATE_FOCUSED_SELECTED]; // font PFont *_font[FOCUSED_STATE_NO]; PFont::Color *_font_color[FOCUSED_STATE_NO]; // border PTexture *_texture_border[FOCUSED_STATE_FOCUSED_SELECTED][BORDER_NO_POS]; // buttons std::list _button_list; static std::map _fs_map; static std::map _border_map; }; //! @brief PMenu theme data container and parser. class PMenuData : public ThemeData { public: PMenuData(void); virtual ~PMenuData(void); //! @brief Returns PFont used in ObjectState state. inline PFont *getFont(ObjectState state) { return _font[state]; } //! @brief Returns PFont::Color used in ObjectState state. inline PFont::Color *getColor(ObjectState state) { return _color[state]; } //! @brief Returns menu PTexture used in ObjectState state. inline PTexture *getTextureMenu(ObjectState state) { return _tex_menu[state]; } //! @brief Returns item PTexture used in ObjectState state. inline PTexture *getTextureItem(ObjectState state) { return _tex_item[state]; } //! @brief Returns arrow PTexture used in ObjectState state. inline PTexture *getTextureArrow(ObjectState state) { return _tex_arrow[state]; } //! @brief Returns separator PTexture used in ObjectState state. inline PTexture *getTextureSeparator(ObjectState state) { return _tex_sep[(state < OBJECT_STATE_SELECTED) ? state : OBJECT_STATE_FOCUSED]; } //! @brief Returns text pad in PadType dir. inline uint getPad(PadType dir) const { return _pad[(dir != PAD_NO) ? dir : 0]; } virtual bool load(CfgParser::Entry *section); virtual void unload(void); virtual void check(void); private: void loadState(CfgParser::Entry *cs, ObjectState state); private: PFont *_font[OBJECT_STATE_NO + 1]; PFont::Color *_color[OBJECT_STATE_NO + 1]; PTexture *_tex_menu[OBJECT_STATE_NO + 1]; PTexture *_tex_item[OBJECT_STATE_NO + 1]; PTexture *_tex_arrow[OBJECT_STATE_NO + 1]; PTexture *_tex_sep[OBJECT_STATE_NO]; uint _pad[PAD_NO]; }; //! @brief CmdDialog/StatusWindow theme data container and parser. class TextDialogData : public ThemeData { public: TextDialogData(void); virtual ~TextDialogData(void); //! @brief Returns PFont. inline PFont *getFont(void) { return _font; } //! @brief Returns PFont::Color. inline PFont::Color *getColor(void) { return _color; } //! @brief Returns background texture. inline PTexture *getTexture(void) { return _tex; } //! @brief Returns text pad in PadType dir. inline uint getPad(PadType dir) const { return _pad[(dir != PAD_NO) ? dir : 0]; } virtual bool load(CfgParser::Entry *section); virtual void unload(void); virtual void check(void); private: PFont *_font; PFont::Color *_color; PTexture *_tex; uint _pad[PAD_NO]; }; /** * Class holding WorkspaceIndicator theme data. */ class WorkspaceIndicatorData : public ThemeData { public: WorkspaceIndicatorData(void); virtual ~WorkspaceIndicatorData(void); virtual bool load(CfgParser::Entry *section); virtual void unload(void); virtual void check(void); public: PFont *font; PFont::Color *font_color; PTexture *texture_background; PTexture *texture_workspace; PTexture *texture_workspace_act; int edge_padding; int workspace_padding; }; /** * Class holding harbour theme data. */ class HarbourData : public ThemeData { public: HarbourData(void); virtual ~HarbourData(void); inline PTexture *getTexture(void) const { return _texture; } virtual bool load(CfgParser::Entry *section); virtual void unload(void); virtual void check(void); private: PTexture *_texture; /**< Texture for rendering dockapps in the harbour. */ }; inline Theme::HarbourData *getHarbourData(void) { return &_harbour_data; } Theme(PScreen *scr); ~Theme(void); bool load(const std::string &dir); void unload(void); inline const GC &getInvertGC(void) const { return _invert_gc; } inline std::map::const_iterator decor_begin(void) { return _pdecordata_map.begin(); } inline std::map::const_iterator decor_end(void) { return _pdecordata_map.end(); } /** * Find PDecorData based on name. */ Theme::PDecorData *getPDecorData(const std::string &name) { std::map::iterator it = _pdecordata_map.begin(); for (; it != _pdecordata_map.end(); ++it) { if (strcasecmp(it->first.c_str(), name.c_str()) == 0) { return it->second; } } // Backwards compatibility, CMDDIALOG was used instead of // INPUTDIALOG previously. if (strcasecmp("INPUTDIALOG", name.c_str()) == 0) { return getPDecorData("CMDDIALOG"); } return 0; } Theme::WorkspaceIndicatorData &getWorkspaceIndicatorData(void) { return _workspace_indicator_data; } // menu inline Theme::PMenuData *getMenuData(void) { return &_menu_data; } // status/cmd inline Theme::TextDialogData *getStatusData(void) { return &_status_data; } inline Theme::TextDialogData *getCmdDialogData(void) { return &_cmd_d_data; } private: void loadThemeRequire(CfgParser &theme_cfg, std::string &file); private: PScreen *_scr; ImageHandler *_image_handler; std::map _section_data_map; /**< Map between section names and data. */ std::string _theme_dir; /**< Path to theme directory. */ std::map _cfg_state; /**< Map of file mtime for all files touched by a configuration. */ bool _is_loaded; // gc GC _invert_gc; // frame decors std::map _pdecordata_map; // menu Theme::PMenuData _menu_data; HarbourData _harbour_data; /**< Data for styling harbour. */ // status window TextDialogData _status_data, _cmd_d_data; WorkspaceIndicatorData _workspace_indicator_data; }; #endif // _THEME_HH_