diff options
-rw-r--r-- | src/gui/itempopup.cpp | 4 | ||||
-rw-r--r-- | src/gui/popup.cpp | 33 | ||||
-rw-r--r-- | src/gui/popup.h | 35 | ||||
-rw-r--r-- | src/gui/popupmenu.cpp | 4 | ||||
-rw-r--r-- | src/gui/skin.cpp | 53 | ||||
-rw-r--r-- | src/gui/skin.h | 11 | ||||
-rw-r--r-- | src/gui/speechbubble.cpp | 2 | ||||
-rw-r--r-- | src/gui/window.cpp | 12 | ||||
-rw-r--r-- | src/gui/window.h | 46 |
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 |