summaryrefslogtreecommitdiff
path: root/src/gui/window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/window.cpp')
-rw-r--r--src/gui/window.cpp246
1 files changed, 211 insertions, 35 deletions
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 55dac5e0..1a6f1ac6 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -18,11 +18,12 @@
* along with The Mana World; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: window.cpp 4207 2008-04-29 09:10:43Z b_lindeijer $
+ * $Id$
*/
#include <algorithm>
#include <climits>
+#include <cassert>
#include <guichan/exception.hpp>
#include <guichan/widgets/icon.hpp>
@@ -43,24 +44,28 @@
#include "../resources/image.h"
#include "../resources/resourcemanager.h"
+#include "../utils/xml.h"
+
ConfigListener *Window::windowConfigListener = 0;
WindowContainer *Window::windowContainer = 0;
int Window::instances = 0;
int Window::mouseResize = 0;
ImageRect Window::border;
Image *Window::closeImage = NULL;
+bool Window::mAlphaChanged = false;
class WindowConfigListener : public ConfigListener
{
void optionChanged(const std::string &)
{
+ Window::mAlphaChanged = true;
for_each(Window::border.grid, Window::border.grid + 9,
std::bind2nd(std::mem_fun(&Image::setAlpha),
config.getValue("guialpha", 0.8)));
}
};
-Window::Window(const std::string& caption, bool modal, Window *parent):
+Window::Window(const std::string& caption, bool modal, Window *parent, const std::string& skin):
gcn::Window(caption),
mGrip(0),
mParent(parent),
@@ -72,7 +77,8 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
mMinWinWidth(100),
mMinWinHeight(40),
mMaxWinWidth(INT_MAX),
- mMaxWinHeight(INT_MAX)
+ mMaxWinHeight(INT_MAX),
+ mSkin(skin)
{
logger->log("Window::Window(\"%s\")", caption.c_str());
@@ -80,23 +86,13 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
throw GCN_EXCEPTION("Window::Window. no windowContainer set");
}
+ // Loads the skin
+ loadSkin(mSkin);
+
+ setGuiAlpha();
+
if (instances == 0)
{
- // Load static resources
- ResourceManager *resman = ResourceManager::getInstance();
- Image *dBorders = resman->getImage("graphics/gui/vscroll_grey.png");
- border.grid[0] = dBorders->getSubImage(0, 0, 4, 4);
- border.grid[1] = dBorders->getSubImage(4, 0, 3, 4);
- border.grid[2] = dBorders->getSubImage(7, 0, 4, 4);
- border.grid[3] = dBorders->getSubImage(0, 4, 4, 10);
- border.grid[4] = resman->getImage("graphics/gui/bg_quad_dis.png");
- border.grid[5] = dBorders->getSubImage(7, 4, 4, 10);
- border.grid[6] = dBorders->getSubImage(0, 15, 4, 4);
- border.grid[7] = dBorders->getSubImage(4, 15, 3, 4);
- border.grid[8] = dBorders->getSubImage(7, 15, 4, 4);
- dBorders->decRef();
- closeImage = resman->getImage("graphics/gui/close_button.png");
-
windowConfigListener = new WindowConfigListener();
// Send GUI alpha changed for initialization
windowConfigListener->optionChanged("guialpha");
@@ -135,14 +131,15 @@ Window::~Window()
const std::string &name = mWindowName;
// Saving X, Y and Width and Height for resizables in the config
- config.setValue(name + "WinX", getX());
- config.setValue(name + "WinY", getY());
- config.setValue(name + "Visible", isVisible());
-
- if (mGrip)
- {
- config.setValue(name + "WinWidth", getWidth());
- config.setValue(name + "WinHeight", getHeight());
+ if (!name.empty()) {
+ config.setValue(name + "WinX", getX());
+ config.setValue(name + "WinY", getY());
+ config.setValue(name + "Visible", isVisible());
+
+ if (mGrip) {
+ config.setValue(name + "WinWidth", getWidth());
+ config.setValue(name + "WinHeight", getHeight());
+ }
}
instances--;
@@ -154,15 +151,11 @@ Window::~Window()
windowConfigListener = NULL;
// Clean up static resources
- delete border.grid[0];
- delete border.grid[1];
- delete border.grid[2];
- delete border.grid[3];
- border.grid[4]->decRef();
- delete border.grid[5];
- delete border.grid[6];
- delete border.grid[7];
- delete border.grid[8];
+ for( int i = 0; i < 9; i++ )
+ {
+ delete border.grid[i];
+ border.grid[i] = NULL;
+ }
closeImage->decRef();
}
@@ -474,6 +467,7 @@ void
Window::loadWindowState()
{
const std::string &name = mWindowName;
+ assert(!name.empty());
setPosition((int) config.getValue(name + "WinX", mDefaultX),
(int) config.getValue(name + "WinY", mDefaultY));
@@ -536,3 +530,185 @@ int Window::getResizeHandles(gcn::MouseEvent &event)
return resizeHandles;
}
+
+void Window::setGuiAlpha()
+{
+ //logger->log("Window::setGuiAlpha: Alpha Value %f", config.getValue("guialpha", 0.8));
+ for(int i = 0; i < 9; i++)
+ {
+ //logger->log("Window::setGuiAlpha: Border Image (%i)", i);
+ border.grid[i]->setAlpha(config.getValue("guialpha", 0.8));
+ }
+
+ mAlphaChanged = false;
+}
+
+void Window::loadSkin(const std::string filename)
+{
+ const std::string windowId = Window::getId();
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ logger->log("Loading Window Skin '%s'.", filename.c_str());
+ logger->log("Loading Window ID '%s'.", windowId.c_str());
+
+
+ if(filename == "")
+ logger->error("Window::loadSkin(): 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();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
+ {
+ logger->error("Widget Skinning error");
+ }
+
+ std::string skinSetImage;
+ skinSetImage = XML::getProperty(rootNode, "image", "");
+ Image *dBorders = NULL;
+ if(skinSetImage != "")
+ {
+ logger->log("Window::loadSkin(): <skinset> defines '%s' as a skin image.", skinSetImage.c_str());
+ dBorders = resman->getImage("graphics/gui/" + skinSetImage);//"graphics/gui/speech_bubble.png");
+ }
+ else
+ {
+ logger->error("Window::loadSkin(): Skinset does not define an image!");
+ }
+
+ //iterate <widget>'s
+ for_each_xml_child_node(widgetNode, rootNode)
+ {
+ if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget"))
+ continue;
+
+ std::string widgetType;
+ widgetType = XML::getProperty(widgetNode, "type", "unknown");
+ if (widgetType == "Window")
+ {
+ // Iterate through <part>'s
+ // LEEOR / TODO:
+ // We need to make provisions to load in a CloseButton image. For now it
+ // can just be hard-coded.
+ for_each_xml_child_node(partNode, widgetNode)
+ {
+ if (!xmlStrEqual(partNode->name, BAD_CAST "part"))
+ {
+ continue;
+ }
+
+ std::string partType;
+ partType = XML::getProperty(partNode, "type", "unknown");
+ // TOP ROW
+ if(partType == "top-left-corner")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+ else if(partType == "top-edge")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+ else if(partType == "top-right-corner")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+
+ // MIDDLE ROW
+ else if(partType == "left-edge")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+ else if(partType == "bg-quad")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+ else if(partType == "right-edge")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+
+ // BOTTOM ROW
+ else if(partType == "bottom-left-corner")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+ else if(partType == "bottom-edge")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+ else if(partType == "bottom-right-corner")
+ {
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height);
+ }
+
+ // Part is of an uknown type.
+ else
+ {
+ logger->log("Window::loadSkin(): Unknown Part Type '%s'", partType.c_str());
+ }
+ }
+ }
+ // Widget is of an uknown type.
+ else
+ {
+ logger->log("Window::loadSkin(): Unknown Widget Type '%s'", widgetType.c_str());
+ }
+ }
+ dBorders->decRef();
+
+ logger->log("Finished loading Window Skin.");
+
+ // Hard-coded for now until we update the above code to look for window buttons.
+ closeImage = resman->getImage("graphics/gui/close_button.png");
+}
+