add horizontal box layout, enter keypress fix

This commit is contained in:
Eduardo Bart 2012-01-15 11:57:42 -02:00
parent 8bc879d295
commit a238111c07
13 changed files with 269 additions and 27 deletions

View File

@ -189,6 +189,8 @@ SET(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgettext.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgetbasestyle.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uilineedit.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiboxlayout.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uihorizontallayout.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiverticallayout.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uigridlayout.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uianchorlayout.cpp

View File

@ -270,16 +270,38 @@ void Application::registerLuaFunctions()
// UILayout
g_lua.registerClass<UILayout>();
g_lua.bindClassMemberFunction<UILayout>("applyStyle", &UILayout::applyStyle);
g_lua.bindClassMemberFunction<UILayout>("update", &UILayout::update);
g_lua.bindClassMemberFunction<UILayout>("updateLater", &UILayout::updateLater);
g_lua.bindClassMemberFunction<UILayout>("applyStyle", &UILayout::applyStyle);
g_lua.bindClassMemberFunction<UILayout>("addWidget", &UILayout::addWidget);
g_lua.bindClassMemberFunction<UILayout>("removeWidget", &UILayout::removeWidget);
g_lua.bindClassMemberFunction<UILayout>("disableUpdates", &UILayout::disableUpdates);
g_lua.bindClassMemberFunction<UILayout>("enableUpdates", &UILayout::enableUpdates);
g_lua.bindClassMemberFunction<UILayout>("setParent", &UILayout::setParent);
g_lua.bindClassMemberFunction<UILayout>("getParentWidget", &UILayout::getParentWidget);
g_lua.bindClassMemberFunction<UILayout>("isUpdateDisabled", &UILayout::isUpdateDisabled);
g_lua.bindClassMemberFunction<UILayout>("isUpdating", &UILayout::isUpdating);
g_lua.bindClassMemberFunction<UILayout>("asUILayout", &UILayout::asUILayout);
g_lua.bindClassMemberFunction<UILayout>("asUIAnchorLayout", &UILayout::asUIAnchorLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIBoxLayout", &UILayout::asUIBoxLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIHorizontalLayout", &UILayout::asUIHorizontalLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIVerticalLayout", &UILayout::asUIVerticalLayout);
g_lua.bindClassMemberFunction<UILayout>("asUIGridLayout", &UILayout::asUIGridLayout);
// UIBoxLayout
g_lua.registerClass<UIBoxLayout>();
g_lua.bindClassMemberFunction<UIBoxLayout>("setSpacing", &UIBoxLayout::setSpacing);
g_lua.bindClassMemberFunction<UIBoxLayout>("setFitChildren", &UIBoxLayout::setFitChildren);
// UIVerticalLayout
g_lua.registerClass<UIVerticalLayout, UILayout>();
g_lua.bindClassStaticFunction<UIVerticalLayout>("create", [](UIWidgetPtr parent){ return UIVerticalLayoutPtr(new UIVerticalLayout(parent)); } );
g_lua.bindClassMemberFunction<UIVerticalLayout>("setFitParent", &UIVerticalLayout::setFitParent);
g_lua.bindClassMemberFunction<UIVerticalLayout>("setAlignBottom", &UIVerticalLayout::setAlignBottom);
// UIHorizontalLayout
g_lua.registerClass<UIHorizontalLayout, UILayout>();
g_lua.bindClassStaticFunction<UIHorizontalLayout>("create", [](UIWidgetPtr parent){ return UIHorizontalLayoutPtr(new UIHorizontalLayout(parent)); } );
g_lua.bindClassMemberFunction<UIHorizontalLayout>("setAlignRight", &UIHorizontalLayout::setAlignRight);
// UIGridLayout
g_lua.registerClass<UIGridLayout, UILayout>();

View File

@ -647,7 +647,10 @@ void X11Window::poll()
XKeyEvent xkey = event.xkey;
xkey.state = xkey.state & ~(ShiftMask);
len = XLookupString(&xkey, buf, sizeof(buf), &keysym, 0);
if(len > 0 && m_inputEvent.keyText.length() == 0)
if(len > 0 && m_inputEvent.keyText.length() == 0 && keysym != XK_BackSpace &&
keysym != XK_Return &&
keysym != XK_Delete &&
keysym != XK_Escape)
m_inputEvent.keyText = buf;
if(m_keyMap.find(keysym) != m_keyMap.end())

View File

@ -30,6 +30,8 @@ class UIWidget;
class UILineEdit;
class UIFrameCounter;
class UILayout;
class UIBoxLayout;
class UIHorizontalLayout;
class UIVerticalLayout;
class UIGridLayout;
class UIAnchorLayout;
@ -40,6 +42,8 @@ typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr;
typedef std::shared_ptr<UILineEdit> UILineEditPtr;
typedef std::shared_ptr<UIFrameCounter> UIFrameCounterPtr;
typedef std::shared_ptr<UILayout> UILayoutPtr;
typedef std::shared_ptr<UIBoxLayout> UIBoxLayoutPtr;
typedef std::shared_ptr<UIHorizontalLayout> UIHorizontalLayoutPtr;
typedef std::shared_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
typedef std::shared_ptr<UIGridLayout> UIGridLayoutPtr;
typedef std::shared_ptr<UIAnchorLayout> UIAnchorLayoutPtr;

View File

@ -28,6 +28,7 @@
#include "uilineedit.h"
#include "uiframecounter.h"
#include "uilayout.h"
#include "uihorizontallayout.h"
#include "uiverticallayout.h"
#include "uigridlayout.h"
#include "uianchorlayout.h"

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "uiboxlayout.h"
#include "uiwidget.h"
UIBoxLayout::UIBoxLayout(UIWidgetPtr parentWidget) : UILayout(parentWidget)
{
m_spacing = 0;
}
void UIBoxLayout::applyStyle(const OTMLNodePtr& styleNode)
{
UILayout::applyStyle(styleNode);
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "spacing")
setSpacing(node->value<int>());
else if(node->tag() == "fit-children")
setFitChildren(node->value<bool>());
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef UIBOXLAYOUT_H
#define UIBOXLAYOUT_H
#include "uilayout.h"
class UIBoxLayout : public UILayout
{
public:
UIBoxLayout(UIWidgetPtr parentWidget);
void applyStyle(const OTMLNodePtr& styleNode);
void addWidget(const UIWidgetPtr& widget) { update(); }
void removeWidget(const UIWidgetPtr& widget) { update(); }
void setSpacing(int spacing) { m_spacing = spacing; update(); }
void setFitChildren(bool fitParent) { m_fitChildren = fitParent; update(); }
UIBoxLayoutPtr asUIBoxLayout() { return std::static_pointer_cast<UIBoxLayout>(shared_from_this()); }
protected:
Boolean<false> m_fitChildren;
int m_spacing;
};
#endif

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "uihorizontallayout.h"
#include "uiwidget.h"
#include <framework/core/eventdispatcher.h>
void UIHorizontalLayout::applyStyle(const OTMLNodePtr& styleNode)
{
UIBoxLayout::applyStyle(styleNode);
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "align-right")
setAlignRight(node->value<bool>());
}
}
void UIHorizontalLayout::internalUpdate()
{
UIWidgetPtr parentWidget = getParentWidget();
UIWidgetList widgets = parentWidget->getChildren();
if(m_alignRight)
std::reverse(widgets.begin(), widgets.end());
Rect childrenRect = parentWidget->getChildrenRect();
Point pos = (m_alignRight) ? childrenRect.topRight() : childrenRect.topLeft();
int prefferedWidth = 0;
int gap;
for(const UIWidgetPtr& widget : widgets) {
if(!widget->isExplicitlyVisible())
continue;
Size size = widget->getSize();
gap = (m_alignRight) ? -(widget->getMarginRight()+widget->getWidth()) : widget->getMarginLeft();
pos.x += gap;
prefferedWidth += gap;
if(widget->isFixedSize()) {
// center it
pos.y = childrenRect.top() + (childrenRect.height() - (widget->getMarginTop() + widget->getHeight() + widget->getMarginBottom()))/2;
pos.y = std::max(pos.y, parentWidget->getY());
} else {
// expand height
size.setHeight(childrenRect.height() - (widget->getMarginTop() + widget->getMarginBottom()));
pos.y = childrenRect.top() + (childrenRect.height() - size.height())/2;
}
widget->setRect(Rect(pos, size));
gap = (m_alignRight) ? -widget->getMarginLeft() : (widget->getWidth() + widget->getMarginRight());
gap += m_spacing;
pos.x += gap;
prefferedWidth += gap;
}
prefferedWidth -= m_spacing;
prefferedWidth += parentWidget->getPaddingLeft() + parentWidget->getPaddingRight();
if(m_fitChildren && prefferedWidth != parentWidget->getWidth()) {
// must set the preffered width later
g_dispatcher.addEvent([=] {
parentWidget->setWidth(prefferedWidth);
});
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef UIHORIZONTALLAYOUT_H
#define UIHORIZONTALLAYOUT_H
#include "uiboxlayout.h"
class UIHorizontalLayout : public UIBoxLayout
{
public:
UIHorizontalLayout(UIWidgetPtr parentWidget) : UIBoxLayout(parentWidget) { }
void applyStyle(const OTMLNodePtr& styleNode);
void setAlignRight(bool aliginRight) { m_alignRight = aliginRight; update(); }
UIHorizontalLayoutPtr asUIHorizontalLayout() { return std::static_pointer_cast<UIHorizontalLayout>(shared_from_this()); }
protected:
void internalUpdate();
Boolean<false> m_alignRight;
};
#endif

View File

@ -49,6 +49,8 @@ public:
UILayoutPtr asUILayout() { return std::static_pointer_cast<UILayout>(shared_from_this()); }
virtual UIAnchorLayoutPtr asUIAnchorLayout() { return nullptr; }
virtual UIBoxLayoutPtr asUIBoxLayout() { return nullptr; }
virtual UIHorizontalLayoutPtr asUIHorizontalLayout() { return nullptr; }
virtual UIVerticalLayoutPtr asUIVerticalLayout() { return nullptr; }
virtual UIGridLayoutPtr asUIGridLayout() { return nullptr; }

View File

@ -24,23 +24,13 @@
#include "uiwidget.h"
#include <framework/core/eventdispatcher.h>
UIVerticalLayout::UIVerticalLayout(UIWidgetPtr parentWidget)
: UILayout(parentWidget)
{
m_spacing = 0;
}
void UIVerticalLayout::applyStyle(const OTMLNodePtr& styleNode)
{
UILayout::applyStyle(styleNode);
UIBoxLayout::applyStyle(styleNode);
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "align-bottom")
setAlignBottom(node->value<bool>());
else if(node->tag() == "spacing")
setSpacing(node->value<int>());
else if(node->tag() == "fit-parent")
setFitParent(node->value<bool>());
}
}
@ -88,10 +78,10 @@ void UIVerticalLayout::internalUpdate()
prefferedHeight -= m_spacing;
prefferedHeight += parentWidget->getPaddingTop() + parentWidget->getPaddingBottom();
if(m_fitParent && prefferedHeight != parentWidget->getHeight()) {
if(m_fitChildren && prefferedHeight != parentWidget->getHeight()) {
// must set the preffered width later
g_dispatcher.addEvent([=] {
parentWidget->setHeight(prefferedHeight);
});
}
}
}

