ede/pekwm/Theme.hh

397 lines
13 KiB
C++

//
// Theme.hh for pekwm
// Copyright © 2003-2009 Claes Nästén <me@pekdon.net>
//
// 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 <string>
#include <map>
//! @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<ActionEvent>::iterator begin(void) {
return _ae_list.begin();
}
//! @brief Return iterator to the last+1 ActionEvent.
inline std::list<ActionEvent>::iterator end(void) {
return _ae_list.end();
}
virtual bool load(CfgParser::Entry *section);
virtual void unload(void);
virtual void check(void);
private:
std::list<ActionEvent> _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<Theme::PDecorButtonData*>::iterator buttonBegin(void) {
return _button_list.begin();
}
//! @brief Return iterator to the last+1 Theme::PDecorButtonData.
inline std::list<Theme::PDecorButtonData*>::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<Theme::PDecorButtonData*> _button_list;
static std::map<FocusedState, std::string> _fs_map;
static std::map<BorderPosition, std::string> _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<std::string, Theme::PDecorData*>::const_iterator decor_begin(void) { return _pdecordata_map.begin(); }
inline std::map<std::string, Theme::PDecorData*>::const_iterator decor_end(void) { return _pdecordata_map.end(); }
/**
* Find PDecorData based on name.
*/
Theme::PDecorData *getPDecorData(const std::string &name) {
std::map<std::string, Theme::PDecorData*>::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<std::string, Theme::ThemeData*> _section_data_map; /**< Map between section names and data. */
std::string _theme_dir; /**< Path to theme directory. */
std::map <std::string, time_t> _cfg_state; /**< Map of file mtime for all files touched by a configuration. */
bool _is_loaded;
// gc
GC _invert_gc;
// frame decors
std::map<std::string, Theme::PDecorData*> _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_