aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Theme.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/Theme.cc')
-rw-r--r--src/FbTk/Theme.cc207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/FbTk/Theme.cc b/src/FbTk/Theme.cc
new file mode 100644
index 0000000..59e9817
--- /dev/null
+++ b/src/FbTk/Theme.cc
@@ -0,0 +1,207 @@
1// Theme.cc for FbTk - Fluxbox ToolKit
2// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: Theme.cc,v 1.21 2003/11/16 22:33:55 rathnor Exp $
23
24#include "Theme.hh"
25
26#include "XrmDatabaseHelper.hh"
27#include "App.hh"
28#include "StringUtil.hh"
29#include "ThemeItems.hh"
30#include "Directory.hh"
31
32#include <cstdio>
33#include <memory>
34#include <iostream>
35
36using namespace std;
37
38namespace FbTk {
39
40Theme::Theme(int screen_num):m_screen_num(screen_num) {
41 ThemeManager::instance().registerTheme(*this);
42}
43
44Theme::~Theme() {
45 ThemeManager::instance().unregisterTheme(*this);
46}
47
48ThemeManager &ThemeManager::instance() {
49 static ThemeManager tm;
50 return tm;
51}
52
53ThemeManager::ThemeManager():
54 m_max_screens(ScreenCount(FbTk::App::instance()->display())),
55 m_verbose(false),
56 m_themelocation("") {
57
58}
59
60bool ThemeManager::registerTheme(Theme &tm) {
61 // valid screen num?
62 if (m_max_screens < tm.screenNum() || tm.screenNum() < 0)
63 return false;
64 // TODO: use find and return false if it's already there
65 // instead of unique
66 m_themelist.push_back(&tm);
67 m_themelist.unique();
68 return true;
69}
70
71bool ThemeManager::unregisterTheme(Theme &tm) {
72 m_themelist.remove(&tm);
73 return true;
74}
75
76bool ThemeManager::load(const std::string &filename) {
77 std::string location = FbTk::StringUtil::expandFilename(filename).c_str();
78 std::string prefix = "";
79
80 if (Directory::isDirectory(filename)) {
81 prefix = location;
82
83 location.append("/theme.cfg");
84 if (!Directory::isRegularFile(location)) {
85 cerr<<"Error loading theme file "<<location<<": not a regular file"<<endl;
86 return false;
87 }
88 } else {
89 // dirname
90 prefix = location.substr(0, location.find_last_of('/'));
91 }
92
93 if (!m_database.load(location.c_str()))
94 return false;
95
96 // relies on the fact that load_rc clears search paths each time
97 if (m_themelocation != "") {
98 Image::removeSearchPath(m_themelocation);
99 m_themelocation.append("/pixmaps");
100 Image::removeSearchPath(m_themelocation);
101 }
102
103 m_themelocation = prefix;
104
105 location = prefix;
106 Image::addSearchPath(location);
107 location.append("/pixmaps");
108 Image::addSearchPath(location);
109
110 //get list and go throu all the resources and load them
111 ThemeList::iterator theme_it = m_themelist.begin();
112 const ThemeList::iterator theme_it_end = m_themelist.end();
113 for (; theme_it != theme_it_end; ++theme_it) {
114 loadTheme(**theme_it);
115 }
116 // notify all themes that we reconfigured
117 theme_it = m_themelist.begin();
118 for (; theme_it != theme_it_end; ++theme_it) {
119 // send reconfiguration signal to theme and listeners
120 (*theme_it)->reconfigTheme();
121 (*theme_it)->reconfigSig().notify();
122 }
123 return true;
124}
125
126void ThemeManager::loadTheme(Theme &tm) {
127 std::list<ThemeItem_base *>::iterator i = tm.itemList().begin();
128 std::list<ThemeItem_base *>::iterator i_end = tm.itemList().end();
129 for (; i != i_end; ++i) {
130 ThemeItem_base *resource = *i;
131 if (!loadItem(*resource)) {
132 // try fallback resource in theme
133 if (!tm.fallback(*resource)) {
134 if (verbose())
135 cerr<<"Failed to read theme item: "<<resource->name()<<endl;
136 resource->setDefaultValue();
137 }
138 }
139 }
140 // send reconfiguration signal to theme and listeners
141}
142
143bool ThemeManager::loadItem(ThemeItem_base &resource) {
144 return loadItem(resource, resource.name(), resource.altName());
145}
146
147/// handles resource item loading with specific name/altname
148bool ThemeManager::loadItem(ThemeItem_base &resource, const std::string &name, const std::string &alt_name) {
149 XrmValue value;
150 char *value_type;
151
152 if (XrmGetResource(*m_database, name.c_str(),
153 alt_name.c_str(), &value_type, &value)) {
154 resource.setFromString(value.addr);
155 resource.load(); // load additional stuff by the ThemeItem
156 } else
157 return false;
158
159 return true;
160}
161
162std::string ThemeManager::resourceValue(const std::string &name, const std::string &altname) {
163 XrmValue value;
164 char *value_type;
165
166 if (*m_database != 0 && XrmGetResource(*m_database, name.c_str(),
167 altname.c_str(), &value_type, &value) && value.addr != 0) {
168 return string(value.addr);
169 }
170 return "";
171}
172
173/*
174void ThemeManager::listItems() {
175 ThemeList::iterator it = m_themelist.begin();
176 ThemeList::iterator it_end = m_themelist.end();
177 for (; it != it_end; ++it) {
178 std::list<ThemeItem_base *>::iterator item = (*it)->itemList().begin();
179 std::list<ThemeItem_base *>::iterator item_end = (*it)->itemList().end();
180 for (; item != item_end; ++item) {
181
182 if (typeid(**item) == typeid(ThemeItem<Texture>)) {
183 cerr<<(*item)->name()<<": <texture type>"<<endl;
184 cerr<<(*item)->name()<<".pixmap: <filename>"<<endl;
185 cerr<<(*item)->name()<<".color: <color>"<<endl;
186 cerr<<(*item)->name()<<".colorTo: <color>"<<endl;
187 } else if (typeid(**item) == typeid(ThemeItem<Color>)) {
188 cerr<<(*item)->name()<<": <color>"<<endl;
189 } else if (typeid(**item) == typeid(ThemeItem<int>)) {
190 cerr<<(*item)->name()<<": <integer>"<<endl;
191 } else if (typeid(**item) == typeid(ThemeItem<bool>)) {
192 cerr<<(*item)->name()<<": <boolean>"<<endl;
193 } else if (typeid(**item) == typeid(ThemeItem<PixmapWithMask>)) {
194 cerr<<(*item)->name()<<": <filename>"<<endl;
195 } else if (typeid(**item) == typeid(ThemeItem<std::string>)) {
196 cerr<<(*item)->name()<<": <string>"<<endl;
197 } else if (typeid(**item) == typeid(ThemeItem<Font>)) {
198 cerr<<(*item)->name()<<": <font>"<<endl;
199 } else {
200 cerr<<(*item)->name()<<":"<<endl;
201 }
202 }
203 }
204
205}
206*/
207}; // end namespace FbTk