new widget, UICheckBox

This commit is contained in:
Eduardo Bart 2011-11-15 21:47:32 -02:00
parent 9c986c4c5c
commit 532d7f239f
31 changed files with 449 additions and 133 deletions

View File

@ -50,7 +50,7 @@ IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
ADD_DEFINITIONS(-D_DEBUG)
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(SOURCES src/framework/ui/uiframecounter.cpp
SET(SOURCES
# main
src/main.cpp
@ -94,9 +94,6 @@ SET(SOURCES src/framework/ui/uiframecounter.cpp
src/framework/net/rsa.cpp
src/framework/net/server.cpp
# framework util
src/framework/util/translator.cpp
# framework core
src/framework/core/logger.cpp
src/framework/core/configs.cpp
@ -142,6 +139,9 @@ SET(SOURCES src/framework/ui/uiframecounter.cpp
src/framework/ui/uiverticallayout.cpp
src/framework/ui/uilayout.cpp
src/framework/ui/uiprogressbar.cpp
src/framework/ui/uicheckbox.cpp
src/framework/ui/uiframecounter.cpp
src/framework/ui/uitranslator.cpp
)
IF(HANDLE_EXCEPTIONS)

View File

@ -1,17 +1,12 @@
== What is OTClient?
OTClient is an alternative Tibia client for usage with otserv. It aims to be complete and flexible,
for that it uses LUA scripting for all game interface functionality and configuration files created with
a syntax similar to CSS for its interface design. OTClient works with a modular system, this means
for that it uses LUA scripting for all game interface functionality and OTML files that has a syntax
similar to CSS for the client interface design. OTClient works with a modular system, this means
that each functionality is a separated module, giving the possibility to users modify and customize
anything easily. Users can also create new mods and extend game interface for their own purposes.
OTClient is written in C++2011, the upcoming C++ standard.
== Need help?
If you have any questions or are looking for more information, please feel free to ask on our official
forum at http://otclient.info/
== Getting Started
In short, if you need to compile OTClient, follow these tutorials:
@ -19,9 +14,14 @@ In short, if you need to compile OTClient, follow these tutorials:
* {Compiling on Ubuntu}[http://otclient.info/page/articles.html/_/general/compiling-on-ubuntu-r12]
Checkout our website at {http://otclient.info}[http://otclient.info/] for tutorials and more information
== Need help?
If you have any questions or are looking for more information, please feel free to ask on our official
forum at http://otclient.info/
== Bugs
Have found a bug? Please create an issue in our bug tracker!
Have found a bug? Please create an issue in our bug tracker
http://otclient.info/tracker
== Contributing
@ -31,8 +31,8 @@ We encourage you to contribute to OTClient! Please check out
== Authors
* edubart <edub4rt@gmail.com> (project creator and leader developer)
* baxnie <henrique_santiago93@hotmail.com> (official developer)
* edubart (project creator and leader developer) <edub4rt@gmail.com>
* baxnie (official developer) <henrique_santiago93@hotmail.com>
== License

2
TODO
View File

@ -12,3 +12,5 @@ remember password/account
scrollbar
make otui syntax more like css
a real working border and background property in otui
setIcon() for buttons
load state styles in order

View File

@ -41,7 +41,7 @@ MainWindow
anchors.bottom: parent.bottom
margin.bottom: 9
margin.right: 9
onClick: About.openWebpage()
@onClick: About.openWebpage()
HorizontalSeparator
anchors.left: parent.left
@ -58,4 +58,4 @@ MainWindow
anchors.top: parent.top
margin.top: 191
margin.left: 188
onClick: About.destroy()
@onClick: About.destroy()

View File

@ -11,6 +11,7 @@ Module
importStyles 'styles/panels.otui'
importStyles 'styles/separators.otui'
importStyles 'styles/lineedits.otui'
importStyles 'styles/checkboxes.otui'
importStyles 'styles/windows.otui'
importStyles 'styles/listboxes.otui'
importStyles 'styles/items.otui'

View File

@ -8,18 +8,18 @@ Button < UIButton
source: /core_styles/images/button.png
border: 5
state.hover:
$hover:
border-image:
source: /core_styles/images/button_hover.png
border: 5
state.pressed:
$pressed:
text-translate: 1 1
border-image:
source: /core_styles/images/button_down.png
border: 5
state.disabled:
$disabled:
color: #999999
background-color: #ffffff88
@ -32,14 +32,14 @@ TopButton < UIButton
size: 26 25
border: 3
state.hover:
$hover:
border-image:
source: /core_styles/images/top_button.png
size: 26 25
offset: 26 0
border: 3
state.pressed:
$pressed:
text-translate: 1 1
border-image:
source: /core_styles/images/top_button.png
@ -47,7 +47,7 @@ TopButton < UIButton
offset: 52 0
border: 3
state.disabled:
$disabled:
background-color: #ffffff66
MenuButton < UIButton
@ -58,7 +58,7 @@ MenuButton < UIButton
source: /core_styles/images/menu.png
size: 64 24
state.hover:
$hover:
border-image:
source: /core_styles/images/menu.png
offset: 0 24

View File

@ -12,7 +12,7 @@ Window < UIWindow
border: 4
border.top: 20
state.pressed:
$pressed:
opacity: 192
MiniWindow < UIWindow

View File

@ -8,7 +8,7 @@ CharacterListLabel < Label
margin.right: 1
margin.top: 1
state.focus:
$focus:
background-color: #ffffff22
color: #ffffff
@ -55,7 +55,7 @@ MainWindow
anchors.bottom: parent.bottom
margin.bottom: 16
margin.right: 16
onClick: CharacterList.doLogin()
@onClick: CharacterList.doLogin()
Button
id: buttonCancel
@ -65,4 +65,4 @@ MainWindow
anchors.bottom: parent.bottom
margin.bottom: 16
margin.right: 16
onClick: CharacterList.destroy()
@onClick: CharacterList.destroy()

View File

@ -1,7 +1,7 @@
MainWindow
id: enterGame
title: Enter Game
size: 236 160
size: 236 200
onEnter: EnterGame.doLogin()
onEscape: EnterGame.hide()
@ -38,6 +38,27 @@ MainWindow
margin.left: 18
margin.right: 18
CheckBox
id: rememberPasswordBox
text: Remember password
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin.top: 10
margin.left: 18
margin.right: 18
CheckBox
id: autoLoginBox
text: Auto login
checked: true
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin.top: 8
margin.left: 18
margin.right: 18
Button
text: Ok
width: 64
@ -45,7 +66,7 @@ MainWindow
anchors.bottom: parent.bottom
margin.bottom: 16
margin.right: 16
onClick: EnterGame.doLogin()
@onClick: EnterGame.doLogin()
Button
text: Cancel
@ -54,4 +75,4 @@ MainWindow
anchors.bottom: parent.bottom
margin.bottom: 16
margin.right: 16
onClick: EnterGame.hide()
@onClick: EnterGame.hide()

View File

@ -20,7 +20,6 @@ function Inventory.create()
local itemWidget = window:getChildById('feet')
window:setHeight(itemWidget:getPosition().y + itemWidget:getHeight() - window:getPosition().y)
end
function Inventory.destroy()

View File

@ -7,4 +7,4 @@ Panel
MenuButton
text: Quit
onClick: exit()
@onClick: exit()

View File

@ -10,7 +10,7 @@ MainWindow
anchors.top: parent.top
margin.left: 18
margin.top: 32
onClick: displayErrorBox("Error", "Not implemented yet")
@onClick: displayErrorBox("Error", "Not implemented yet")
Label
text: |-
@ -28,7 +28,7 @@ MainWindow
anchors.top: parent.top
margin.left: 18
margin.top: 65
onClick: displayErrorBox("Error", "Not implemented yet")
@onClick: displayErrorBox("Error", "Not implemented yet")
Label
text: |-
@ -46,7 +46,7 @@ MainWindow
anchors.top: parent.top
margin.left: 18
margin.top: 98
onClick: displayErrorBox("Error", "Not implemented yet")
@onClick: displayErrorBox("Error", "Not implemented yet")
Label
text: Customise the console
@ -62,7 +62,7 @@ MainWindow
anchors.top: parent.top
margin.left: 18
margin.top: 131
onClick: displayErrorBox("Error", "Not implemented yet")
@onClick: displayErrorBox("Error", "Not implemented yet")
Label
text: Edit your hotkey texts
@ -86,7 +86,7 @@ MainWindow
anchors.bottom: parent.bottom
margin.left: 18
margin.bottom: 60
onClick: displayErrorBox("Error", "Not implemented yet")
@onClick: displayErrorBox("Error", "Not implemented yet")
Label
text: |-
@ -113,4 +113,4 @@ MainWindow
anchors.bottom: parent.bottom
margin.right: 10
margin.bottom: 10
onClick: Options.destroy()
@onClick: Options.destroy()

View File

@ -12,7 +12,7 @@ Window
margin.left: 20
Button
onClick: Outfit.previousType()
@onClick: Outfit.previousType()
text: <<
width: 32
margin.top: 3
@ -20,7 +20,7 @@ Window
anchors.left: creature.left
Button
onClick: Outfit.nextType()
@onClick: Outfit.nextType()
text: >>
width: 32
margin.top: 3
@ -43,7 +43,7 @@ Window
anchors.bottom: parent.bottom
margin.bottom: 16
margin.right: 16
onClick: Outfit.accept()
@onClick: Outfit.accept()
Button
id: buttonCancel
@ -53,4 +53,4 @@ Window
anchors.bottom: parent.bottom
margin.bottom: 16
margin.right: 16
onClick: Outfit.destroy()
@onClick: Outfit.destroy()

View File

@ -12,7 +12,7 @@ TopPanel
margin.top: 4
margin.left: 6
tooltip: Options
onClick: Options.create()
@onClick: Options.create()
UIWidget
size: 16 16
@ -25,7 +25,7 @@ TopPanel
anchors.left: prev.right
margin.left: 6
tooltip: Enter game with a character
onClick: |
@onClick: |
if Game.isOnline() then
CharacterList.show()
else
@ -44,7 +44,7 @@ TopPanel
margin.top: 4
margin.right: 6
tooltip: Logout
onClick: |
@onClick: |
if Game.isOnline() then
Game.logout(false)
else
@ -63,7 +63,7 @@ TopPanel
margin.top: 4
margin.right: 6
tooltip: About OTClient
onClick: About.create()
@onClick: About.create()
UIWidget
size: 16 16

View File

@ -246,12 +246,16 @@ namespace Fw
};
enum WidgetState {
InvalidState = -1,
DefaultState = 0,
ActiveState = 1,
FocusState = 2,
HoverState = 4,
PressedState = 8,
DisabledState = 16
DisabledState = 16,
CheckedState = 32,
OnState = 64,
LastState = 128
//FirstState,
//MiddleState,
//LastState,

View File

@ -44,7 +44,6 @@ void ResourceManager::init(const char* argv0, const char *appName)
bool found = false;
for(const std::string& dir : possibleDirs) {
dump << dir;
if(g_resources.addToSearchPath(dir)) {
logInfo("Using modules directory '", dir.c_str(), "'");
found = true;

View File

@ -64,7 +64,6 @@
// additional utilities
#include "util/types.h"
#include "util/tools.h"
#include "util/translator.h"
#include "util/point.h"
#include "util/color.h"
#include "util/rect.h"

View File

@ -129,6 +129,10 @@ void LuaInterface::registerFunctions()
g_lua.bindClassMemberFunction<UILineEdit>("clearText", &UILineEdit::clearText);
g_lua.bindClassMemberFunction<UILineEdit>("getCursorPos", &UILineEdit::getCursorPos);
// UICheckBox
g_lua.registerClass<UICheckBox, UIWidget>();
g_lua.bindClassStaticFunction<UICheckBox>("create", &UIWidget::create<UICheckBox>);
// UIWindow
g_lua.registerClass<UIWindow, UIWidget>();
g_lua.bindClassStaticFunction<UIWindow>("create", &UIWidget::create<UIWindow>);

View File

@ -24,15 +24,16 @@
#define FRAMEWORK_UI_DECLARATIONS_H
#include <framework/global.h>
#include <framework/platform/platformevent.h>
class UIManager;
class UIWidget;
class UILabel;
class UIButton;
class UILineEdit;
class UIWindow;
class UICheckBox;
class UIProgressBar;
class UIFrameCounter;
class UIWindow;
class UILayout;
class UIVerticalLayout;
class UIAnchorLayout;
@ -43,8 +44,10 @@ typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr;
typedef std::shared_ptr<UILabel> UILabelPtr;
typedef std::shared_ptr<UIButton> UIButtonPtr;
typedef std::shared_ptr<UILineEdit> UILineEditPtr;
typedef std::shared_ptr<UICheckBox> UICheckBoxPtr;
typedef std::shared_ptr<UIProgressBar> UIProgressBarPtr;
typedef std::shared_ptr<UIFrameCounter> UIFrameCounterPtr;
typedef std::shared_ptr<UIWindow> UIWindowPtr;
typedef std::shared_ptr<UIWindow> UIFrameCounterPtr;
typedef std::shared_ptr<UILayout> UILayoutPtr;
typedef std::shared_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
typedef std::shared_ptr<UIAnchorLayout> UIAnchorLayoutPtr;

View File

@ -31,5 +31,6 @@
#include "uiwindow.h"
#include "uiframecounter.h"
#include "uiprogressbar.h"
#include "uicheckbox.h"
#endif

View File

@ -40,7 +40,7 @@ void UIButton::render()
{
UIWidget::render();
Rect textRect = m_rect;
textRect.translate(m_textTranslate);
textRect.translate(m_textOffset);
m_font->renderText(m_text, textRect, Fw::AlignCenter, m_foregroundColor);
}
@ -49,8 +49,8 @@ void UIButton::onStyleApply(const OTMLNodePtr& styleNode)
UIWidget::onStyleApply(styleNode);
for(OTMLNodePtr node : styleNode->children()) {
if(node->tag() == "text-translate") {
m_textTranslate = node->value<Point>();
if(node->tag() == "text-offset") {
m_textOffset = node->value<Point>();
} else if(node->tag() == "text") {
m_text = node->value();
}

View File

@ -44,7 +44,7 @@ protected:
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
SimpleCallback m_onClick;
Point m_textTranslate;
Point m_textOffset;
std::string m_text;
};

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2010-2011 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 "uicheckbox.h"
#include <framework/otml/otmlnode.h>
#include <framework/graphics/image.h>
#include <framework/graphics/font.h>
#include <framework/graphics/graphics.h>
#include <framework/core/eventdispatcher.h>
void UICheckBox::render()
{
Rect boxRect;
boxRect.setSize(m_boxSize);
boxRect.moveLeft(m_rect.left());
boxRect.moveVerticalCenter(m_rect.verticalCenter());
g_graphics.bindColor(m_backgroundColor);
m_image->draw(boxRect);
Rect textRect(m_rect);
textRect.setTopLeft(textRect.topLeft() + m_textOffset);
m_font->renderText(m_text, textRect, Fw::AlignLeft, m_foregroundColor);
}
void UICheckBox::onMouseRelease(const Point& mousePos, Fw::MouseButton button)
{
if(isPressed() && getRect().contains(mousePos))
setState(Fw::CheckedState, !isChecked());
}
void UICheckBox::onStyleApply(const OTMLNodePtr& styleNode)
{
UIWidget::onStyleApply(styleNode);
for(OTMLNodePtr node : styleNode->children()) {
if(node->tag() == "text-offset")
m_textOffset = node->value<Point>();
else if(node->tag() == "text")
m_text = node->value();
else if(node->tag() == "box-size")
m_boxSize = node->value<Size>();
else if(node->tag() == "checked") {
// must be scheduled because setChecked can change the style again
g_dispatcher.addEvent(std::bind(&UICheckBox::setChecked, asUICheckBox(), node->value<bool>()));
}
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010-2011 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 UICHECKBOX_H
#define UICHECKBOX_H
#include "uiwidget.h"
class UICheckBox : public UIWidget
{
public:
void render();
bool isChecked() { return hasState(Fw::CheckedState); }
void setChecked(bool checked) { setState(Fw::CheckedState, checked); }
void setText(const std::string& text) { m_text = text; }
std::string getText() { return m_text; }
UICheckBoxPtr asUICheckBox() { return std::static_pointer_cast<UICheckBox>(shared_from_this()); }
protected:
virtual void onStyleApply(const OTMLNodePtr& styleNode);
virtual void onMouseRelease(const Point& mousePos, Fw::MouseButton button);
std::string m_text;
Size m_boxSize;
Point m_textOffset;
};
#endif

View File

@ -21,6 +21,7 @@
*/
#include "uiframecounter.h"
#include "uitranslator.h"
#include <framework/graphics/font.h>
#include <framework/otml/otmlnode.h>
#include <framework/platform/platform.h>

View File

@ -21,6 +21,7 @@
*/
#include "uilabel.h"
#include "uitranslator.h"
#include <framework/graphics/font.h>
#include <framework/otml/otmlnode.h>

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2010-2011 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 "uitranslator.h"
#include <boost/algorithm/string.hpp>
Fw::AlignmentFlag Fw::translateAlignment(std::string aligment)
{
boost::to_lower(aligment);
boost::erase_all(aligment, " ");
if(aligment == "topleft")
return Fw::AlignTopLeft;
else if(aligment == "topright")
return Fw::AlignTopRight;
else if(aligment == "bottomleft")
return Fw::AlignBottomLeft;
else if(aligment == "bottomright")
return Fw::AlignBottomRight;
else if(aligment == "left")
return Fw::AlignLeftCenter;
else if(aligment == "right")
return Fw::AlignRightCenter;
else if(aligment == "top")
return Fw::AlignTopCenter;
else if(aligment == "bottom")
return Fw::AlignBottomCenter;
else if(aligment == "center")
return Fw::AlignCenter;
return Fw::AlignNone;
}
Fw::AnchorEdge Fw::translateAnchorEdge(std::string anchorEdge)
{
boost::to_lower(anchorEdge);
boost::erase_all(anchorEdge, " ");
if(anchorEdge == "left")
return Fw::AnchorLeft;
else if(anchorEdge == "right")
return Fw::AnchorRight;
else if(anchorEdge == "top")
return Fw::AnchorTop;
else if(anchorEdge == "bottom")
return Fw::AnchorBottom;
else if(anchorEdge == "horizontalcenter")
return Fw::AnchorHorizontalCenter;
else if(anchorEdge == "verticalcenter")
return Fw::AnchorVerticalCenter;
return Fw::AnchorNone;
}
Fw::WidgetState Fw::translateState(std::string state)
{
boost::to_lower(state);
boost::erase_all(state, " ");
if(state == "active")
return Fw::ActiveState;
else if(state == "focus")
return Fw::FocusState;
else if(state == "hover")
return Fw::HoverState;
else if(state == "pressed")
return Fw::PressedState;
else if(state == "checked")
return Fw::CheckedState;
else if(state == "disabled")
return Fw::DisabledState;
else if(state == "on")
return Fw::OnState;
else
return Fw::InvalidState;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2010-2011 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 TRANSLATOR_H
#define TRANSLATOR_H
#include "../const.h"
#include <string>
namespace Fw {
AlignmentFlag translateAlignment(std::string aligment);
AnchorEdge translateAnchorEdge(std::string anchorEdge);
WidgetState translateState(std::string state);
};
#endif

View File

@ -24,6 +24,7 @@
#include "uimanager.h"
#include "uianchorlayout.h"
#include "uiverticallayout.h"
#include "uitranslator.h"
#include <framework/core/eventdispatcher.h>
#include <framework/graphics/image.h>
@ -36,6 +37,7 @@
UIWidget::UIWidget()
{
m_updateEventScheduled = false;
m_firstOnStyle = true;
m_states = Fw::DefaultState;
// generate an unique id, this is need because anchored layouts find widgets by id
@ -611,6 +613,28 @@ void UIWidget::updateLayout()
m_layout->update();
}
void UIWidget::setState(Fw::WidgetState state, bool on)
{
if(state == Fw::InvalidState)
return;
int oldStates = m_states;
if(on)
m_states |= state;
else
m_states &= ~state;
if(oldStates != m_states)
updateStyle();
}
bool UIWidget::hasState(Fw::WidgetState state)
{
if(state == Fw::InvalidState)
return false;
return (m_states & state);
}
void UIWidget::updateState(Fw::WidgetState state)
{
bool newStatus = true;
@ -675,12 +699,7 @@ void UIWidget::updateState(Fw::WidgetState state)
}
if(newStatus != oldStatus) {
if(newStatus)
m_states |= state;
else
m_states &= ~state;
updateStyle();
setState(state, newStatus);
if(state == Fw::FocusState) {
g_dispatcher.addEvent(std::bind(&UIWidget::onFocusChange, asUIWidget(), newStatus, m_lastFocusReason));
@ -691,10 +710,8 @@ void UIWidget::updateState(Fw::WidgetState state)
void UIWidget::updateStates()
{
updateState(Fw::ActiveState);
updateState(Fw::FocusState);
updateState(Fw::DisabledState);
updateState(Fw::HoverState);
for(int state = 1; state != Fw::LastState; state <<= 1)
updateState((Fw::WidgetState)state);
}
void UIWidget::updateStyle()
@ -712,26 +729,32 @@ void UIWidget::updateStyle()
}
}
// merge states styles, NOTE: order does matter
OTMLNodePtr style = m_style->get("state.active");
if(style && hasState(Fw::ActiveState))
newStateStyle->merge(style);
// checks for states combination
for(const OTMLNodePtr& style : m_style->children()) {
if(boost::starts_with(style->tag(), "$")) {
std::string statesStr = style->tag().substr(1);
std::vector<std::string> statesSplit;
boost::split(statesSplit, statesStr, boost::is_any_of(std::string(" ")));
style = m_style->get("state.focus");
if(style && hasState(Fw::FocusState))
newStateStyle->merge(style);
bool match = true;
for(std::string stateStr : statesSplit) {
if(stateStr.length() == 0)
continue;
style = m_style->get("state.hover");
if(style && hasState(Fw::HoverState))
newStateStyle->merge(style);
bool notstate = (stateStr[0] == '!');
if(notstate)
stateStr = stateStr.substr(1);
style = m_style->get("state.pressed");
if(style && hasState(Fw::PressedState))
newStateStyle->merge(style);
bool stateOn = hasState(Fw::translateState(stateStr));
if((!notstate && !stateOn) || (notstate && stateOn))
match = false;
}
style = m_style->get("state.disabled");
if(style && hasState(Fw::DisabledState))
newStateStyle->merge(style);
// merge states styles
if(match)
newStateStyle->merge(style);
}
}
applyStyle(newStateStyle);
m_stateStyle = newStateStyle;
@ -886,13 +909,25 @@ void UIWidget::onStyleApply(const OTMLNodePtr& styleNode)
anchorLayout->addAnchor(asUIWidget(), anchoredEdge, hookedWidgetId, hookedEdge);
}
} else if(node->tag() == "onClick" ||
node->tag() == "onMousePress" ||
node->tag() == "onHoverChange") {
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
luaSetField(node->tag());
// lua functions
} else if(boost::starts_with(node->tag(), "@")) {
// on load once
if(m_firstOnStyle) {
std::string funcName = node->tag().substr(1);
std::string funcOrigin = "@" + node->source() + "[" + node->tag() + "]";
g_lua.loadFunction(node->value(), funcOrigin);
luaSetField(funcName);
}
// lua fields value
} else if(boost::starts_with(node->tag(), "&")) {
std::string fieldName = node->tag().substr(1);
std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]";
g_lua.evaluateExpression(node->value(), fieldOrigin);
luaSetField(fieldName);
}
}
m_firstOnStyle = false;
}
void UIWidget::onGeometryUpdate(const Rect& oldRect, const Rect& newRect)

View File

@ -80,49 +80,48 @@ public:
void unlock();
void focus();
bool isActive() const { return hasState(Fw::ActiveState); }
bool isEnabled() const { return !hasState(Fw::DisabledState); }
bool isDisabled() const { return hasState(Fw::DisabledState); }
bool isFocused() const { return hasState(Fw::FocusState); }
bool isHovered() const { return hasState(Fw::HoverState); }
bool isPressed() const { return hasState(Fw::PressedState); }
bool isActive() { return hasState(Fw::ActiveState); }
bool isEnabled() { return !hasState(Fw::DisabledState); }
bool isDisabled() { return hasState(Fw::DisabledState); }
bool isFocused() { return hasState(Fw::FocusState); }
bool isHovered() { return hasState(Fw::HoverState); }
bool isPressed() { return hasState(Fw::PressedState); }
bool isVisible();
bool isHidden() { return !isVisible(); }
bool isExplicitlyEnabled() const { return m_enabled; }
bool isExplicitlyVisible() const { return m_visible; }
bool isFocusable() const { return m_focusable; }
bool isPhantom() const { return m_phantom; }
bool isSizeFixed() const { return m_fixedSize; }
bool hasChildren() const { return m_children.size() > 0; }
bool isExplicitlyEnabled() { return m_enabled; }
bool isExplicitlyVisible() { return m_visible; }
bool isFocusable() { return m_focusable; }
bool isPhantom() { return m_phantom; }
bool isSizeFixed() { return m_fixedSize; }
bool hasChildren() { return m_children.size() > 0; }
bool hasChild(const UIWidgetPtr& child);
bool hasState(Fw::WidgetState state) const { return m_states & state; }
std::string getId() const { return m_id; }
int getChildCount() const { return m_children.size(); }
UILayoutPtr getLayout() const { return m_layout; }
UIWidgetPtr getParent() const { return m_parent.lock(); }
std::string getId() { return m_id; }
int getChildCount() { return m_children.size(); }
UILayoutPtr getLayout() { return m_layout; }
UIWidgetPtr getParent() { return m_parent.lock(); }
UIWidgetPtr getRootParent();
Point getPosition() const { return m_rect.topLeft(); }
Size getSize() const { return m_rect.size(); }
Rect getRect() const { return m_rect; }
int getX() const { return m_rect.x(); }
int getY() const { return m_rect.y(); }
int getWidth() const { return m_rect.width(); }
int getHeight() const { return m_rect.height(); }
ImagePtr getImage() const { return m_image; }
FontPtr getFont() const { return m_font; }
Color getForegroundColor() const { return m_foregroundColor; }
Color getBackgroundColor() const { return m_backgroundColor; }
int getOpacity() const { return m_opacity; }
int getMarginLeft() const { return m_marginLeft; }
int getMarginRight() const { return m_marginRight; }
int getMarginTop() const { return m_marginTop; }
int getMarginBottom() const { return m_marginBottom; }
Fw::FocusReason getLastFocusReason() const { return m_lastFocusReason; }
OTMLNodePtr getStyle() const { return m_style; }
Point getPosition() { return m_rect.topLeft(); }
Size getSize() { return m_rect.size(); }
Rect getRect() { return m_rect; }
int getX() { return m_rect.x(); }
int getY() { return m_rect.y(); }
int getWidth() { return m_rect.width(); }
int getHeight() { return m_rect.height(); }
ImagePtr getImage() { return m_image; }
FontPtr getFont() { return m_font; }
Color getForegroundColor() { return m_foregroundColor; }
Color getBackgroundColor() { return m_backgroundColor; }
int getOpacity() { return m_opacity; }
int getMarginLeft() { return m_marginLeft; }
int getMarginRight() { return m_marginRight; }
int getMarginTop() { return m_marginTop; }
int getMarginBottom() { return m_marginBottom; }
Fw::FocusReason getLastFocusReason() { return m_lastFocusReason; }
OTMLNodePtr getStyle() { return m_style; }
UIWidgetList getChildren() const { return m_children; }
UIWidgetPtr getFocusedChild() const { return m_focusedChild; }
UIWidgetList getChildren() { return m_children; }
UIWidgetPtr getFocusedChild() { return m_focusedChild; }
UIWidgetPtr getChildAfter(const UIWidgetPtr& relativeChild);
UIWidgetPtr getChildBefore(const UIWidgetPtr& relativeChild);
UIWidgetPtr getChildById(const std::string& childId);
@ -147,16 +146,17 @@ public:
void updateParentLayout();
void updateLayout();
virtual void updateState(Fw::WidgetState state);
void updateStates();
virtual void updateStyle();
virtual void updateState(Fw::WidgetState state);
void setState(Fw::WidgetState state, bool on);
bool hasState(Fw::WidgetState state);
void updateStyle();
void applyStyle(const OTMLNodePtr& styleNode);
UIWidgetPtr asUIWidget() { return std::static_pointer_cast<UIWidget>(shared_from_this()); }
private:
bool m_updateEventScheduled;
protected:
/// Triggered when widget style is changed
virtual void onStyleApply(const OTMLNodePtr& styleNode);
@ -190,6 +190,8 @@ protected:
bool m_fixedSize;
bool m_pressed;
bool m_phantom;
bool m_updateEventScheduled;
bool m_firstOnStyle;
Rect m_rect;
UILayoutPtr m_layout;
UIWidgetWeakPtr m_parent;
@ -198,7 +200,7 @@ protected:
UIWidgetPtr m_focusedChild;
OTMLNodePtr m_style;
OTMLNodePtr m_stateStyle;
uint m_states;
int m_states;
// basic style components used by all widgets
ImagePtr m_image;

View File

@ -21,6 +21,7 @@
*/
#include "uiwindow.h"
#include "uitranslator.h"
#include <framework/graphics/borderimage.h>
#include <framework/graphics/font.h>
#include <framework/graphics/graphics.h>