scripting rework

This commit is contained in:
Eduardo Bart
2011-05-02 19:48:41 -03:00
parent f290b4f89c
commit c052723477
24 changed files with 622 additions and 375 deletions

View File

@@ -33,8 +33,7 @@ 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_onClickCallback)
g_dispatcher.addTask(boost::bind(m_onClickCallback, asUIElement()));
g_dispatcher.addTask(boost::bind(&Scriptable::callLuaTableField, shared_from_this(), "onClick"));
}
}
}

View File

@@ -42,18 +42,15 @@ public:
void onInputEvent(const InputEvent& event);
void setText(const std::string& text) { m_text = text; }
const std::string& getText() const { return m_text; }
std::string getText() const { return m_text; }
UI::EButtonState getState() { return m_state; }
void setOnClick(const UIElementCallback& callback) { m_onClickCallback = callback; }
virtual const char *getScriptableName() const { return "UIButton"; }
private:
std::string m_text;
UI::EButtonState m_state;
UIElementCallback m_onClickCallback;
};
#endif // UIBUTTON_H

View File

@@ -54,13 +54,14 @@ UIContainerPtr& UIContainer::getRoot()
return rootContainer;
}
void UIContainer::addChild(UIElementPtr child)
void UIContainer::addChild(const UIElementPtr& child)
{
m_children.push_back(child);
child->setParent(asUIContainer());
if(child->getParent() != asUIContainer())
child->setParent(asUIContainer());
}
void UIContainer::removeChild(UIElementPtr child)
void UIContainer::removeChild(const UIElementPtr& child)
{
// defocus if needed
if(m_focusedElement == child)
@@ -72,8 +73,16 @@ void UIContainer::removeChild(UIElementPtr child)
// remove from children list
m_children.remove(child);
// child must have this container as parent
child->setParent(UIContainerPtr());
if(child->getParent() == asUIContainer())
child->setParent(UIContainerPtr());
}
bool UIContainer::hasChild(const UIElementPtr& child)
{
auto it = std::find(m_children.begin(), m_children.end(), child);
if(it != m_children.end())
return true;
return false;
}
UIElementPtr UIContainer::getChildById(const std::string& id)
@@ -201,19 +210,15 @@ void UIContainer::focusNextElement()
setFocusedElement(element);
}
void UIContainer::setFocusedElement(UIElementPtr focusedElement)
void UIContainer::setFocusedElement(const UIElementPtr& focusedElement)
{
if(focusedElement != m_focusedElement) {
if(m_focusedElement) {
m_focusedElement->setFocused(false);
if(m_focusedElement)
m_focusedElement->onFocusChange();
}
m_focusedElement = focusedElement;
if(m_focusedElement) {
m_focusedElement->setFocused(true);
if(m_focusedElement)
m_focusedElement->onFocusChange();
}
}
// when containers are focused they go to the top
@@ -222,7 +227,7 @@ void UIContainer::setFocusedElement(UIElementPtr focusedElement)
}
}
bool UIContainer::lockElement(UIElementPtr element)
bool UIContainer::lockElement(const UIElementPtr& element)
{
if(std::find(m_children.begin(), m_children.end(), element) != m_children.end()) {
m_lockedElements.remove(element);
@@ -238,7 +243,7 @@ bool UIContainer::lockElement(UIElementPtr element)
return false;
}
bool UIContainer::unlockElement(UIElementPtr element)
bool UIContainer::unlockElement(const UIElementPtr& element)
{
auto it = std::find(m_lockedElements.begin(), m_lockedElements.end(), element);
if(it != m_lockedElements.end()) {

View File

@@ -40,29 +40,33 @@ public:
virtual void onInputEvent(const InputEvent& event);
/// Add an element, this must never be called from events loops
void addChild(UIElementPtr child);
void addChild(const UIElementPtr& child);
/// Remove an element, this must never be called from events loops
void removeChild(UIElementPtr child);
void removeChild(const UIElementPtr& child);
/// Check if has child
bool hasChild(const 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);
/// Get children
const std::list<UIElementPtr>& getChildren() const { return m_children; }
/// 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);
bool lockElement(const UIElementPtr& element);
/// Renable all children
bool unlockElement(UIElementPtr element);
bool unlockElement(const UIElementPtr& element);
/// Focus next element
void focusNextElement();
/// Focus element
void setFocusedElement(UIElementPtr focusedElement);
void setFocusedElement(const UIElementPtr& focusedElement);
/// Get focused element
UIElementPtr getFocusedElement() const { return m_focusedElement; }

View File

@@ -34,8 +34,7 @@ UIElement::UIElement(UI::EElementType type) :
UILayout(),
m_type(type),
m_visible(true),
m_enabled(true),
m_focused(false)
m_enabled(true)
{
}
@@ -56,8 +55,7 @@ void UIElement::internalOnDestroy()
//logTraceDebug(getId());
UIElementPtr me = asUIElement();
if(m_onDestroyCallback)
m_onDestroyCallback(me);
callLuaTableField("onDestroy");
// remove from parent
if(getParent()) {
@@ -65,7 +63,7 @@ void UIElement::internalOnDestroy()
}
// free script stuff
clearLuaRefs();
releaseLuaTableRef();
g_dispatcher.addTask(boost::bind(&UIElement::internalDestroyCheck, asUIElement()));
}
@@ -90,8 +88,7 @@ void UIElement::setSkin(const UIElementSkinPtr& skin)
void UIElement::onLoad()
{
if(m_onLoadCallback)
g_dispatcher.addTask(boost::bind(m_onLoadCallback, asUIElement()));
g_dispatcher.addTask(boost::bind(&Scriptable::callLuaTableField, shared_from_this(), "onLoad"));
}
void UIElement::render()
@@ -139,3 +136,36 @@ void UIElement::moveTo(Point pos)
}
setRect(newRect);
}
void UIElement::setParent(UIContainerPtr parent)
{
UIElementPtr me = asUIElement();
UIContainerPtr oldParent = m_parent.lock();
m_parent.reset();
if(oldParent && oldParent->hasChild(me)) {
oldParent->removeChild(me);
}
if(parent) {
m_parent = UIContainerWeakPtr(parent);
if(!parent->hasChild(me))
parent->addChild(me);
}
}
bool UIElement::isFocused() const
{
if(UIContainerPtr parent = m_parent.lock())
return (parent->getFocusedElement() == shared_from_this());
return false;
}
void UIElement::setFocused(bool focused)
{
if(UIContainerPtr parent = m_parent.lock()) {
if(focused) {
parent->setFocusedElement(asUIElement());
} else if(parent->getFocusedElement() == asUIElement()) {
parent->setFocusedElement(UIElementPtr());
}
}
}

