move UIWindow to lua

This commit is contained in:
Eduardo Bart 2012-01-10 21:13:38 -02:00
parent a1374baee1
commit 8ad88c4070
23 changed files with 57 additions and 254 deletions

8
TODO
View File

@ -24,28 +24,22 @@
== UI == UI
[bart] fix massive hotkeys when holding down a key [bart] fix massive hotkeys when holding down a key
[bart] tab widgets [bart] tab widgets
[bart] add anchors API
[bart] scrollbar [bart] scrollbar
[bart] scrollable widgets [bart] scrollable widgets
[bart] grid layout [bart] grid layout
[bart] horizontal box layout [bart] horizontal box layout
[bart] move layout proprieties to widget style [bart] move layout proprieties to widget style
[bart] move UICheckBox to lua
[bart] move UIWindow to lua
[bart] multiline text editor widget [bart] multiline text editor widget
[bart] multiline rich text widget [bart] multiline rich text widget
[bart] create UIMessageBox, UIToolTip and UIInputBox [bart] create UIMessageBox, UIToolTip and UIInputBox
[bart] rework UI image style
[bart] class UIImage and UIText
[bart] add UI border
[bart] fix style inheretance using a style translator [bart] fix style inheretance using a style translator
[bart] find a way to add new widgets without focusing them [bart] find a way to add new widgets without focusing them
[bart] fix moving windows and tooltips conflicts [bart] fix moving windows and tooltips conflicts
[bart] break UILabel lines [bart] break UILabel lines
[bart] review and make more error prone with more warnings [bart] review and make more error prone with more warnings
[bart] a real working border and background property in otui
[bart] reapply anchor styles when adding new childs [bart] reapply anchor styles when adding new childs
[bart] ui text selection [bart] ui text selection
[bart] implement ui window moving policies
break window anchors when moving break window anchors when moving

View File

@ -1,6 +1,6 @@
MainWindow MainWindow
id: about id: about
title: Info text: Info
size: 244 221 size: 244 221
FlatPanel FlatPanel

View File

