ultimatepp/bazaar/Theme/Theme.cpp
cbpporter 1743f45f9b .Bazaat/Theme: Fixed GetTempPath related bug for Windows XP
git-svn-id: svn://ultimatepp.org/upp/trunk@2274 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2010-03-27 12:39:51 +00:00

494 lines
No EOL
17 KiB
C++

#include "Theme.h"
#include <plugin/zip/zip.h>
Value StringToObject(const String& s, const String& file = "") {
Vector<String> v = Split(s, ' ');
if (v.GetCount() == 0)
return Null;
if (v[0] == "png") {
Image im = PNGRaster().LoadFileAny(file);
ImageBuffer img;
img = im;
if (img.IsEmpty())
return Null;
if (v.GetCount() == 6 && v[1] == "hot") {
img.SetHotSpot(Point(StrInt(v[2]), StrInt(v[3])));
img.Set2ndSpot(Point(StrInt(v[4]), StrInt(v[5])));
}
return (Image)img;
}
else if (v[0] == "color")
return Color(StrInt(v[1]), StrInt(v[2]), StrInt(v[3]));
else if (v[0] == "rect")
return Rect(StrInt(v[1]), StrInt(v[2]), StrInt(v[3]), StrInt(v[3]));
else if (v[0] == "null")
return "null";
else
return StrInt(v[0]);
}
inline String GetMap(const VectorMap<String, String>& set, const String& s) {
int k = set.Find(s);
return (k >= 0) ? set[k] : "";
}
String MakePath(const String& folder, const String& cat) {
return folder + DIR_SEP + cat;
}
template <class T>
void SetIfNotNull(T& t, const Value& v) {
if (v.Is<String>() && (String)v == "null")
t = Null;
else
if (!IsNull(v))
t = v;
}
class ThemeHelper {
private:
const VectorMap<String, String>& set;
const String& dir;
const String& file;
public:
ThemeHelper(const VectorMap<String, String>& aset, const String& adir, const String& afile):
set(aset), dir(adir), file(afile) {};
ThemeHelper& operator ()(int& t, const String& s);
ThemeHelper& operator ()(bool& t, const String& s);
ThemeHelper& operator ()(Value& t, const String& s);
ThemeHelper& operator ()(Rect& t, const String& s);
ThemeHelper& operator ()(Point& t, const String& s);
ThemeHelper& operator ()(Color& t, const String& s);
ThemeHelper& operator ()(Size& t, const String& s);
template <typename T>
ThemeHelper& operator ()(T v[], String val, int count);
};
ThemeHelper& ThemeHelper::operator()(int& t, const String& s) {
Value v = StringToObject(GetMap(set, s));
if (!v.IsNull() && v.Is<int>())
t = v;
return *this;
}
ThemeHelper& ThemeHelper::operator()(bool& t, const String& s) {
Value v = StringToObject(GetMap(set, s));
if (!v.IsNull() && v.Is<int>())
t = v;
return *this;
}
template <typename T>
ThemeHelper& ThemeHelper::operator ()(T v[], String val, int count) {
String nv = ToLower(val);
String all = GetMap(set, nv + "[]");
Vector<String> ret;
ret.SetCount(count, "");
if (!all.IsEmpty())
for (int i = 0; i < count; i++)
ret[i] = all;
for (int i = 0; i < count; i++) {
String temp = GetMap(set, nv + "[" + IntStr(i) + "]");
if (!temp.IsEmpty())
ret[i] = temp;
}
for (int i = 0; i < count; i++)
SetIfNotNull(v[i], StringToObject(ret[i], MakePath(dir, file + val + IntStr(i)+ ".png")));
return *this;
}
ThemeHelper& ThemeHelper::operator ()(Value& t, const String& s) {
String nw = ToLower(s);
Value v = StringToObject(GetMap(set, nw), MakePath(dir, file + s + ".png"));
if (v.Is<String>() && (String)v == "null")
t = Null;
else
if (!IsNull(v))
t = v;
return *this;
}
ThemeHelper& ThemeHelper::operator ()(Rect& t, const String& s) {
Value v = StringToObject(GetMap(set, s));
if (!v.IsNull() && v.Is<Rect>())
t = v;
return *this;
}
ThemeHelper& ThemeHelper::operator ()(Point& t, const String& s) {
Value v = StringToObject(GetMap(set, s));
if (!v.IsNull() && v.Is<Point>())
t = v;
return *this;
}
ThemeHelper& ThemeHelper::operator ()(Color& t, const String& s) {
Value v = StringToObject(GetMap(set, s));
if (!v.IsNull() && v.Is<Color>())
t = v;
return *this;
}
ThemeHelper& ThemeHelper::operator ()(Size& t, const String& s) {
Value v = StringToObject(GetMap(set, s));
if (!v.IsNull() && v.Is<Size>())
t = v;
return *this;
}
inline void SetChImg(int i, const Image& img)
{
if (!img.IsEmpty())
CtrlsImg::Set(i, img);
}
Vector<String> Theme::Fill(const VectorMap<String, String>& set, String val, int count) {
String all = GetMap(set, val + "[]");
Vector<String> ret;
ret.SetCount(count, "");
if (!all.IsEmpty())
for (int i = 0; i < count; i++)
ret[i] = all;
for (int i = 0; i < count; i++) {
String temp = GetMap(set, val + "[" + IntStr(i) + "]");
if (!temp.IsEmpty())
ret[i] = temp;
}
return ret;
}
void Theme::LoadButton(Button::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file)
{
ThemeHelper(set, dir, file)
(d.focusmargin, "focusmargin")
(d.look, "Look", 4)
(d.monocolor, "monocolor", 4)
(d.overpaint, "overpaint")
(d.pressoffset, "pressoffset")
(d.textcolor, "textcolor", 4)
(d.transparent, "transparent")
;
}
void Theme::LoadScrollBar(ScrollBar::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.hlower, "HLower", 4)
(d.hthumb, "HThumb", 4)
(d.hupper, "HUpper", 4)
(d.vlower, "VLower", 4)
(d.vthumb, "VThumb", 4)
(d.vupper, "VUpper", 4)
;
}
void Theme::LoadOption0(const VectorMap<String, String>& set, const String& dir, const String& file) {
Vector<String> look = Fill(set, "look");
SetChImg(CtrlsImg::I_O0, StringToObject(look[0], dir + DIR_SEP + file + IntStr(0)+ ".png"));
SetChImg(CtrlsImg::I_O0h, StringToObject(look[1], dir + DIR_SEP + file + IntStr(1)+ ".png"));
SetChImg(CtrlsImg::I_O0p, StringToObject(look[2], dir + DIR_SEP + file + IntStr(2)+ ".png"));
SetChImg(CtrlsImg::I_O0d, StringToObject(look[3], dir + DIR_SEP + file + IntStr(3)+ ".png"));
}
void Theme::LoadOption1(const VectorMap<String, String>& set, const String& dir, const String& file) {
Vector<String> look = Fill(set, "look");
SetChImg(CtrlsImg::I_O1, StringToObject(look[0], dir + DIR_SEP + file + IntStr(0)+ ".png"));
SetChImg(CtrlsImg::I_O1h, StringToObject(look[1], dir + DIR_SEP + file + IntStr(1)+ ".png"));
SetChImg(CtrlsImg::I_O1p, StringToObject(look[2], dir + DIR_SEP + file + IntStr(2)+ ".png"));
SetChImg(CtrlsImg::I_O1d, StringToObject(look[3], dir + DIR_SEP + file + IntStr(3)+ ".png"));
}
void Theme::LoadOption2(const VectorMap<String, String>& set, const String& dir, const String& file) {
Vector<String> look = Fill(set, "look");
SetChImg(CtrlsImg::I_O2, StringToObject(look[0], dir + DIR_SEP + file + IntStr(0)+ ".png"));
SetChImg(CtrlsImg::I_O2h, StringToObject(look[1], dir + DIR_SEP + file + IntStr(1)+ ".png"));
SetChImg(CtrlsImg::I_O2p, StringToObject(look[2], dir + DIR_SEP + file + IntStr(2)+ ".png"));
SetChImg(CtrlsImg::I_O2d, StringToObject(look[3], dir + DIR_SEP + file + IntStr(3)+ ".png"));
}
void Theme::LoadSwitch0(const VectorMap<String, String>& set, const String& dir, const String& file) {
Vector<String> look = Fill(set, "look");
SetChImg(CtrlsImg::I_S0, StringToObject(look[0], dir + DIR_SEP + file + IntStr(0)+ ".png"));
SetChImg(CtrlsImg::I_S0h, StringToObject(look[1], dir + DIR_SEP + file + IntStr(1)+ ".png"));
SetChImg(CtrlsImg::I_S0p, StringToObject(look[2], dir + DIR_SEP + file + IntStr(2)+ ".png"));
SetChImg(CtrlsImg::I_S0d, StringToObject(look[3], dir + DIR_SEP + file + IntStr(3)+ ".png"));
}
void Theme::LoadSwitch1(const VectorMap<String, String>& set, const String& dir, const String& file) {
Vector<String> look = Fill(set, "look");
SetChImg(CtrlsImg::I_S1, StringToObject(look[0], dir + DIR_SEP + file + IntStr(0)+ ".png"));
SetChImg(CtrlsImg::I_S1h, StringToObject(look[1], dir + DIR_SEP + file + IntStr(1)+ ".png"));
SetChImg(CtrlsImg::I_S1p, StringToObject(look[2], dir + DIR_SEP + file + IntStr(2)+ ".png"));
SetChImg(CtrlsImg::I_S1d, StringToObject(look[3], dir + DIR_SEP + file + IntStr(3)+ ".png"));
}
void Theme::LoadToolBar(ToolBar::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.arealook, "AreaLook")
(d.look, "Look")
;
}
void Theme::LoadToolButton(ToolButton::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.contrast, "contrast", 6)
(d.light, "light", 6)
(d.look, "Look", 6)
(d.offset, "offset", 6)
(d.textcolor, "textcolor", 6)
;
ToolBar::StyleDefault().Write().buttonstyle = d;
}
void Theme::LoadMenuBar(MenuBar::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.arealook, "AreaLook")
(d.item, "Item")
(d.itemtext, "itemtext")
(d.leftgap, "leftgap")
(d.look, "Look")
(d.lsepm, "lsepm")
(d.maxiconsize, "maxiconsize")
(d.popupbody, "PopupBody")
(d.popupframe, "PopupFrame")
(d.popupiconbar, "PopupIconBar")
(d.pullshift, "pullshift")
(d.rsepm, "rsepm")
(d.textgap, "textgap")
(d.topbar, "TopBar")
(d.topitem, "TopItem", 3)
(d.topitemtext, "topitemtext", 3)
(d.separator.l1, "separatorl1")
(d.separator.l2, "separatorl2")
;
}
void Theme::LoadEditField(EditField::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.activeedge, "activeedge")
(d.disabled, "disabled")
(d.edge, "Edge", 4)
(d.focus, "focus")
(d.invalid, "invalid")
(d.paper, "paper")
(d.selected, "selected")
(d.selectedtext, "selectedtext")
(d.text, "text")
(d.textdisabled, "textdisabled")
;
}
void Theme::LoadMultiButton(MultiButton::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.activeedge, "activeedge")
(d.border, "border")
(d.edge, "Edge", 4)
(d.fmonocolor, "fmonocolor", 4)
(d.left, "Left", 4)
(d.lmiddle, "LMiddle", 4)
(d.loff, "loff")
(d.look, "Look", 4)
(d.margin, "margin")
(d.monocolor, "monocolor", 4)
(d.overpaint, "overpaint")
(d.pressoffset, "pressoffset")
(d.right, "Right", 4)
(d.rmiddle, "RMiddle", 4)
(d.roff, "roff")
(d.trivial, "Trivial", 4)
(d.trivialborder, "trivialborder")
(d.trivialsep, "trivialsep")
(d.usetrivial, "usetrivial")
;
}
void Theme::LoadTabCtrl(TabCtrl::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.body, "Body")
(d.both, "Both", 4)
(d.edge, "edge")
(d.extendleft, "extendleft")
(d.first, "First", 4)
(d.last, "Last", 4)
(d.margin, "margin")
(d.normal, "Normal", 4)
(d.sel, "sel")
//tabheight
(d.text_color, "text_color", 4)
;
}
void Theme::LoadProgress(ProgressIndicator::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.bound, "bound")
(d.classic, "classic")
(d.hchunk, "HChunk")
(d.hlook, "HLook")
(d.vchunk, "VChunk")
(d.vlook, "VLook")
;
}
void Theme::LoadHeader(HeaderCtrl::Style& d, const VectorMap<String, String>& set, const String& dir, const String& file) {
ThemeHelper(set, dir, file)
(d.gridadjustment, "gridadjustment")
(d.look, "Look", 4)
(d.pressoffset, "pressoffset")
;
}
Theme& Theme::Load(const String& path) {
ini.Clear();
if (DirectoryExists(path) && FileExists(AppendFileName(path, "theme.ini"))) {
folder = path;
ini.Load(AppendFileName(folder, "theme.ini"));
return *this;
}
if (FileExists(path)) {
#ifdef PLATFORM_WIN32
WString temp = FromUtf8(GetTempPath());
WStringBuffer b(MAX_PATH);
GetLongPathNameW(temp, b, MAX_PATH);
b.Strlen();
String outdir = ToUtf8((WString)b);
#else
String outdir = GetTempPath();
#endif
outdir = AppendFileName(outdir, "UppTheme" + Uuid::Create().ToString() + "\\");
RealizeDirectory(outdir);
FileUnZip unzip(path);
while(unzip) {
String fn = AppendFileName(outdir, unzip.GetPath());
if(unzip.IsFolder()) {
RealizeDirectory(fn);
unzip.SkipFile();
}
else {
RealizePath(fn);
FileOut out(fn);
unzip.ReadFile(out);
}
}
folder = outdir;
ini.Load(AppendFileName(outdir, "theme.ini"));
return *this;
}
return *this;
}
int Theme::GetGroup(const String& group) {
for (int i = 0; i < ini.GetGroupCount(); i++)
if (ToLower(ini.GetGroupName(i)) == group)
return i;
return -1;
}
Theme& Theme::Apply() {
for (int i = 0; i < ini.GetGroupCount(); i++) {
String group = ToLower(ini.GetGroupName(i));
VectorMap<String, String> set;
for (int k = 0; k < ini.GetKeyCount(i); k++) {
set.Add(ini.GetKey(i, k), ini.Get(i, k));
}
if (group == "button" && useButton)
LoadButton(Button::StyleNormal().Write(), set, MakePath(folder, "Button"), "Button");
else if (group == "okbutton" && useOkButton)
LoadButton(Button::StyleOk().Write(), set, MakePath(folder, "OkButton"), "OkButton");
else if (group == "edgebutton" && useEdgeButton)
LoadButton(Button::StyleEdge().Write(), set, MakePath(folder, "EdgeButton"), "EdgeButton");
else if (group == "leftedgebutton" && useLEdgeButton)
LoadButton(Button::StyleLeftEdge().Write(), set, MakePath(folder, "LeftEdgeButton"), "LeftEdgeButton");
else if (group == "option0" && useOption)
LoadOption0(set, MakePath(folder, "Option"), "Option0");
else if (group == "option1" && useOption)
LoadOption1(set, MakePath(folder, "Option"), "Option1");
else if (group == "option2" && useOption)
LoadOption2(set, MakePath(folder, "Option"), "Option2");
else if (group == "switch0" && useSwitch)
LoadSwitch0(set, MakePath(folder, "Switch"), "Switch0");
else if (group == "switch1" && useSwitch)
LoadSwitch1(set, MakePath(folder, "Switch"), "Switch1");
else if (group == "spininc" && useOption)
LoadButton(SpinButtons::StyleDefault().Write().inc, set, MakePath(folder, "Spin"), "SpinInc");
else if (group == "spindec")
LoadButton(SpinButtons::StyleDefault().Write().dec, set, MakePath(folder, "Spin"), "SpinDec");
else if (group == "scrollupbutton")
LoadButton(ScrollBar::StyleDefault().Write().up, set, MakePath(folder, "ScrollBar"), "ScrollUpButton");
else if (group == "scrolldownbutton")
LoadButton(ScrollBar::StyleDefault().Write().down, set, MakePath(folder, "ScrollBar"), "ScrollDownButton");
else if (group == "scrollleftbutton")
LoadButton(ScrollBar::StyleDefault().Write().left, set, MakePath(folder, "ScrollBar"), "ScrollLeftButton");
else if (group == "scrollrightbutton")
LoadButton(ScrollBar::StyleDefault().Write().right, set, MakePath(folder, "ScrollBar"), "ScrollRightButton");
else if (group == "scrollbar")
LoadScrollBar(ScrollBar::StyleDefault().Write(), set, MakePath(folder, "ScrollBar"), "Scroll");
else if (group == "toolbutton")
LoadToolButton(ToolButton::StyleDefault().Write(), set, MakePath(folder, "ToolButton"), "ToolButton");
else if (group == "menubar")
LoadMenuBar(MenuBar::StyleDefault().Write(), set, MakePath(folder, "MenuBar"), "Menu");
else if (group == "toolbar")
LoadToolBar(ToolBar::StyleDefault().Write(), set, MakePath(folder, "ToolBar"), "ToolBar");
else if (group == "editfield")
LoadEditField(EditField::StyleDefault().Write(), set, MakePath(folder, "EditField"), "EditField");
else if (group == "viewedge") {
Value edge;
ThemeHelper(set, MakePath(folder, "ViewEdge"), "ViewEdge")
(edge, "Edge")
;
ViewEdge_Write(edge);
}
else if (group == "dropchoice" && useDropC)
LoadMultiButton(DropChoice::StyleFrame().Write(), set, MakePath(folder, "DropChoice"), "DropChoice");
else if (group == "droplist" && useDropL)
LoadMultiButton(DropList::StyleDefault().Write(), set, MakePath(folder, "DropList"), "DropList");
else if (group == "tabctrl" && useTab)
LoadTabCtrl(TabCtrl::StyleDefault().Write(), set, MakePath(folder, "TabCtrl"), "Tab");
else if (group == "progress" && useProgress)
LoadProgress(ProgressIndicator::StyleDefault().Write(), set, MakePath(folder, "Progress"), "Progress");
else if (group == "headerctrl" && useHeader)
LoadHeader(HeaderCtrl::StyleDefault().Write(), set, MakePath(folder, "HeaderCtrl"), "Header");
else if (group == "colors") {
String cf = GetMap(set, "colorface");
if (!cf.IsEmpty())
SColorFace_Write(StringToObject(cf));
String cs = GetMap(set, "colorshadow");
if (!cs.IsEmpty())
SColorShadow_Write(StringToObject(cs));
String cl = GetMap(set, "colorlight");
if (!cl.IsEmpty())
SColorLight_Write(StringToObject(cl));
String cm = GetMap(set, "colormark");
if (!cm.IsEmpty())
SColorMark_Write(StringToObject(cm));
String cd = GetMap(set, "colordissabled");
if (!cd.IsEmpty())
SColorDisabled_Write(StringToObject(cd));
}
}
return *this;
}