View File

@@ -67,9 +67,9 @@ public:
void moveTo(Point pos);
void setSkin(const UIElementSkinPtr& skin);
const UIElementSkinPtr& getSkin() const { return m_skin; }
UIElementSkinPtr getSkin() const { return m_skin; }
void setParent(UIContainerPtr parent) { m_parent = parent; }
void setParent(UIContainerPtr parent);
UIContainerPtr getParent() const { return m_parent.lock(); }
void setId(const std::string& id) { m_id = id; }
@@ -78,8 +78,8 @@ public:
void setEnabled(bool enabled) { m_enabled = enabled; }
bool isEnabled() const { return m_enabled; }
void setFocused(bool focused) { m_focused = focused; }
bool isFocused() const { return m_focused; }
void setFocused(bool focused);
bool isFocused() const;
void setVisible(bool visible) { m_visible = visible; }
bool isVisible() const { return m_visible; }
@@ -91,9 +91,6 @@ public:
virtual UIContainerPtr asUIContainer() { return UIContainerPtr(); }
virtual const char *getScriptableName() const { return "UIElement"; }
void setOnDestroy(const UIElementCallback& onDestroyCallback) { m_onDestroyCallback = onDestroyCallback; }
void setOnLoad(const UIElementCallback& onLoadCallback) { m_onLoadCallback = onLoadCallback; }
private:
UI::EElementType m_type;
UIContainerWeakPtr m_parent;
@@ -101,9 +98,6 @@ private:
std::string m_id;
bool m_visible;
bool m_enabled;
bool m_focused;
UIElementCallback m_onLoadCallback;
UIElementCallback m_onDestroyCallback;
};
#endif // UIELEMENT_H

