summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorIra Rice <irarice@gmail.com>2009-03-25 11:31:02 -0600
committerIra Rice <irarice@gmail.com>2009-03-25 11:31:02 -0600
commite0be7afc936c39e2b0e1db84a13653cfd78a6035 (patch)
treef5e99fa2f4f2d7c1c7149bd66e410798ae632735 /src/gui
parentf6e7a477681109aea040456e3f4ebd0f65645ecc (diff)
downloadmana-e0be7afc936c39e2b0e1db84a13653cfd78a6035.tar.gz
mana-e0be7afc936c39e2b0e1db84a13653cfd78a6035.tar.bz2
mana-e0be7afc936c39e2b0e1db84a13653cfd78a6035.tar.xz
mana-e0be7afc936c39e2b0e1db84a13653cfd78a6035.zip
Modified skin loading to save and load a skin's XML path, as well as
modified the skin loading method to take a default value, in case the value in the configuration file fails to load for one reason or another. While this doesn't directly expose skinning on a per window basis to the user at the moment, it does allow people to change what skins get loaded with which windows now without needing to modify the code. TODO: Determine a decent approach to allowing the user to change their window skins in game, as well as moving all widget skin loading to the skin class (for instance, the button skins, progressbar skins, etc.) so that different skin configurations can use different widget skins. Signed-off-by: Ira Rice <irarice@gmail.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/itempopup.cpp4
-rw-r--r--src/gui/popup.cpp33
-rw-r--r--src/gui/popup.h35
-rw-r--r--src/gui/popupmenu.cpp4
-rw-r--r--src/gui/skin.cpp53
-rw-r--r--src/gui/skin.h11
-rw-r--r--src/gui/speechbubble.cpp2
-rw-r--r--src/gui/window.cpp12
-rw-r--r--src/gui/window.h46
9 files changed, 142 insertions, 58 deletions
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
index a4042ae2..2ebe6645 100644
--- a/src/gui/itempopup.cpp
+++ b/src/gui/itempopup.cpp
@@ -39,7 +39,7 @@
#include "../utils/stringutils.h"
ItemPopup::ItemPopup():
- Popup()
+ Popup("ItemPopup")
{
mItemType = "";
@@ -85,6 +85,8 @@ ItemPopup::ItemPopup():
add(mItemDescScroll);
add(mItemEffectScroll);
add(mItemWeightScroll);
+
+ loadPopupConfiguration();
}
ItemPopup::~ItemPopup()
diff --git a/src/gui/popup.cpp b/src/gui/popup.cpp
index d44dbc93..6d57081f 100644
--- a/src/gui/popup.cpp
+++ b/src/gui/popup.cpp
@@ -42,6 +42,7 @@ Popup::Popup(const std::string& name, Window *parent,
const std::string& skin):
mParent(parent),
mPopupName(name),
+ mDefaultSkinPath(skin),
mMinWidth(100),
mMinHeight(40),
mMaxWidth(INT_MAX),
@@ -57,7 +58,7 @@ Popup::Popup(const std::string& name, Window *parent,
instances++;
// Loads the skin
- mSkin = skinLoader->load(skin);
+ mSkin = skinLoader->load(skin, mDefaultSkinPath);
// Add this window to the window container
windowContainer->add(this);
@@ -70,6 +71,8 @@ Popup::~Popup()
{
logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str());
+ savePopupConfiguration();
+
while (!mWidgets.empty())
{
gcn::Widget *w = mWidgets.front();
@@ -87,6 +90,34 @@ void Popup::setWindowContainer(WindowContainer *wc)
windowContainer = wc;
}
+void Popup::loadPopupConfiguration()
+{
+ if (mPopupName.empty())
+ return;
+
+ const std::string &name = mPopupName;
+ const std::string &skinName = config.getValue(name + "Skin",
+ mSkin->getFilePath());
+
+ if (skinName.compare(mSkin->getFilePath()) != 0)
+ {
+ mSkin->instances--;
+ mSkin = skinLoader->load(skinName, mDefaultSkinPath);
+ }
+}
+
+void Popup::savePopupConfiguration()
+{
+ if (mPopupName.empty())
+ return;
+
+ const std::string &name = mPopupName;
+
+ // Saves the skin path in a config file (which allows for skins to be
+ // changed from the default path)
+ config.setValue(name + "Skin", mSkin->getFilePath());
+}
+
void Popup::draw(gcn::Graphics *graphics)
{
if (!isVisible())
diff --git a/src/gui/popup.h b/src/gui/popup.h
index 3e3ff5ad..868f2a2b 100644
--- a/src/gui/popup.h
+++ b/src/gui/popup.h
@@ -67,6 +67,18 @@ class Popup : public gcn::Container
static void setWindowContainer(WindowContainer *windowContainer);
/**
+ * Changes the popup's skin to use the skin defined in the saved
+ * configuration file.
+ */
+ void loadPopupConfiguration();
+
+ /**
+ * Currently only saves the skin used by the popup so that when the
+ * client is reloaded, it can use the saved skin.
+ */
+ void savePopupConfiguration();
+
+ /**
* Draws the popup.
*/
void draw(gcn::Graphics *graphics);
@@ -167,17 +179,18 @@ class Popup : public gcn::Container
virtual gcn::Rectangle getChildrenArea();
private:
- Window *mParent; /**< The parent Window (if there is one) */
- std::string mPopupName; /**< Name of the Popup */
- int mMinWidth; /**< Minimum Popup width */
- int mMinHeight; /**< Minimum Popup height */
- int mMaxWidth; /**< Maximum Popup width */
- int mMaxHeight; /**< Maximum Popup height */
- unsigned int mPadding; /**< Holds the padding of the window. */
-
- static int instances; /**< Number of Popup instances */
-
- Skin* mSkin; /**< Skin in use by this Popup */
+ Window *mParent; /**< The parent Window (if there is one) */
+ std::string mPopupName; /**< Name of the popup */
+ std::string mDefaultSkinPath; /**< Default skin path for this popup */
+ int mMinWidth; /**< Minimum popup width */
+ int mMinHeight; /**< Minimum popup height */
+ int mMaxWidth; /**< Maximum popup width */
+ int mMaxHeight; /**< Maximum popup height */
+ unsigned int mPadding; /**< Holds the padding of the popup. */
+
+ static int instances; /**< Number of popup instances */
+
+ Skin* mSkin; /**< Skin in use by this popup */
};
#endif
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index 02be3055..fd2a0361 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -61,8 +61,10 @@ PopupMenu::PopupMenu():
mBrowserBox->setPosition(4, 4);
mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
mBrowserBox->setOpaque(false);
- add(mBrowserBox);
mBrowserBox->setLinkHandler(this);
+ add(mBrowserBox);
+
+ loadWindowState();
}
void PopupMenu::showPopup(int x, int y, Being *being)
diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp
index ac258175..515ef01b 100644
--- a/src/gui/skin.cpp
+++ b/src/gui/skin.cpp
@@ -31,6 +31,7 @@
#include "../resources/resourcemanager.h"
#include "../utils/dtor.h"
+#include "../utils/strprintf.h"
#include "../utils/xml.h"
SkinLoader* skinLoader = NULL;
@@ -45,8 +46,9 @@ class SkinConfigListener : public ConfigListener
}
};
-Skin::Skin(ImageRect skin, Image* close, std::string name):
+Skin::Skin(ImageRect skin, Image* close, std::string filePath, std::string name):
instances(0),
+ mFilePath(filePath),
mName(name),
border(skin),
closeImage(close)
@@ -86,32 +88,47 @@ unsigned int Skin::getMinHeight()
border.grid[6]->getHeight();
}
-Skin* SkinLoader::load(const std::string &filename)
+Skin* SkinLoader::load(const std::string &filename,
+ const std::string &defaultPath)
{
- SkinIterator skinIterator = mSkins.find(filename);
-
- if (mSkins.end() != skinIterator)
- {
- skinIterator->second->instances++;
- return skinIterator->second;
- }
+ std::string filePath = filename;
ResourceManager *resman = ResourceManager::getInstance();
logger->log("Loading Skin '%s'.", filename.c_str());
- if (filename.empty())
+ if (filename.empty() && defaultPath.empty())
logger->error("SkinLoader::load(): Invalid File Name.");
- // TODO:
- // If there is an error loading the specified file, we should try to revert
- // to a 'default' skin file. Only if the 'default' skin file can't be loaded
- // should we have a terminating error.
- XML::Document doc(filename);
- xmlNodePtr rootNode = doc.rootNode();
+ XML::Document *doc = new XML::Document(filePath);
+ xmlNodePtr rootNode = doc->rootNode();
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
- logger->error("Widget Skinning error");
+ {
+ filePath = defaultPath;
+
+ logger->log("Widget Skinning error. Loading '%s' instead.",
+ filePath.c_str());
+
+ delete doc;
+
+ doc = new XML::Document(filePath);
+ rootNode = doc->rootNode();
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
+ {
+ logger->error(strprintf("Skinning failed. Check this skin file "
+ "to make sure it's valid: %s",
+ filePath.c_str()));
+ }
+ }
+
+ SkinIterator skinIterator = mSkins.find(filePath);
+
+ if (mSkins.end() != skinIterator)
+ {
+ skinIterator->second->instances++;
+ return skinIterator->second;
+ }
std::string skinSetImage;
skinSetImage = XML::getProperty(rootNode, "image", "");
@@ -197,7 +214,7 @@ Skin* SkinLoader::load(const std::string &filename)
// Hard-coded for now until we update the above code to look for window buttons.
Image* closeImage = resman->getImage("graphics/gui/close_button.png");
- Skin* skin = new Skin(border, closeImage);
+ Skin* skin = new Skin(border, closeImage, filename);
mSkins[filename] = skin;
diff --git a/src/gui/skin.h b/src/gui/skin.h
index c90952e3..b7e2c29f 100644
--- a/src/gui/skin.h
+++ b/src/gui/skin.h
@@ -33,7 +33,8 @@ class Image;
class Skin
{
public:
- Skin(ImageRect skin, Image* close, std::string name = "");
+ Skin(ImageRect skin, Image* close, std::string filePath,
+ std::string name = "");
~Skin();
/**
@@ -44,6 +45,11 @@ class Skin
std::string getName() { return mName; }
/**
+ * Returns the skin's xml file path.
+ */
+ std::string getFilePath() { return mFilePath; }
+
+ /**
* Returns the background skin.
*/
ImageRect getBorder() { return border; }
@@ -76,6 +82,7 @@ class Skin
int instances;
private:
+ std::string mFilePath; /**< File name path for the skin */
std::string mName; /**< Name of the skin to use */
ImageRect border; /**< The window border and background */
Image *closeImage; /**< Close Button Image */
@@ -98,7 +105,7 @@ class SkinLoader
/**
* Loads a skin
*/
- Skin* load(const std::string &filename);
+ Skin* load(const std::string &filename, const std::string &defaultPath);
/**
* Updates the alpha values of all of the skins
diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp
index 9e4c9234..ca771fce 100644
--- a/src/gui/speechbubble.cpp
+++ b/src/gui/speechbubble.cpp
@@ -60,6 +60,8 @@ SpeechBubble::SpeechBubble():
add(mCaption);
add(mSpeechArea);
+
+ loadPopupConfiguration();
}
void SpeechBubble::setCaption(const std::string &name, const gcn::Color *color)
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 75820521..642fdeb8 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -48,6 +48,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std
mParent(parent),
mLayout(NULL),
mWindowName("window"),
+ mDefaultSkinPath(skin),
mShowTitle(true),
mModal(modal),
mCloseButton(false),
@@ -74,7 +75,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std
setTitleBarHeight(20);
// Loads the skin
- mSkin = skinLoader->load(skin);
+ mSkin = skinLoader->load(skin, mDefaultSkinPath);
// Add this window to the window container
windowContainer->add(this);
@@ -476,12 +477,20 @@ void Window::mouseDragged(gcn::MouseEvent &event)
void Window::loadWindowState()
{
const std::string &name = mWindowName;
+ const std::string skinName = config.getValue(name + "Skin",
+ mSkin->getFilePath());
assert(!name.empty());
setPosition((int) config.getValue(name + "WinX", mDefaultX),
(int) config.getValue(name + "WinY", mDefaultY));
setVisible((bool) config.getValue(name + "Visible", false));
+ if (skinName.compare(mSkin->getFilePath()) != 0)
+ {
+ mSkin->instances--;
+ mSkin = skinLoader->load(skinName, mDefaultSkinPath);
+ }
+
if (mGrip)
{
int width = (int) config.getValue(name + "WinWidth", mDefaultWidth);
@@ -512,6 +521,7 @@ void Window::saveWindowState()
config.setValue(mWindowName + "WinX", getX());
config.setValue(mWindowName + "WinY", getY());
config.setValue(mWindowName + "Visible", isVisible());
+ config.setValue(mWindowName + "Skin", mSkin->getFilePath());
if (mGrip)
{
diff --git a/src/gui/window.h b/src/gui/window.h
index b0b67ad8..66e73e12 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -320,29 +320,29 @@ class Window : public gcn::Window, gcn::WidgetListener
*/
int getResizeHandles(gcn::MouseEvent &event);
- GCContainer *mChrome; /**< Contained container */
- ResizeGrip *mGrip; /**< Resize grip */
- Window *mParent; /**< The parent window */
- Layout *mLayout; /**< Layout handler */
- std::string mWindowName; /**< Name of the window */
- bool mShowTitle; /**< Window has a title bar */
- bool mModal; /**< Window is modal */
- bool mCloseButton; /**< Window has a close button */
- bool mSticky; /**< Window resists minimization */
- bool mAlphaChanged; /**< Whether the alpha percent was changed */
- int mMinWinWidth; /**< Minimum window width */
- int mMinWinHeight; /**< Minimum window height */
- int mMaxWinWidth; /**< Maximum window width */
- int mMaxWinHeight; /**< Maximum window height */
- int mDefaultX; /**< Default window X position */
- int mDefaultY; /**< Default window Y position */
- int mDefaultWidth; /**< Default window width */
- int mDefaultHeight; /**< Default window height */
-
- static int mouseResize; /**< Active resize handles */
- static int instances; /**< Number of Window instances */
-
- Skin* mSkin; /**< Skin in use by this window */
+ GCContainer *mChrome; /**< Contained container */
+ ResizeGrip *mGrip; /**< Resize grip */
+ Window *mParent; /**< The parent window */
+ Layout *mLayout; /**< Layout handler */
+ std::string mWindowName; /**< Name of the window */
+ std::string mDefaultSkinPath; /**< Default skin path for this window */
+ bool mShowTitle; /**< Window has a title bar */
+ bool mModal; /**< Window is modal */
+ bool mCloseButton; /**< Window has a close button */
+ bool mSticky; /**< Window resists minimization */
+ int mMinWinWidth; /**< Minimum window width */
+ int mMinWinHeight; /**< Minimum window height */
+ int mMaxWinWidth; /**< Maximum window width */
+ int mMaxWinHeight; /**< Maximum window height */
+ int mDefaultX; /**< Default window X position */
+ int mDefaultY; /**< Default window Y position */
+ int mDefaultWidth; /**< Default window width */
+ int mDefaultHeight; /**< Default window height */
+
+ static int mouseResize; /**< Active resize handles */
+ static int instances; /**< Number of Window instances */
+
+ Skin* mSkin; /**< Skin in use by this window */
/**
* The width of the resize border. Is independent of the actual window