View File

@ -23,30 +23,23 @@
#ifndef UIVERTICALLAYOUT_H
#define UIVERTICALLAYOUT_H
#include "uilayout.h"
#include "uiboxlayout.h"
class UIVerticalLayout : public UILayout
class UIVerticalLayout : public UIBoxLayout
{
public:
UIVerticalLayout(UIWidgetPtr parentWidget);
UIVerticalLayout(UIWidgetPtr parentWidget) : UIBoxLayout(parentWidget) { }
void applyStyle(const OTMLNodePtr& styleNode);
void addWidget(const UIWidgetPtr& widget) { update(); }
void removeWidget(const UIWidgetPtr& widget) { update(); }
void setAlignBottom(bool aliginBottom) { m_alignBottom = aliginBottom; update(); }
void setSpacing(int spacing) { m_spacing = spacing; update(); }
void setFitParent(bool fitParent) { m_fitParent = fitParent; update(); }
UIVerticalLayoutPtr asUIVerticalLayout() { return std::static_pointer_cast<UIVerticalLayout>(shared_from_this()); }
protected:
void internalUpdate();
private:
Boolean<false> m_alignBottom;
Boolean<false> m_fitParent;
int m_spacing;
};
#endif

View File

@ -21,6 +21,7 @@
*/
#include "uiwidget.h"
#include "uihorizontallayout.h"
#include "uiverticallayout.h"
#include "uigridlayout.h"
#include "uianchorlayout.h"
@ -232,7 +233,9 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
if(!layoutType.empty()) {
UILayoutPtr layout;
if(layoutType == "verticalBox")
if(layoutType == "horizontalBox")
layout = UIHorizontalLayoutPtr(new UIHorizontalLayout(asUIWidget()));
else if(layoutType == "verticalBox")
layout = UIVerticalLayoutPtr(new UIVerticalLayout(asUIWidget()));
else if(layoutType == "grid")
layout = UIGridLayoutPtr(new UIGridLayout(asUIWidget()));