@ -10,8 +10,10 @@ local function onCharactersWindowKeyPress(self, keyCode, keyText, keyboardModifi
if keyboardModifiers == KeyboardNoModifier then if keyboardModifiers == KeyboardNoModifier then
if keyCode == KeyUp or keyCode == KeyTab then if keyCode == KeyUp or keyCode == KeyTab then
characterList:focusPreviousChild(ActiveFocusReason) characterList:focusPreviousChild(ActiveFocusReason)
return true
elseif keyCode == KeyDown then elseif keyCode == KeyDown then
characterList:focusNextChild(ActiveFocusReason) characterList:focusNextChild(ActiveFocusReason)
return true
end end
end end
return false return false
@ -59,7 +61,7 @@ function CharacterList.create(characters, premDays)
charactersWindow = displayUI('characterlist.otui') charactersWindow = displayUI('characterlist.otui')
characterList = charactersWindow:getChildById('characterList') characterList = charactersWindow:getChildById('characterList')
local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel') local accountStatusLabel = charactersWindow:getChildById('accountStatusLabel')
charactersWindow.onKeyPress = onCharactersWindowKeyPress connect(charactersWindow, {onKeyPress = onCharactersWindowKeyPress })
local focusLabel local focusLabel
for i,characterInfo in ipairs(characters) do for i,characterInfo in ipairs(characters) do

View File

@ -10,7 +10,7 @@ CharacterListLabel < Label
MainWindow MainWindow
id: charactersWindow id: charactersWindow
title: Character List text: Character List
size: 250 248 size: 250 248
@onEnter: CharacterList.doLogin() @onEnter: CharacterList.doLogin()
@onEscape: CharacterList.destroy() @onEscape: CharacterList.destroy()
@ -23,6 +23,8 @@ MainWindow
margin-bottom: 5 margin-bottom: 5
margin-left: 16 margin-left: 16
margin-right: 16 margin-right: 16
padding: 1
focusable: false
Label Label
id: accountStatusLabel id: accountStatusLabel

View File

@ -1,6 +1,6 @@
MainWindow MainWindow
id: enterGame id: enterGame
title: Enter Game text: Enter Game
size: 236 240 size: 236 240
@onEnter: EnterGame.doLogin() @onEnter: EnterGame.doLogin()
@onEscape: EnterGame.hide() @onEscape: EnterGame.hide()

View File

@ -18,7 +18,7 @@ OptionCheckBox < CheckBox
MainWindow MainWindow
id: optionsWindow id: optionsWindow
title: Options text: Options
size: 286 280 size: 286 280
@onEnter: Options.hide() @onEnter: Options.hide()
@onEscape: Options.hide() @onEscape: Options.hide()

View File

@ -99,6 +99,21 @@ function tonumber(v)
return oldtonumber(v) return oldtonumber(v)
end end
function signalcall(param, ...)
if type(param) == 'function' then
return param(...)
elseif type(param) == 'table' then
for k,v in pairs(param) do
if param(...) then
return true
end
end
elseif func ~= nil then
error('attempt to call a non function value')
end
return false
end
function runscript(file) function runscript(file)
g_lua.runScript(resolvepath(file, 2)) g_lua.runScript(resolvepath(file, 2))
end end

View File

@ -3,16 +3,16 @@ Window < UIWindow
size: 200 200 size: 200 200
opacity: 1 opacity: 1
color: white color: white
head-height: 20 text-offset: 0 2
head-text-align: center text-align: top
move-policy: free move-policy: free
stackable: true stackable: true
image-source: /core_styles/images/window.png image-source: /core_styles/images/window.png
image-border: 4 image-border: 4
image-border-top: 20 image-border-top: 20
$pressed: //$pressed:
opacity: 0.75 // opacity: 0.75
$disabled: $disabled:
color: #aaaaaa88 color: #aaaaaa88
@ -20,8 +20,8 @@ Window < UIWindow
MiniWindow < UIWindow MiniWindow < UIWindow
font: verdana-11px-antialised font: verdana-11px-antialised
size: 192 200 size: 192 200
head-height: 25 text-offset: 0 5
head-text-align: center text-align: top
margin-top: 10 margin-top: 10
margin-left: 6 margin-left: 6
margin-right: 6 margin-right: 6

View File

@ -12,5 +12,6 @@ Module
require 'uicombobox' require 'uicombobox'
require 'uiprogressbar' require 'uiprogressbar'
require 'uipopupmenu' require 'uipopupmenu'
require 'uiwindow'
require 'tooltip/tooltip' require 'tooltip/tooltip'
require 'messagebox/messagebox' require 'messagebox/messagebox'

View File

@ -10,8 +10,9 @@ function MessageBox.create(title, text, flags)
setmetatable(box, MessageBox) setmetatable(box, MessageBox)
-- create messagebox window -- create messagebox window
local window = displayUI('messagebox.otui', { locked = true }) local window = displayUI('messagebox.otui')
window:setTitle(title) window:lock()
window:setText(title)
local label = window:getChildById('messageBoxLabel') local label = window:getChildById('messageBoxLabel')
label:setText(text) label:setText(text)

View File

@ -0,0 +1,17 @@
UIWindow = extends(UIWidget)
function UIWindow.create()
local window = UIWindow.internalCreate()
window:setTextAlign(AlignTopCenter)
return window
end
function UIWindow:onKeyPress(keyCode, keyText, keyboardModifiers)
if keyboardModifiers == KeyboardNoModifier then
if keyCode == KeyReturn or keyCode == KeyEnter then
signalcall(self.onEnter, self)
elseif keyCode == KeyEscape then
signalcall(self.onEscape, self)
end
end
end

View File

@ -3,7 +3,7 @@ Color < ColorBox
anchors.left: head.right anchors.left: head.right
Window Window
title: Select Outfit text: Select Outfit
size: 550 280 size: 550 280
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter

View File

@ -34,7 +34,7 @@ SkillPercentPanel < ProgressBar
MiniWindow MiniWindow
id: skillWindow id: skillWindow
title: Skills text: Skills
size: 200 310 size: 200 310
Panel Panel

View File

@ -1,6 +1,6 @@
MainWindow MainWindow
size: 256 128 size: 256 128
title: Add to VIP list text: Add to VIP list
@onEnter: VipList.addVip() @onEnter: VipList.addVip()
@onEscape: VipList.destroyAddWindow() @onEscape: VipList.destroyAddWindow()

View File

@ -6,7 +6,7 @@ VipListLabel < GameLabel
MiniWindow MiniWindow
id: vipWindow id: vipWindow
title: VIP List text: VIP List
UIWidget UIWidget
id: vipList id: vipList

View File

@ -189,7 +189,6 @@ SET(framework_SOURCES ${framework_SOURCES}
${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgettext.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgettext.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgetbasestyle.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiwidgetbasestyle.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uilineedit.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uilineedit.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiwindow.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uianchorlayout.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uianchorlayout.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uiverticallayout.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uiverticallayout.cpp
${CMAKE_CURRENT_LIST_DIR}/ui/uilayout.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/uilayout.cpp

View File

@ -307,12 +307,6 @@ void Application::registerLuaFunctions()
g_lua.bindClassMemberFunction<UILineEdit>("isAlwaysActive", &UILineEdit::isAlwaysActive); g_lua.bindClassMemberFunction<UILineEdit>("isAlwaysActive", &UILineEdit::isAlwaysActive);
g_lua.bindClassMemberFunction<UILineEdit>("isTextHidden", &UILineEdit::isTextHidden); g_lua.bindClassMemberFunction<UILineEdit>("isTextHidden", &UILineEdit::isTextHidden);
// UIWindow
g_lua.registerClass<UIWindow, UIWidget>();
g_lua.bindClassStaticFunction<UIWindow>("create", []{ return UIWindowPtr(new UIWindow); } );
g_lua.bindClassMemberFunction<UIWindow>("getTitle", &UIWindow::getTitle);
g_lua.bindClassMemberFunction<UIWindow>("setTitle", &UIWindow::setTitle);
// UIFrameCounter // UIFrameCounter
g_lua.registerClass<UIFrameCounter, UIWidget>(); g_lua.registerClass<UIFrameCounter, UIWidget>();
g_lua.bindClassStaticFunction<UIFrameCounter>("create", []{ return UIFrameCounterPtr(new UIFrameCounter); } ); g_lua.bindClassStaticFunction<UIFrameCounter>("create", []{ return UIFrameCounterPtr(new UIFrameCounter); } );

View File

@ -29,7 +29,6 @@ class UIManager;
class UIWidget; class UIWidget;
class UILineEdit; class UILineEdit;
class UIFrameCounter; class UIFrameCounter;
class UIWindow;
class UILayout; class UILayout;
class UIVerticalLayout; class UIVerticalLayout;
class UIAnchorLayout; class UIAnchorLayout;
@ -39,7 +38,6 @@ typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr;
typedef std::shared_ptr<UILineEdit> UILineEditPtr; typedef std::shared_ptr<UILineEdit> UILineEditPtr;
typedef std::shared_ptr<UIFrameCounter> UIFrameCounterPtr; typedef std::shared_ptr<UIFrameCounter> UIFrameCounterPtr;
typedef std::shared_ptr<UIWindow> UIWindowPtr;
typedef std::shared_ptr<UILayout> UILayoutPtr; typedef std::shared_ptr<UILayout> UILayoutPtr;
typedef std::shared_ptr<UIVerticalLayout> UIVerticalLayoutPtr; typedef std::shared_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
typedef std::shared_ptr<UIAnchorLayout> UIAnchorLayoutPtr; typedef std::shared_ptr<UIAnchorLayout> UIAnchorLayoutPtr;

View File

@ -26,7 +26,6 @@
#include "uimanager.h" #include "uimanager.h"
#include "uiwidget.h" #include "uiwidget.h"
#include "uilineedit.h" #include "uilineedit.h"
#include "uiwindow.h"
#include "uiframecounter.h" #include "uiframecounter.h"
#include "uilayout.h" #include "uilayout.h"
#include "uiverticallayout.h" #include "uiverticallayout.h"

View File

@ -722,7 +722,6 @@ int UIWidget::getChildIndex(const UIWidgetPtr& child)
Rect UIWidget::getChildrenRect() Rect UIWidget::getChildrenRect()
{ {
Rect rect = m_rect; Rect rect = m_rect;
rect.expand(-m_borderWidth.top, -m_borderWidth.right, -m_borderWidth.bottom, -m_borderWidth.left);
rect.expand(-m_padding.top, -m_padding.right, -m_padding.bottom, -m_padding.left); rect.expand(-m_padding.top, -m_padding.right, -m_padding.bottom, -m_padding.left);
return rect; return rect;
} }

View File

@ -34,9 +34,7 @@ void UIWidget::initText()
void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode) void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode)
{ {
for(const OTMLNodePtr& node : styleNode->children()) { for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "icon") if(node->tag() == "text")
setIcon(node->value());
else if(node->tag() == "text")
setText(node->value()); setText(node->value());
else if(node->tag() == "text-align") else if(node->tag() == "text-align")
setTextAlign(Fw::translateAlignment(node->value())); setTextAlign(Fw::translateAlignment(node->value()));

View File

@ -1,153 +0,0 @@
/*
* 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 "uiwindow.h"
#include "uitranslator.h"
#include <framework/graphics/font.h>
#include <framework/graphics/graphics.h>
#include <framework/otml/otml.h>
UIWindow::UIWindow()
{
m_moving = false;
m_movePolicy = DONT_MOVE;
m_titleAlign = Fw::AlignCenter;
m_headHeight = 0;
m_oldIndex = -1;
}
void UIWindow::draw()
{
// render children
UIWidget::draw();
// draw window head text
Rect headTextRect = m_rect;
headTextRect.expandTop(-m_headTextOffset.y);
headTextRect.setHeight(m_headHeight);
if(m_titleAlign & Fw::AlignLeft)
headTextRect.expandLeft(-m_headTextOffset.x);
else if(m_titleAlign & Fw::AlignRight)
headTextRect.expandRight(-m_headTextOffset.x);
else {
headTextRect.expandLeft(-m_headTextOffset.x);
headTextRect.expandRight(-m_headTextOffset.x);
}
m_font->renderText(m_title, headTextRect, m_titleAlign, m_color);
}
void UIWindow::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
{
UIWidget::onStyleApply(styleName, styleNode);
for(OTMLNodePtr node : styleNode->children()) {
if(node->tag() == "head-height")
m_headHeight = node->value<int>();
else if(node->tag() == "head-text-offset")
m_headTextOffset = node->value<Point>();
else if(node->tag() == "title")
setTitle(node->value());
else if(node->tag() == "head-text-align")
m_titleAlign = Fw::translateAlignment(node->value());
else if(node->tag() == "move-policy") {
if(node->value() == "free")
m_movePolicy = FREE_MOVE;
else if(node->value() == "free updated")
m_movePolicy = FREE_UPDATED_MOVE;
else
m_movePolicy = DONT_MOVE;
}
}
}
void UIWindow::onGeometryChange(const Rect& oldRect, const Rect& newRect)
{
bindRectToParent();
if(newRect == getRect())
UIWidget::onGeometryChange(oldRect, newRect);
}
bool UIWindow::onMousePress(const Point& mousePos, Fw::MouseButton button)
{
if(m_movePolicy != DONT_MOVE && button == Fw::MouseLeftButton) {
UIWidgetPtr clickedChild = getChildByPos(mousePos);
//FIXME: recursively check for non phantom children
if(!clickedChild || clickedChild->isPhantom()) {
m_moving = true;
m_movingReference = mousePos - getRect().topLeft();
m_oldIndex = getParent()->getChildIndex(asUIWidget());
m_oldPos = getPos();
getParent()->moveChildToTop(asUIWidget());
}
}
return UIWidget::onMousePress(mousePos, button);
}
void UIWindow::onMouseRelease(const Point& mousePos, Fw::MouseButton button)
{
if(m_moving) {
if(m_movePolicy == FREE_UPDATED_MOVE) {
UIWidgetPtr parent = getParent();
// restore position before move
parent->moveChildToIndex(asUIWidget(), m_oldIndex);
setPos(m_oldPos);
// calculate new index
int newIndex;
for(newIndex=parent->getChildCount();newIndex>1;--newIndex) {
UIWidgetPtr child = parent->getChildByIndex(newIndex);
if(mousePos.y >= child->getRect().top())
break;
}
// set the new index
parent->moveChildToIndex(asUIWidget(), newIndex);
updateParentLayout();
}
m_moving = false;
}
UIWidget::onMouseRelease(mousePos, button);
}
bool UIWindow::onMouseMove(const Point& mousePos, const Point& mouseMoved)
{
if(m_moving) {
setPos(mousePos - m_movingReference);
return true;
}
return UIWidget::onMouseMove(mousePos, mouseMoved);
}
bool UIWindow::onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers)
{
if(keyboardModifiers == Fw::KeyboardNoModifier) {
if(keyCode == Fw::KeyReturn || keyCode == Fw::KeyEnter) {
if(callLuaField<bool>("onEnter"))
return true;
} else if(keyCode == Fw::KeyEscape) {
if(callLuaField<bool>("onEscape"))
return true;
}
}
return UIWidget::onKeyPress(keyCode, keyText, keyboardModifiers);
}

View File

@ -1,63 +0,0 @@
/*
* 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 UIWINDOW_H
#define UIWINDOW_H
#include "uiwidget.h"
class UIWindow : public UIWidget
{
enum MovePolicy {
DONT_MOVE = 0,
FREE_MOVE,
FREE_UPDATED_MOVE
};
public:
UIWindow();
virtual void draw();
void setTitle(const std::string& title) { m_title = title; }
std::string getTitle() const { return m_title; }
protected:
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
virtual void onGeometryChange(const Rect& oldRect, const Rect& newRect);
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
virtual bool onKeyPress(uchar keyCode, std::string keyText, int keyboardModifiers);
private:
std::string m_title;
bool m_moving;
MovePolicy m_movePolicy;
Fw::AlignmentFlag m_titleAlign;
Point m_headTextOffset;
Point m_movingReference;
Point m_oldPos;
int m_oldIndex;
int m_headHeight;
};
#endif