View File

@@ -38,7 +38,7 @@ public:
m_color(Color::white) { }
void setText(const std::string& text);
const std::string& getText() const { return m_text; }
std::string getText() const { return m_text; }
void setAlign(int align) { m_align = align; }
int getAlign() const { return m_align; }

View File

@@ -66,7 +66,7 @@ private:
class UILayout : public Scriptable
{
public:
UILayout() :
UILayout() : Scriptable(),
m_marginLeft(0),
m_marginRight(0),
m_marginTop(0),
@@ -79,7 +79,7 @@ public:
/// Set the layout rect, always absolute position
void setRect(const Rect& rect);
/// Get layout size, it always return the absolute position
const Rect& getRect() const{ return m_rect; }
Rect getRect() const { return m_rect; }
// anchors add methods
bool addAnchor(EAnchorType type, const AnchorLine& anchorLine);

View File

@@ -215,23 +215,17 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
// load events
if(node.FindValue("onLoad")) {
const YAML::Node& cnode = node["onLoad"];
int funcRef = g_lua.loadBufferAsFunction(cnode.Read<std::string>(), element->getId() + ":onLoad");
if(funcRef != LUA_REFNIL) {
g_lua.pushClassInstance(element);
g_lua.pushFunction(funcRef);
lua_UIElement_setOnLoad();
} else
if(g_lua.loadBufferAsFunction(cnode.Read<std::string>(), element->getId() + ":onLoad"))
g_lua.setScriptableField(element, "onLoad");
else
logError(YAML::Exception(cnode.GetMark(), "failed to parse inline lua script").what());
}
if(node.FindValue("onDestroy")) {
const YAML::Node& cnode = node["onDestroy"];
int funcRef = g_lua.loadBufferAsFunction(cnode.Read<std::string>(), element->getId() + ":onDestroy");
if(funcRef != LUA_REFNIL) {
g_lua.pushClassInstance(element);
g_lua.pushFunction(funcRef);
lua_UIElement_setOnDestroy();
} else
if(g_lua.loadBufferAsFunction(cnode.Read<std::string>(), element->getId() + ":onDestroy"))
g_lua.setScriptableField(element, "onDestroy");
else
logError(YAML::Exception(cnode.GetMark(), "failed to parse inline lua script").what());
}
@@ -314,13 +308,9 @@ void UILoader::loadButton(const UIButtonPtr& button, const YAML::Node& node)
// set on click event
if(node.FindValue("onClick")) {
int funcRef = g_lua.loadBufferAsFunction(node["onClick"].Read<std::string>(), button->getId() + ":onClick");
if(funcRef != LUA_REFNIL) {
g_lua.pushClassInstance(button);
g_lua.pushFunction(funcRef);
lua_UIButton_setOnClick();
} else {
if(g_lua.loadBufferAsFunction(node["onClick"].Read<std::string>(), button->getId() + ":onClick"))
g_lua.setScriptableField(button, "onClick");
else
logError(YAML::Exception(node["onClick"].GetMark(), "failed to parse inline lua script").what());
}
}
}

View File

@@ -41,7 +41,7 @@ public:
void onFocusChange();
void setText(const std::string& text);
const std::string& getText() const { return m_textArea.getText(); }
std::string getText() const { return m_textArea.getText(); }
TextArea& getTextArea() { return m_textArea; }
bool isFocusable() const { return true; }

View File

@@ -38,7 +38,7 @@ public:
void onInputEvent(const InputEvent& event);
void setTitle(const std::string& title) { m_title = title; }
const std::string& getTitle() const { return m_title; }
std::string getTitle() const { return m_title; }
virtual const char *getScriptableName() const { return "UIWindow"; }