remove game state classes

scripting improvements
This commit is contained in:
Eduardo Bart
2011-04-22 10:49:46 -03:00
parent a3901b0251
commit e611734396
32 changed files with 428 additions and 435 deletions

View File

@@ -33,8 +33,8 @@ void UIButton::onInputEvent(const InputEvent& event)
} else if(event.type == EV_MOUSE_LUP && m_state == UI::ButtonDown) {
m_state = UI::ButtonUp;
if(getRect().contains(event.mousePos)) {
if(m_buttonClickCallback) {
g_dispatcher.addTask(m_buttonClickCallback);
if(m_onClickCallback) {
g_dispatcher.addTask(boost::bind(m_onClickCallback, boost::static_pointer_cast<UIButton>(shared_from_this())));
}
}
}

View File

@@ -29,8 +29,13 @@
#include <ui/uielement.h>
#include <graphics/borderedimage.h>
class UIButton;
typedef boost::shared_ptr<UIButton> UIButtonPtr;
class UIButton : public UIElement
{
typedef boost::function<void(UIButtonPtr)> OnClick;
public:
UIButton() :
UIElement(UI::Button),
@@ -43,16 +48,14 @@ public:
UI::EButtonState getState() { return m_state; }
void setOnClick(const Callback& callback) { m_buttonClickCallback = callback; }
void setOnClick(const OnClick& callback) { m_onClickCallback = callback; }
virtual const char *getScriptableName() const { return "UIButton"; }
private:
std::string m_text;
UI::EButtonState m_state;
Callback m_buttonClickCallback;
OnClick m_onClickCallback;
};
typedef boost::shared_ptr<UIButton> UIButtonPtr;
#endif // UIBUTTON_H

View File

@@ -25,6 +25,7 @@
#include <prerequisites.h>
#include <core/resources.h>
#include <ui/uicontainer.h>
#include <core/dispatcher.h>
UIContainerPtr rootContainer(new UIContainer);
@@ -71,6 +72,15 @@ UIElementPtr UIContainer::getChildById(const std::string& id)
return UIElementPtr();
}
UIElementPtr UIContainer::getChildByPos(const Point& pos)
{
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
if((*it)->getRect().contains(pos))
return (*it);
}
return UIElementPtr();
}
UIElementPtr UIContainer::recursiveGetChildById(const std::string& id)
{
if(getId() == id)
@@ -93,6 +103,21 @@ UIElementPtr UIContainer::recursiveGetChildById(const std::string& id)
return UIElementPtr();
}
void UIContainer::pushChildToTop(const UIElementPtr& child)
{
bool removed = false;
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
if((*it) == child) {
removed = true;
m_children.erase(it);
break;
}
}
if(removed) {
m_children.push_back(child);
}
}
void UIContainer::render()
{
UIElement::render();
@@ -119,9 +144,10 @@ void UIContainer::onInputEvent(const InputEvent& event)
}
// mouse events
} else if(event.type & EV_MOUSE) {
// mouse down and wheel events only go to elements that contains the mouse position and are not containers
if((event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) && !child->asUIContainer()) {
if(child->getRect().contains(event.mousePos)) {
// mouse down and wheel events only go to elements that contains the mouse position
if(event.type & EV_DOWN || event.type & EV_MOUSE_WHEEL) {
// the child must contains the mouse position and be on top
if(child->getRect().contains(event.mousePos) && child == getChildByPos(event.mousePos)) {
// focus it
if(event.type == EV_MOUSE_LDOWN && child->isFocusable())
setFocusedElement(child);
@@ -171,9 +197,17 @@ void UIContainer::setFocusedElement(UIElementPtr focusedElement)
m_focusedElement->setFocused(false);
m_focusedElement->onFocusChange();
}
m_focusedElement = focusedElement;
m_focusedElement->setFocused(true);
m_focusedElement->onFocusChange();
if(m_focusedElement) {
m_focusedElement->setFocused(true);
m_focusedElement->onFocusChange();
}
}
// when containers are focused they go to the top
if(focusedElement && focusedElement->asUIContainer()) {
g_dispatcher.addTask(boost::bind(&UIContainer::pushChildToTop, asUIContainer(), m_focusedElement));
}
}

View File

@@ -44,8 +44,14 @@ public:
void removeChild(UIElementPtr child);
/// Find an element in this container by id
UIElementPtr getChildById(const std::string& id);
/// Find an element by position
UIElementPtr getChildByPos(const Point& pos);
/// Find an element in this container and in its children by id
UIElementPtr recursiveGetChildById(const std::string& id);
/// Pushs a child to the top
void pushChildToTop(const UIElementPtr& child);
int getChildCount() const { return m_children.size(); }
/// Disable all children except the specified element
bool lockElement(UIElementPtr element);

View File

@@ -42,12 +42,21 @@ UIElement::UIElement(UI::EElementType type) :
void UIElement::destroy()
{
// we must always have a parent when destroying
assert(getParent());
// we cant delete now, as this call maybe in a event loop
g_dispatcher.addTask(boost::bind(&UIContainer::removeChild, getParent(), asUIContainer()));
// shared ptr must have 4 refs, (this + removeChild callback + parent + use_count call)
assert(asUIElement().use_count() == 4);
setVisible(false);
setEnabled(false);
if(getParent()) {
// schedule removal from parent
g_dispatcher.addTask(boost::bind(&UIContainer::removeChild, getParent(), asUIElement()));
}
// schedule internal destroy (used to check for leaks)
g_dispatcher.addTask(boost::bind(&UIElement::internalDestroy, asUIElement()));
}
void UIElement::internalDestroy()
{
// check for leaks, the number of references must be always 2 here
assert(asUIElement().use_count() == 2);
}
void UIElement::setSkin(const UIElementSkinPtr& skin)

View File

@@ -89,6 +89,8 @@ public:
friend class UIContainer;
private:
void internalDestroy();
UI::EElementType m_type;
UIContainerWeakPtr m_parent;
UIElementSkinPtr m_skin;

View File

@@ -50,6 +50,8 @@ void UIElementSkin::draw(UIElement *element)
ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
{
ImagePtr image;
TexturePtr texture;
if(node.FindValue("bordered image")) {
const YAML::Node& child = node["bordered image"];
Rect left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, center;
@@ -72,7 +74,6 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
if(child.FindValue("center"))
child["center"] >> center;
TexturePtr texture;
if(child.FindValue("image")) {
std::string textureName;
child["image"] >> textureName;
@@ -81,17 +82,34 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
texture = g_uiSkins.getDefaultTexture();
}
image = ImagePtr(new BorderedImage(texture,
left,
right,
top,
bottom,
topLeft,
topRight,
bottomLeft,
bottomRight,
center));
if(texture) {
image = ImagePtr(new BorderedImage(texture,
left,
right,
top,
bottom,
topLeft,
topRight,
bottomLeft,
bottomRight,
center));
}
} else if(node.FindValue("image")) {
std::string textureName;
node["image"] >> textureName;
texture = g_textures.get(textureName);
if(texture) {
image = ImagePtr(new Image(texture));
}
}
if(texture && node.FindValue("antialised")){
bool antialised;
node["antialised"] >> antialised;
if(antialised)
texture->enableBilinearFilter();
}
return image;
}

View File

@@ -37,6 +37,7 @@ public:
UIElementSkin(const std::string& name, UI::EElementType elementType) :
m_name(name),
m_elementType(elementType) { }
UIElementSkin() : m_elementType(UI::Element) { }
virtual ~UIElementSkin() { }
/// Load the skin from a YAML node

View File

@@ -133,8 +133,8 @@ void UILayout::recalculateLayout()
m_rect.moveVerticalCenter(m_anchors[ANCHOR_VERTICAL_CENTER].getPos() + m_marginTop - m_marginBottom);
} else {
if(m_anchors[ANCHOR_TOP].isValid() && m_anchors[ANCHOR_BOTTOM].isValid()) {
m_rect.setLeft(m_anchors[ANCHOR_TOP].getPos() + m_marginTop);
m_rect.setRight(m_anchors[ANCHOR_BOTTOM].getPos() - m_marginBottom);
m_rect.setTop(m_anchors[ANCHOR_TOP].getPos() + m_marginTop);
m_rect.setBottom(m_anchors[ANCHOR_BOTTOM].getPos() - m_marginBottom);
} else if(m_anchors[ANCHOR_TOP].isValid()) {
m_rect.moveTop(m_anchors[ANCHOR_TOP].getPos() + m_marginTop);
} else if(m_anchors[ANCHOR_BOTTOM].isValid()) {

View File

@@ -67,7 +67,7 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
{
std::string fileContents = g_resources.loadTextFile(file);
if(!fileContents.size()) {
logFatal("Could not load ui file \"%s", file.c_str());
logError("Could not load ui file \"%s", file.c_str());
return UIElementPtr();
}
@@ -101,7 +101,7 @@ UIElementPtr UILoader::loadFile(const std::string& file, const UIContainerPtr& p
return element;
} catch (YAML::Exception& e) {
logFatal("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
logError("Failed to load ui file \"%s\":\n %s", file.c_str(), e.what());
}
return UIElementPtr();
@@ -168,9 +168,15 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
}
// set element skin
if(node.FindValue("skin"))
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), node["skin"]));
else // apply default skin
if(node.FindValue("skin")) {
if(node["skin"].GetType() == YAML::CT_SCALAR) {
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), node["skin"]));
} else {
UIElementSkinPtr skin = UIElementSkinPtr(new UIElementSkin());
skin->load(node["skin"]);
element->setSkin(skin);
}
} else // apply default skin
element->setSkin(g_uiSkins.getElementSkin(element->getElementType(), "default"));
// load elements common proprieties
@@ -252,6 +258,8 @@ void UILoader::loadElementAnchor(const UIElementPtr& element, EAnchorType type,
UILayoutPtr relativeElement;
if(relativeElementId == "parent" && element->getParent()) {
relativeElement = element->getParent()->asUILayout();
} else if(relativeElementId == "root") {
relativeElement = UIContainer::getRootContainer();
} else {
UIElementPtr tmp = element->backwardsGetElementById(relativeElementId);
if(tmp)
@@ -277,6 +285,8 @@ void UILoader::loadButton(const UIButtonPtr& button, const YAML::Node& node)
g_lua.pushClassInstance(button);
g_lua.pushFunction(funcRef);
g_lua.lua_UIButton_setOnClick();
} else {
throw YAML::Exception(node["onClick"].GetMark(), "failed to parse lua script");
}
}
}

View File

@@ -42,6 +42,8 @@ public:
virtual const char *getScriptableName() const { return "UIWindow"; }
virtual bool isFocusable() const { return true; }
private:
std::string m_title;
bool m_moving;