Merge branch 'master' of github.com:edubart/otclient
This commit is contained in:
commit
8f27ff60ac
|
@ -128,8 +128,9 @@ SET(SOURCES
|
|||
src/framework/ui/uibutton.cpp
|
||||
src/framework/ui/uilineedit.cpp
|
||||
src/framework/ui/uiwindow.cpp
|
||||
src/framework/ui/uianchor.cpp
|
||||
src/framework/ui/uilist.cpp
|
||||
src/framework/ui/uianchorlayout.cpp
|
||||
src/framework/ui/uiverticallayout.cpp
|
||||
src/framework/ui/uilayout.cpp
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
|
|
|
@ -15,14 +15,16 @@ function Console.onLog(level, message, time)
|
|||
if level == LogDebug then
|
||||
color = '#5555ff'
|
||||
elseif level == LogInfo then
|
||||
color = '#55ff55'
|
||||
color = '#5555ff'
|
||||
elseif level == LogWarning then
|
||||
color = '#ffff00'
|
||||
else
|
||||
color = '#ff0000'
|
||||
end
|
||||
|
||||
if level ~= LogDebug then
|
||||
Console.addLine(message, color)
|
||||
end
|
||||
|
||||
logLocked = false
|
||||
end
|
||||
|
@ -32,21 +34,21 @@ function Console.addLine(text, color)
|
|||
-- create new label
|
||||
|
||||
local label = UILabel.create()
|
||||
label:setStyle('ConsoleLabel')
|
||||
console:insertChild(-2, label)
|
||||
label:setId('consoleLabel' .. numLines)
|
||||
label:setText(text)
|
||||
label:setForegroundColor(color)
|
||||
console:insertChild(label, -1)
|
||||
label:setStyle('ConsoleLabel')
|
||||
|
||||
numLines = numLines + 1
|
||||
if numLines > maxLines then
|
||||
local firstLine = console:getChildByIndex(0)
|
||||
firstLine:destroy()
|
||||
local firstLabel = console:getChildByIndex(1)
|
||||
firstLabel:destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Console.create()
|
||||
console = loadUI("/console/console.otui")
|
||||
rootWidget:addChild(console)
|
||||
console = UI.loadAndDisplay("/console/console.otui")
|
||||
console:hide()
|
||||
|
||||
Logger.setOnLog(Console.onLog)
|
||||
|
|
|
@ -13,7 +13,9 @@ RectPanel
|
|||
anchors.fill: parent
|
||||
|
||||
UILabel
|
||||
size: 18 20
|
||||
id: commandSymbolLabel
|
||||
size: 20 16
|
||||
size fixed: true
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
margin.left: 2
|
||||
|
@ -22,11 +24,10 @@ RectPanel
|
|||
|
||||
UILineEdit
|
||||
id: commandBox
|
||||
height: 20
|
||||
height: 16
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: prev.right
|
||||
anchors.left: commandSymbolLabel.right
|
||||
anchors.right: parent.right
|
||||
margin.left: 4
|
||||
font: terminus-14px-bold
|
||||
onAction: |
|
||||
function(self)
|
||||
|
|
|
@ -13,10 +13,10 @@ Module
|
|||
require 'constants'
|
||||
require 'util'
|
||||
require 'widget'
|
||||
require 'messagebox'
|
||||
require 'ui'
|
||||
require 'messagebox/messagebox'
|
||||
require 'dispatcher'
|
||||
|
||||
rootWidget = getRootWidget()
|
||||
return true
|
||||
|
||||
onUnload: |
|
||||
|
|
|
@ -10,50 +10,33 @@ function MessageBox.create(title, text, flags)
|
|||
setmetatable(box, MessageBox)
|
||||
|
||||
-- create messagebox window
|
||||
local window = UIWindow.create()
|
||||
window:setStyle('Window')
|
||||
window:setId("messageBoxWindow")
|
||||
local window = UI.loadAndDisplayLocked('/core/messagebox/messagebox.otui')
|
||||
window:setTitle(title)
|
||||
window:centerIn("parent")
|
||||
rootWidget:addChild(window)
|
||||
rootWidget:lockChild(window)
|
||||
|
||||
-- create messagebox label
|
||||
local label = UILabel.create()
|
||||
local label = window:getChildById('messageBoxLabel')
|
||||
label:setStyle('Label')
|
||||
label:setId("messageBoxLabel")
|
||||
label:setText(text)
|
||||
label:addAnchor(AnchorHorizontalCenter, window:getId(), AnchorHorizontalCenter)
|
||||
label:addAnchor(AnchorTop, window:getId(), AnchorTop)
|
||||
label:setMargin(27, 0)
|
||||
label:resizeToText()
|
||||
window:addChild(label)
|
||||
|
||||
-- set window size based on label size
|
||||
window:setWidth(label:getWidth() + 60)
|
||||
window:setHeight(label:getHeight() + 64)
|
||||
window:updateParentLayout()
|
||||
|
||||
-- setup messagebox first button
|
||||
local button1 = UIButton.create()
|
||||
button1:setStyle('Button')
|
||||
button1:setId("messageBoxButton1")
|
||||
button1:addAnchor(AnchorBottom, window:getId(), AnchorBottom)
|
||||
button1:addAnchor(AnchorRight, window:getId(), AnchorRight)
|
||||
button1:setMargin(10)
|
||||
button1:setWidth(64)
|
||||
window:addChild(button1)
|
||||
local buttonRight = window:getChildById('messageBoxRightButton')
|
||||
|
||||
if flags == MessageBoxOk then
|
||||
button1:setText("Ok")
|
||||
buttonRight:setText("Ok")
|
||||
box.onOk = EmptyFunction
|
||||
button1.onClick = function()
|
||||
buttonRight.onClick = function()
|
||||
box.onOk()
|
||||
box:destroy()
|
||||
end
|
||||
elseif flags == MessageBoxCancel then
|
||||
button1:setText("Cancel")
|
||||
buttonRight:setText("Cancel")
|
||||
box.onCancel = EmptyFunction
|
||||
button1.onClick = function()
|
||||
buttonRight.onClick = function()
|
||||
box.onCancel()
|
||||
box:destroy()
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
Window
|
||||
id: messageBoxWindow
|
||||
anchors.centerIn: parent
|
||||
height: 80
|
||||
width: 120
|
||||
|
||||
Label
|
||||
id: messageBoxLabel
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
margin.top: 27
|
||||
margin.bottom : 27
|
||||
|
||||
Button
|
||||
id: messageBoxRightButton
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
margin.right: 10
|
||||
margin.bottom: 10
|
||||
width: 64
|
||||
visible: true
|
|
@ -8,11 +8,6 @@ Module
|
|||
dependencies:
|
||||
- core_fonts
|
||||
onLoad: |
|
||||
importStyles('buttons.otui')
|
||||
importStyles('labels.otui')
|
||||
importStyles('panels.otui')
|
||||
importStyles('separators.otui')
|
||||
importStyles('lineedits.otui')
|
||||
importStyles('windows.otui')
|
||||
require 'ui'
|
||||
return true
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ Button < UIButton
|
|||
source: /core_ui/images/button_hover.png
|
||||
border: 5
|
||||
|
||||
state.down:
|
||||
state.pressed:
|
||||
text-translate: 1 1
|
||||
border-image:
|
||||
source: /core_ui/images/button_down.png
|
|
@ -0,0 +1,5 @@
|
|||
TextList < UIWidget
|
||||
size: 200 200
|
||||
border-image:
|
||||
source: /core_ui/images/panel_flat.png
|
||||
border: 4
|
|
@ -2,3 +2,4 @@ HorizontalSeparator < UIWidget
|
|||
border-image:
|
||||
source: /core_ui/images/horizontal_separator.png
|
||||
border.top: 2
|
||||
height: 2
|
|
@ -1,6 +1,8 @@
|
|||
Window < UIWindow
|
||||
font: helvetica-12px-bold
|
||||
size: 200 200
|
||||
opacity: 255
|
||||
background-color: #ffffff
|
||||
head:
|
||||
height: 20
|
||||
border-image:
|
||||
|
@ -17,5 +19,8 @@ Window < UIWindow
|
|||
border: 4
|
||||
border.top: 0
|
||||
|
||||
state.pressed:
|
||||
opacity: 192
|
||||
|
||||
MainWindow < Window
|
||||
anchors.centerIn: parent
|
|
@ -0,0 +1,30 @@
|
|||
UI = { }
|
||||
UI.root = getRootWidget()
|
||||
|
||||
function UI.loadAndDisplayLocked(otuiFile)
|
||||
local widget = loadUI(otuiFile, UI.root)
|
||||
UI.root:lockChild(widget)
|
||||
return widget
|
||||
end
|
||||
|
||||
function UI.loadAndDisplay(otuiFile)
|
||||
local widget = loadUI(otuiFile, UI.root)
|
||||
return widget
|
||||
end
|
||||
|
||||
function UI.display(widget)
|
||||
UI.root:addChild(widget)
|
||||
end
|
||||
|
||||
function UI.displayLocked(widget)
|
||||
UI.root:addChild(widget)
|
||||
UI.root:lockChild(widget)
|
||||
end
|
||||
|
||||
importStyles('styles/buttons.otui')
|
||||
importStyles('styles/labels.otui')
|
||||
importStyles('styles/panels.otui')
|
||||
importStyles('styles/separators.otui')
|
||||
importStyles('styles/lineedits.otui')
|
||||
importStyles('styles/windows.otui')
|
||||
importStyles('styles/listboxes.otui')
|
|
@ -2,7 +2,7 @@ function EnterGame_connectToLoginServer()
|
|||
local protocolLogin = ProtocolLogin.create()
|
||||
|
||||
local recreateEnterGame = function()
|
||||
rootWidget:addChild(loadUI("/mainmenu/ui/entergamewindow.otui"))
|
||||
UI.loadAndDisplayLocked("/mainmenu/ui/entergamewindow.otui")
|
||||
end
|
||||
|
||||
local loadBox = displayCancelBox("Please wait", "Connecting..")
|
||||
|
@ -30,7 +30,7 @@ function EnterGame_connectToLoginServer()
|
|||
mainMenu:hide()
|
||||
end
|
||||
|
||||
local enterGameWindow = rootWidget:getChildById("enterGameWindow")
|
||||
local enterGameWindow = UI.root:getChildById("enterGameWindow")
|
||||
local account = enterGameWindow:getChildById("accountNameLineEdit"):getText()
|
||||
local password = enterGameWindow:getChildById("accountPasswordLineEdit"):getText()
|
||||
protocolLogin:login(account, password)
|
||||
|
|
|
@ -12,8 +12,7 @@ Module
|
|||
require('entergame')
|
||||
|
||||
if not initialized then
|
||||
mainMenu = loadUI("/mainmenu/ui/mainmenu.otui")
|
||||
getRootWidget():addChild(mainMenu)
|
||||
mainMenu = UI.loadAndDisplay("/mainmenu/ui/mainmenu.otui")
|
||||
initialized = true
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
MainWindow
|
||||
id: charactersWindow
|
||||
title: Charlist
|
||||
size: 200 250
|
||||
|
||||
TextList
|
||||
id: charactersList
|
||||
anchors.fill: parent
|
||||
margin.top: 30
|
||||
margin.bottom: 50
|
||||
margin.left: 16
|
||||
margin.right: 16
|
||||
|
||||
Button
|
||||
id: buttonOk
|
||||
text: Ok
|
||||
width: 64
|
||||
anchors.right: next.left
|
||||
anchors.bottom: parent.bottom
|
||||
margin.bottom: 16
|
||||
margin.right: 16
|
||||
|
||||
Button
|
||||
id: buttonCancel
|
||||
text: Cancel
|
||||
width: 64
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
margin.bottom: 16
|
||||
margin.right: 16
|
||||
onClick: |
|
||||
function(self)
|
||||
self:getParent():destroy()
|
||||
end
|
|
@ -1,7 +1,8 @@
|
|||
MenuButton < Button
|
||||
anchors.top: prev.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 10
|
||||
margin.bottom: 11
|
||||
margin.left: 20
|
||||
margin.right: 20
|
||||
|
||||
|
||||
Panel
|
||||
id: mainMenuBackground
|
||||
|
@ -9,6 +10,7 @@ Panel
|
|||
source: /mainmenu/ui/background.png
|
||||
smooth: true
|
||||
anchors.fill: parent
|
||||
focusable: false
|
||||
|
||||
RoundedPanel
|
||||
id: mainMenu
|
||||
|
@ -17,24 +19,20 @@ Panel
|
|||
anchors.bottom: parent.bottom
|
||||
margin.left: 60
|
||||
margin.bottom: 70
|
||||
layout: verticalBox
|
||||
|
||||
MenuButton
|
||||
text: Enter Game
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 18
|
||||
onClick: |
|
||||
local enterGameWindow = loadUI("/mainmenu/ui/entergamewindow.otui")
|
||||
rootWidget:addChild(enterGameWindow)
|
||||
GFX.fadeIn(enterGameWindow)
|
||||
onClick: UI.loadAndDisplayLocked("/mainmenu/ui/entergamewindow.otui")
|
||||
|
||||
MenuButton
|
||||
text: Options
|
||||
onClick: rootWidget:addChild(loadUI("/mainmenu/ui/optionswindow.otui"))
|
||||
onClick: UI.loadAndDisplayLocked("/mainmenu/ui/optionswindow.otui")
|
||||
|
||||
MenuButton
|
||||
text: Info
|
||||
onClick: rootWidget:addChild(loadUI("/mainmenu/ui/infowindow.otui"))
|
||||
onClick: UI.loadAndDisplayLocked("/mainmenu/ui/infowindow.otui")
|
||||
|
||||
MenuButton
|
||||
text: Exit
|
||||
|
|
|
@ -89,7 +89,7 @@ MainWindow
|
|||
onClick: displayErrorBox("Error", "Not implemented yet")
|
||||
|
||||
Label
|
||||
text: |
|
||||
text: |-
|
||||
Show the most recent
|
||||
Message of the Day
|
||||
anchors.left: prev.right
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
--UI.loadAndDisplayLocked('/mainmenu/ui/charlist.otui')
|
|
@ -0,0 +1,10 @@
|
|||
Module
|
||||
name: playground
|
||||
autoLoad: true
|
||||
dependencies:
|
||||
- core
|
||||
|
||||
onLoad: |
|
||||
require 'playground'
|
||||
return true
|
||||
|
|
@ -12,6 +12,7 @@ enum LogLevel {
|
|||
};
|
||||
|
||||
enum AlignmentFlag {
|
||||
AlignNone = 0,
|
||||
AlignLeft = 1,
|
||||
AlignRight = 2,
|
||||
AlignTop = 4,
|
||||
|
@ -39,6 +40,45 @@ enum AnchorEdge {
|
|||
AnchorHorizontalCenter,
|
||||
};
|
||||
|
||||
enum FocusReason {
|
||||
MouseFocusReason = 0,
|
||||
TabFocusReason,
|
||||
ActiveFocusReason,
|
||||
OtherFocusReason
|
||||
};
|
||||
|
||||
enum MouseButton {
|
||||
MouseNoButton = 0,
|
||||
MouseLeftButton,
|
||||
MouseRightButton,
|
||||
MouseMidButton
|
||||
};
|
||||
|
||||
enum MouseWheelDirection {
|
||||
MouseNoWheel = 0,
|
||||
MouseWheelUp,
|
||||
MouseWheelDown
|
||||
};
|
||||
|
||||
enum KeyboardModifier {
|
||||
KeyboardNoModifier = 0,
|
||||
KeyboardCtrlModifier = 1,
|
||||
KeyboardAltModifier = 2,
|
||||
KeyboardShiftModifier = 4
|
||||
};
|
||||
|
||||
enum WidgetState {
|
||||
DefaultState = 0,
|
||||
ActiveState = 1,
|
||||
FocusState = 2,
|
||||
HoverState = 4,
|
||||
PressedState = 8,
|
||||
DisabledState = 16
|
||||
//FirstState,
|
||||
//MiddleState,
|
||||
//LastState,
|
||||
//AlternateState
|
||||
};
|
||||
|
||||
//}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ void Logger::log(LogLevel level, std::string message)
|
|||
m_logMessages.push_back(LogMessage(level, message, now));
|
||||
|
||||
if(m_onLog)
|
||||
g_dispatcher.addEvent(std::bind(m_onLog, level, message, now));
|
||||
m_onLog(level, message, now);
|
||||
}
|
||||
|
||||
if(level == LogFatal) {
|
||||
|
@ -46,7 +46,8 @@ void Logger::logFunc(LogLevel level, const std::string& message, std::string pre
|
|||
void Logger::fireOldMessages()
|
||||
{
|
||||
if(m_onLog) {
|
||||
for(const LogMessage& logMessage : m_logMessages)
|
||||
g_dispatcher.addEvent(std::bind(m_onLog, logMessage.level, logMessage.message, logMessage.when));
|
||||
auto backup = m_logMessages;
|
||||
for(const LogMessage& logMessage : backup)
|
||||
m_onLog(logMessage.level, logMessage.message, logMessage.when);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
// boost utilities
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/any.hpp>
|
||||
|
||||
// global constants
|
||||
#include "const.h"
|
||||
|
|
|
@ -60,10 +60,3 @@ FontPtr FontManager::getFont(const std::string& fontName)
|
|||
return getDefaultFont();
|
||||
}
|
||||
|
||||
FontPtr FontManager::getDefaultFont()
|
||||
{
|
||||
// default font should always exists, otherwise the app may crash
|
||||
if(!m_defaultFont)
|
||||
logFatal("no default font to display, cannot continue to run");
|
||||
return m_defaultFont;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public:
|
|||
|
||||
bool fontExists(const std::string& fontName);
|
||||
FontPtr getFont(const std::string& fontName);
|
||||
FontPtr getDefaultFont();
|
||||
FontPtr getDefaultFont() { return m_defaultFont; }
|
||||
|
||||
void setDefaultFont(const std::string& fontName) { m_defaultFont = getFont(fontName); }
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ void LuaInterface::registerFunctions()
|
|||
{
|
||||
// UIWidget
|
||||
g_lua.registerClass<UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create);
|
||||
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create<UIWidget>);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getId", &UIWidget::getId);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
|
||||
|
@ -39,41 +39,41 @@ void LuaInterface::registerFunctions()
|
|||
g_lua.bindClassMemberFunction<UIWidget>("setMarginRight", &UIWidget::setMarginRight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("show", &UIWidget::show);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("fill", &UIWidget::fill);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("centerIn", &UIWidget::centerIn);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("addAnchor", &UIWidget::addAnchor);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getChildById", &UIWidget::getChildById);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getChildByIndex", &UIWidget::getChildByIndex);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getChildCount", &UIWidget::getChildCount);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("insertChild", &UIWidget::insertChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("removeChild", &UIWidget::removeChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("addChild", &UIWidget::addChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("lockChild", &UIWidget::lockChild);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("updateLayout", &UIWidget::updateLayout);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("updateParentLayout", &UIWidget::updateParentLayout);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy);
|
||||
|
||||
|
||||
// UILabel
|
||||
g_lua.registerClass<UILabel, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UILabel>("create", &UILabel::create);
|
||||
g_lua.bindClassStaticFunction<UILabel>("create", &UIWidget::create<UILabel>);
|
||||
g_lua.bindClassMemberFunction<UILabel>("getText", &UILabel::getText);
|
||||
g_lua.bindClassMemberFunction<UILabel>("setText", &UILabel::setText);
|
||||
g_lua.bindClassMemberFunction("resizeToText", &UILabel::resizeToText);
|
||||
|
||||
// UIButton
|
||||
g_lua.registerClass<UIButton, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIButton>("create", &UIButton::create);
|
||||
g_lua.bindClassStaticFunction<UIButton>("create", &UIWidget::create<UIButton>);
|
||||
g_lua.bindClassMemberFunction<UIButton>("getText", &UIButton::getText);
|
||||
g_lua.bindClassMemberFunction<UIButton>("setText", &UIButton::setText);
|
||||
|
||||
// UILineEdit
|
||||
g_lua.registerClass<UILineEdit, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UILineEdit>("create", &UILineEdit::create);
|
||||
g_lua.bindClassStaticFunction<UILineEdit>("create", &UIWidget::create<UILineEdit>);
|
||||
g_lua.bindClassMemberFunction<UILineEdit>("getText", &UILineEdit::getText);
|
||||
g_lua.bindClassMemberFunction<UILineEdit>("setText", &UILineEdit::setText);
|
||||
g_lua.bindClassMemberFunction<UILineEdit>("clearText", &UILineEdit::clearText);
|
||||
|
||||
// UIWindow
|
||||
g_lua.registerClass<UIWindow, UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIWindow>("create", &UIWindow::create);
|
||||
g_lua.bindClassStaticFunction<UIWindow>("create", &UIWidget::create<UIWindow>);
|
||||
g_lua.bindClassMemberFunction<UIWindow>("getTitle", &UIWindow::getTitle);
|
||||
g_lua.bindClassMemberFunction<UIWindow>("setTitle", &UIWindow::setTitle);
|
||||
|
||||
|
@ -95,7 +95,7 @@ void LuaInterface::registerFunctions()
|
|||
g_lua.bindGlobalFunction("importFont", std::bind(&FontManager::importFont, &g_fonts, _1));
|
||||
g_lua.bindGlobalFunction("importStyles", std::bind(&UIManager::importStyles, &g_ui, _1));
|
||||
g_lua.bindGlobalFunction("setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, _1));
|
||||
g_lua.bindGlobalFunction("loadUI", std::bind(&UIManager::loadUI, &g_ui, _1));
|
||||
g_lua.bindGlobalFunction("loadUI", std::bind(&UIManager::loadUI, &g_ui, _1, _2));
|
||||
g_lua.bindGlobalFunction("getRootWidget", std::bind(&UIManager::getRootWidget, &g_ui));
|
||||
g_lua.bindGlobalFunction("addEvent", std::bind(&EventDispatcher::addEvent, &g_dispatcher, _1, false));
|
||||
g_lua.bindGlobalFunction("scheduleEvent", std::bind(&EventDispatcher::scheduleEvent, &g_dispatcher, _1, _2));
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
|
||||
void hideMouseCursor();
|
||||
void showMouseCursor();
|
||||
Point getMouseCursorPos();
|
||||
|
||||
/// Enable or disable vertical synchronization
|
||||
void setVerticalSync(bool enable);
|
||||
|
|
|
@ -41,7 +41,7 @@ struct X11PlatformPrivate {
|
|||
int lastTicks;
|
||||
std::string clipboardText;
|
||||
std::map<int, uchar> keyMap;
|
||||
PlatformListener* listener;
|
||||
PlatformEvent inputEvent;
|
||||
} x11;
|
||||
|
||||
Platform g_platform;
|
||||
|
@ -261,7 +261,7 @@ void Platform::terminate()
|
|||
void Platform::poll()
|
||||
{
|
||||
XEvent event, peekevent;
|
||||
static PlatformEvent inputEvent;
|
||||
PlatformEvent& inputEvent = x11.inputEvent;
|
||||
while(XPending(x11.display) > 0) {
|
||||
XNextEvent(x11.display, &event);
|
||||
|
||||
|
@ -336,14 +336,13 @@ void Platform::poll()
|
|||
//logDebug("char: ", buf[0], " code: ", (uint)buf[0]);
|
||||
inputEvent.keychar = buf[0];
|
||||
}
|
||||
}
|
||||
|
||||
// unmask Shift/Lock to get expected results
|
||||
event.xkey.state &= ~(ShiftMask | LockMask);
|
||||
} else {
|
||||
//event.xkey.state &= ~(ShiftMask | LockMask);
|
||||
len = XLookupString(&event.xkey, buf, sizeof(buf), &keysym, 0);
|
||||
|
||||
if(inputEvent.keychar == 0)
|
||||
if(len > 0 && (uchar)inputEvent.keychar >= 32)
|
||||
inputEvent.keychar = (len > 0) ? buf[0] : 0;
|
||||
}
|
||||
|
||||
if(x11.keyMap.find(keysym) != x11.keyMap.end())
|
||||
inputEvent.keycode = x11.keyMap[keysym];
|
||||
|
@ -734,6 +733,11 @@ void Platform::showMouseCursor()
|
|||
}
|
||||
}
|
||||
|
||||
Point Platform::getMouseCursorPos()
|
||||
{
|
||||
return x11.inputEvent.mousePos;
|
||||
}
|
||||
|
||||
void Platform::setVerticalSync(bool enable)
|
||||
{
|
||||
typedef GLint (*glSwapIntervalProc)(GLint);
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef FRAMEWORK_UI_CONST_H
|
||||
#define FRAMEWORK_UI_CONST_H
|
||||
|
||||
// namespace ui {
|
||||
|
||||
namespace UI {
|
||||
|
||||
enum FocusReason {
|
||||
MouseFocusReason = 0,
|
||||
TabFocusReason,
|
||||
ActiveFocusReason,
|
||||
OtherFocusReason
|
||||
};
|
||||
|
||||
enum MouseButton {
|
||||
MouseNoButton = 0,
|
||||
MouseLeftButton,
|
||||
MouseRightButton,
|
||||
MouseMidButton
|
||||
};
|
||||
|
||||
enum MouseWheelDirection {
|
||||
MouseNoWheel = 0,
|
||||
MouseWheelUp,
|
||||
MouseWheelDown
|
||||
};
|
||||
|
||||
enum KeyboardModifier {
|
||||
KeyboardNoModifier = 0,
|
||||
KeyboardCtrlModifier = 1,
|
||||
KeyboardAltModifier = 2,
|
||||
KeyboardShiftModifier = 4
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
#endif
|
|
@ -2,16 +2,17 @@
|
|||
#define FRAMEWORK_UI_DECLARATIONS_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include "const.h"
|
||||
#include <framework/platform/platformevent.h>
|
||||
|
||||
class UIManager;
|
||||
class UIAnchor;
|
||||
class UIWidget;
|
||||
class UILabel;
|
||||
class UIButton;
|
||||
class UILineEdit;
|
||||
class UIWindow;
|
||||
class UILayout;
|
||||
class UIVerticalLayout;
|
||||
class UIAnchorLayout;
|
||||
|
||||
typedef std::shared_ptr<UIWidget> UIWidgetPtr;
|
||||
typedef std::weak_ptr<UIWidget> UIWidgetWeakPtr;
|
||||
|
@ -20,8 +21,10 @@ typedef std::shared_ptr<UILabel> UILabelPtr;
|
|||
typedef std::shared_ptr<UIButton> UIButtonPtr;
|
||||
typedef std::shared_ptr<UILineEdit> UILineEditPtr;
|
||||
typedef std::shared_ptr<UIWindow> UIWindowPtr;
|
||||
typedef std::shared_ptr<UILayout> UILayoutPtr;
|
||||
typedef std::shared_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
|
||||
typedef std::shared_ptr<UIAnchorLayout> UIAnchorLayoutPtr;
|
||||
|
||||
typedef std::vector<UIAnchor> UIAnchorList;
|
||||
typedef std::deque<UIWidgetPtr> UIWidgetList;
|
||||
typedef std::deque<UIWidgetWeakPtr> UIWeakWidgetList;
|
||||
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
#include "uianchor.h"
|
||||
#include "uiwidget.h"
|
||||
|
||||
UIAnchor::UIAnchor(AnchorEdge anchoredEdge, const std::string& hookedWidgetId, AnchorEdge hookedEdge) :
|
||||
m_anchoredEdge(anchoredEdge), m_hookedWidgetId(hookedWidgetId), m_hookedEdge(hookedEdge) {
|
||||
}
|
||||
|
||||
int UIAnchor::getHookedPoint() const {
|
||||
UIWidgetPtr hookedWidget = getHookedWidget();
|
||||
|
||||
if(hookedWidget) {
|
||||
switch(m_hookedEdge) {
|
||||
case AnchorLeft:
|
||||
return hookedWidget->getRect().left();
|
||||
case AnchorRight:
|
||||
return hookedWidget->getRect().right();
|
||||
case AnchorTop:
|
||||
return hookedWidget->getRect().top();
|
||||
case AnchorBottom:
|
||||
return hookedWidget->getRect().bottom();
|
||||
case AnchorHorizontalCenter:
|
||||
return hookedWidget->getRect().horizontalCenter();
|
||||
case AnchorVerticalCenter:
|
||||
return hookedWidget->getRect().verticalCenter();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_POINT;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef UIANCHOR_H
|
||||
#define UIANCHOR_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class UIAnchor
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
INVALID_POINT = -999999
|
||||
};
|
||||
|
||||
UIAnchor(AnchorEdge anchoredEdge, const std::string& hookedWidgetId, AnchorEdge hookedEdge);
|
||||
|
||||
AnchorEdge getAnchoredEdge() const { return m_anchoredEdge; }
|
||||
UIWidgetPtr getHookedWidget() const { return m_hookedWidget.lock(); }
|
||||
std::string getHookedWidgetId() const { return m_hookedWidgetId; }
|
||||
int getHookedPoint() const;
|
||||
|
||||
void setHookedWidget(const UIWidgetPtr hookedWidget) { m_hookedWidget = hookedWidget; }
|
||||
|
||||
private:
|
||||
AnchorEdge m_anchoredEdge;
|
||||
UIWidgetWeakPtr m_hookedWidget;
|
||||
std::string m_hookedWidgetId;
|
||||
AnchorEdge m_hookedEdge;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,190 @@
|
|||
#include "uianchorlayout.h"
|
||||
#include "uiwidget.h"
|
||||
|
||||
void UIAnchorGroup::addAnchor(const UIAnchor& anchor)
|
||||
{
|
||||
// duplicated anchors must be replaced
|
||||
for(UIAnchor& other : m_anchors) {
|
||||
if(other.getAnchoredEdge() == anchor.getAnchoredEdge()) {
|
||||
other = anchor;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_anchors.push_back(anchor);
|
||||
}
|
||||
|
||||
void UIAnchorLayout::addAnchor(const UIWidgetPtr& anchoredWidget, AnchorEdge anchoredEdge,
|
||||
const std::string& hookedWidgetId, AnchorEdge hookedEdge)
|
||||
{
|
||||
if(!anchoredWidget)
|
||||
return;
|
||||
|
||||
assert(anchoredWidget != getParentWidget());
|
||||
|
||||
UIAnchor anchor(anchoredEdge, hookedWidgetId, hookedEdge);
|
||||
UIAnchorGroup& anchorGroup = m_anchorsGroups[anchoredWidget];
|
||||
anchorGroup.addAnchor(anchor);
|
||||
|
||||
// layout must be updated because a new anchor got in
|
||||
update();
|
||||
}
|
||||
|
||||
void UIAnchorLayout::removeAnchors(const UIWidgetPtr& anchoredWidget)
|
||||
{
|
||||
m_anchorsGroups.erase(anchoredWidget);
|
||||
update();
|
||||
}
|
||||
|
||||
void UIAnchorLayout::centerIn(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId)
|
||||
{
|
||||
addAnchor(anchoredWidget, AnchorHorizontalCenter, hookedWidgetId, AnchorHorizontalCenter);
|
||||
addAnchor(anchoredWidget, AnchorVerticalCenter, hookedWidgetId, AnchorVerticalCenter);
|
||||
}
|
||||
|
||||
void UIAnchorLayout::fill(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId)
|
||||
{
|
||||
addAnchor(anchoredWidget, AnchorLeft, hookedWidgetId, AnchorLeft);
|
||||
addAnchor(anchoredWidget, AnchorRight, hookedWidgetId, AnchorRight);
|
||||
addAnchor(anchoredWidget, AnchorTop, hookedWidgetId, AnchorTop);
|
||||
addAnchor(anchoredWidget, AnchorBottom, hookedWidgetId, AnchorBottom);
|
||||
}
|
||||
|
||||
void UIAnchorLayout::update()
|
||||
{
|
||||
// reset all anchors groups update state
|
||||
for(auto& it : m_anchorsGroups) {
|
||||
UIAnchorGroup& anchorGroup = it.second;
|
||||
anchorGroup.setUpdated(false);
|
||||
}
|
||||
|
||||
// update all anchors
|
||||
for(auto& it : m_anchorsGroups) {
|
||||
const UIWidgetPtr& widget = it.first;
|
||||
UIAnchorGroup& anchorGroup = it.second;
|
||||
if(!anchorGroup.isUpdated())
|
||||
updateWidget(widget, anchorGroup);
|
||||
}
|
||||
}
|
||||
|
||||
void UIAnchorLayout::addWidget(const UIWidgetPtr& widget)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void UIAnchorLayout::removeWidget(const UIWidgetPtr& widget)
|
||||
{
|
||||
removeAnchors(widget);
|
||||
}
|
||||
|
||||
void UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup)
|
||||
{
|
||||
UIWidgetPtr parentWidget = getParentWidget();
|
||||
Rect newRect = widget->getRect();
|
||||
bool verticalMoved = false;
|
||||
bool horizontalMoved = false;
|
||||
|
||||
// calculates new rect based on anchors
|
||||
for(const UIAnchor& anchor : anchorGroup.getAnchors()) {
|
||||
// skip invalid anchors
|
||||
if(anchor.getHookedEdge() == AnchorNone)
|
||||
continue;
|
||||
|
||||
// determine hooked widget
|
||||
UIWidgetPtr hookedWidget;
|
||||
if(parentWidget) {
|
||||
if(anchor.getHookedWidgetId() == "parent")
|
||||
hookedWidget = parentWidget;
|
||||
else if(anchor.getHookedWidgetId() == "next")
|
||||
hookedWidget = parentWidget->getChildAfter(widget);
|
||||
else if(anchor.getHookedWidgetId() == "prev")
|
||||
hookedWidget = parentWidget->getChildBefore(widget);
|
||||
else
|
||||
hookedWidget = parentWidget->getChildById(anchor.getHookedWidgetId());
|
||||
}
|
||||
|
||||
// skip invalid anchors
|
||||
if(!hookedWidget)
|
||||
continue;
|
||||
|
||||
if(hookedWidget != getParentWidget()) {
|
||||
// update this hooked widget anchors
|
||||
auto it = m_anchorsGroups.find(hookedWidget);
|
||||
if(it != m_anchorsGroups.end()) {
|
||||
UIAnchorGroup& hookedAnchorGroup = it->second;
|
||||
if(!hookedAnchorGroup.isUpdated())
|
||||
updateWidget(hookedWidget, hookedAnchorGroup);
|
||||
}
|
||||
}
|
||||
|
||||
// determine hooked widget edge point
|
||||
int point = 0;
|
||||
switch(anchor.getHookedEdge()) {
|
||||
case AnchorLeft:
|
||||
point = hookedWidget->getRect().left();
|
||||
break;
|
||||
case AnchorRight:
|
||||
point = hookedWidget->getRect().right();
|
||||
break;
|
||||
case AnchorTop:
|
||||
point = hookedWidget->getRect().top();
|
||||
break;
|
||||
case AnchorBottom:
|
||||
point = hookedWidget->getRect().bottom();
|
||||
break;
|
||||
case AnchorHorizontalCenter:
|
||||
point = hookedWidget->getRect().horizontalCenter();
|
||||
break;
|
||||
case AnchorVerticalCenter:
|
||||
point = hookedWidget->getRect().verticalCenter();
|
||||
break;
|
||||
default:
|
||||
// must never happens
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(anchor.getAnchoredEdge()) {
|
||||
case AnchorHorizontalCenter:
|
||||
newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight());
|
||||
horizontalMoved = true;
|
||||
break;
|
||||
case AnchorLeft:
|
||||
if(!horizontalMoved) {
|
||||
newRect.moveLeft(point + widget->getMarginLeft());
|
||||
horizontalMoved = true;
|
||||
} else
|
||||
newRect.setLeft(point + widget->getMarginLeft());
|
||||
break;
|
||||
case AnchorRight:
|
||||
if(!horizontalMoved) {
|
||||
newRect.moveRight(point - widget->getMarginRight());
|
||||
horizontalMoved = true;
|
||||
} else
|
||||
newRect.setRight(point - widget->getMarginRight());
|
||||
break;
|
||||
case AnchorVerticalCenter:
|
||||
newRect.moveVerticalCenter(point + widget->getMarginTop() - widget->getMarginBottom());
|
||||
verticalMoved = true;
|
||||
break;
|
||||
case AnchorTop:
|
||||
if(!verticalMoved) {
|
||||
newRect.moveTop(point + widget->getMarginTop());
|
||||
verticalMoved = true;
|
||||
} else
|
||||
newRect.setTop(point + widget->getMarginTop());
|
||||
break;
|
||||
case AnchorBottom:
|
||||
if(!verticalMoved) {
|
||||
newRect.moveBottom(point - widget->getMarginBottom());
|
||||
verticalMoved = true;
|
||||
} else
|
||||
newRect.setBottom(point - widget->getMarginBottom());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
widget->setRect(newRect);
|
||||
anchorGroup.setUpdated(true);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef UIANCHORLAYOUT_H
|
||||
#define UIANCHORLAYOUT_H
|
||||
|
||||
#include "uilayout.h"
|
||||
|
||||
class UIAnchor
|
||||
{
|
||||
public:
|
||||
UIAnchor(AnchorEdge anchoredEdge, const std::string& hookedWidgetId, AnchorEdge hookedEdge) :
|
||||
m_anchoredEdge(anchoredEdge), m_hookedEdge(hookedEdge), m_hookedWidgetId(hookedWidgetId) { }
|
||||
|
||||
AnchorEdge getAnchoredEdge() const { return m_anchoredEdge; }
|
||||
std::string getHookedWidgetId() const { return m_hookedWidgetId; }
|
||||
AnchorEdge getHookedEdge() const { return m_hookedEdge; }
|
||||
|
||||
private:
|
||||
AnchorEdge m_anchoredEdge;
|
||||
AnchorEdge m_hookedEdge;
|
||||
std::string m_hookedWidgetId;
|
||||
};
|
||||
|
||||
class UIAnchorGroup
|
||||
{
|
||||
public:
|
||||
UIAnchorGroup() : m_updated(true) { }
|
||||
|
||||
void addAnchor(const UIAnchor& anchor);
|
||||
const std::vector<UIAnchor>& getAnchors() const { return m_anchors; }
|
||||
bool isUpdated() const { return m_updated; }
|
||||
void setUpdated(bool updated) { m_updated = updated; }
|
||||
|
||||
private:
|
||||
std::vector<UIAnchor> m_anchors;
|
||||
bool m_updated;
|
||||
};
|
||||
|
||||
class UIAnchorLayout : public UILayout
|
||||
{
|
||||
public:
|
||||
UIAnchorLayout(UIWidgetPtr parentWidget) : UILayout(parentWidget) { }
|
||||
|
||||
void addAnchor(const UIWidgetPtr& anchoredWidget, AnchorEdge anchoredEdge,
|
||||
const std::string& hookedWidgetId, AnchorEdge hookedEdge);
|
||||
void removeAnchors(const UIWidgetPtr& anchoredWidget);
|
||||
void centerIn(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId);
|
||||
void fill(const UIWidgetPtr& anchoredWidget, const std::string& hookedWidgetId);
|
||||
|
||||
void update();
|
||||
void addWidget(const UIWidgetPtr& widget);
|
||||
void removeWidget(const UIWidgetPtr& widget);
|
||||
|
||||
UIAnchorLayoutPtr asUIAnchorLayout() { return std::static_pointer_cast<UIAnchorLayout>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
void updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup);
|
||||
std::map<UIWidgetPtr, UIAnchorGroup> m_anchorsGroups;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,96 +5,44 @@
|
|||
#include <framework/luascript/luainterface.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
||||
UIButton::UIButton()
|
||||
void UIButton::setup()
|
||||
{
|
||||
m_state = ButtonUp;
|
||||
m_focusable = false;
|
||||
UIWidget::setup();
|
||||
setFocusable(false);
|
||||
|
||||
// by default, all callbacks call lua fields
|
||||
m_onClick = [this]() { this->callLuaField("onClick"); };
|
||||
}
|
||||
|
||||
UIButtonPtr UIButton::create()
|
||||
void UIButton::render()
|
||||
{
|
||||
UIButtonPtr button(new UIButton);
|
||||
return button;
|
||||
UIWidget::render();
|
||||
Rect textRect = m_rect;
|
||||
textRect.translate(m_textTranslate);
|
||||
m_font->renderText(m_text, textRect, AlignCenter, m_foregroundColor);
|
||||
}
|
||||
|
||||
void UIButton::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
for(int i=0; i<3; ++i) {
|
||||
m_statesStyle[i].image = m_image;
|
||||
m_statesStyle[i].color = m_backgroundColor;
|
||||
m_statesStyle[i].foregroundColor = m_foregroundColor;
|
||||
m_statesStyle[i].textTranslate = Point(0,0);
|
||||
}
|
||||
|
||||
if(OTMLNodePtr node = styleNode->get("state.up"))
|
||||
loadStateStyle(m_statesStyle[ButtonUp], node);
|
||||
if(OTMLNodePtr node = styleNode->get("state.hover"))
|
||||
loadStateStyle(m_statesStyle[ButtonHover], node);
|
||||
if(OTMLNodePtr node = styleNode->get("state.down"))
|
||||
loadStateStyle(m_statesStyle[ButtonDown], node);
|
||||
|
||||
m_text = styleNode->valueAt("text", fw::empty_string);
|
||||
|
||||
if(OTMLNodePtr node = styleNode->get("onClick")) {
|
||||
for(OTMLNodePtr node : styleNode->children()) {
|
||||
if(node->tag() == "text-translate") {
|
||||
m_textTranslate = node->value<Point>();
|
||||
} else if(node->tag() == "text") {
|
||||
m_text = node->value();
|
||||
} else if(node->tag() == "onClick") {
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
luaSetField(node->tag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIButton::loadStateStyle(ButtonStateStyle& stateStyle, const OTMLNodePtr& stateStyleNode)
|
||||
bool UIButton::onMouseRelease(const Point& mousePos, MouseButton button)
|
||||
{
|
||||
if(OTMLNodePtr node = stateStyleNode->get("border-image"))
|
||||
stateStyle.image = BorderImage::loadFromOTML(node);
|
||||
if(OTMLNodePtr node = stateStyleNode->get("image"))
|
||||
stateStyle.image = Image::loadFromOTML(node);
|
||||
stateStyle.textTranslate = stateStyleNode->valueAt("text-translate", Point());
|
||||
stateStyle.color = stateStyleNode->valueAt("font-color", m_foregroundColor);
|
||||
stateStyle.color = stateStyleNode->valueAt("color", m_backgroundColor);
|
||||
}
|
||||
|
||||
void UIButton::render()
|
||||
{
|
||||
UIWidget::render();
|
||||
|
||||
const ButtonStateStyle& currentStyle = m_statesStyle[m_state];
|
||||
Rect textRect = getRect();
|
||||
|
||||
if(currentStyle.image) {
|
||||
g_graphics.bindColor(currentStyle.color);
|
||||
currentStyle.image->draw(textRect);
|
||||
}
|
||||
|
||||
textRect.translate(currentStyle.textTranslate);
|
||||
m_font->renderText(m_text, textRect, AlignCenter, currentStyle.foregroundColor);
|
||||
}
|
||||
|
||||
void UIButton::onHoverChange(bool hovered)
|
||||
{
|
||||
if(hovered && m_state == ButtonUp)
|
||||
m_state = ButtonHover;
|
||||
else if(m_state == ButtonHover)
|
||||
m_state = ButtonUp;
|
||||
}
|
||||
|
||||
bool UIButton::onMousePress(const Point& mousePos, UI::MouseButton button)
|
||||
{
|
||||
if(button == UI::MouseLeftButton) {
|
||||
m_state = ButtonDown;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UIButton::onMouseRelease(const Point& mousePos, UI::MouseButton button)
|
||||
{
|
||||
if(m_state == ButtonDown) {
|
||||
if(isPressed()) {
|
||||
if(m_onClick && getRect().contains(mousePos))
|
||||
m_onClick();
|
||||
m_state = (isHovered() && isEnabled()) ? ButtonHover : ButtonUp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -5,26 +5,8 @@
|
|||
|
||||
class UIButton : public UIWidget
|
||||
{
|
||||
struct ButtonStateStyle {
|
||||
ImagePtr image;
|
||||
Point textTranslate;
|
||||
Color foregroundColor;
|
||||
Color color;
|
||||
};
|
||||
|
||||
enum ButtonState {
|
||||
ButtonUp = 0,
|
||||
ButtonDown,
|
||||
ButtonHover
|
||||
};
|
||||
|
||||
public:
|
||||
UIButton();
|
||||
|
||||
static UIButtonPtr create();
|
||||
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
void loadStateStyle(ButtonStateStyle& stateStyle, const OTMLNodePtr& stateStyleNode);
|
||||
virtual void setup();
|
||||
virtual void render();
|
||||
|
||||
void setOnClick(const SimpleCallback& onClick) { m_onClick = onClick; }
|
||||
|
@ -32,18 +14,15 @@ public:
|
|||
|
||||
SimpleCallback getOnClick() const { return m_onClick; }
|
||||
std::string getText() const { return m_text; }
|
||||
ButtonState getState() const { return m_state; }
|
||||
|
||||
UIButtonPtr asUIButton() { return std::static_pointer_cast<UIButton>(shared_from_this()); }
|
||||
|
||||
protected:
|
||||
virtual void onHoverChange(bool hovered);
|
||||
virtual bool onMousePress(const Point& mousePos, UI::MouseButton button);
|
||||
virtual bool onMouseRelease(const Point& mousePos, UI::MouseButton button);
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual bool onMouseRelease(const Point& mousePos, MouseButton button);
|
||||
|
||||
ButtonState m_state;
|
||||
ButtonStateStyle m_statesStyle[3];
|
||||
SimpleCallback m_onClick;
|
||||
Point m_textTranslate;
|
||||
std::string m_text;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,35 +2,11 @@
|
|||
#include <framework/graphics/font.h>
|
||||
#include <framework/otml/otmlnode.h>
|
||||
|
||||
UILabel::UILabel()
|
||||
void UILabel::setup()
|
||||
{
|
||||
m_align = AlignLeft;
|
||||
m_focusable = false;
|
||||
}
|
||||
|
||||
UILabelPtr UILabel::create()
|
||||
{
|
||||
UILabelPtr label(new UILabel);
|
||||
return label;
|
||||
}
|
||||
|
||||
void UILabel::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
m_text = styleNode->valueAt("text", m_text);
|
||||
|
||||
if(styleNode->hasChildAt("align"))
|
||||
m_align = fw::translateAlignment(styleNode->valueAt("align"));
|
||||
|
||||
// auto resize if needed
|
||||
if(!m_text.empty() && !m_rect.isValid()) {
|
||||
Size textSize = m_font->calculateTextRectSize(m_text);
|
||||
if(m_rect.width() <= 0)
|
||||
m_rect.setWidth(textSize.width());
|
||||
if(m_rect.height() <= 0)
|
||||
m_rect.setHeight(textSize.height());
|
||||
}
|
||||
UIWidget::setup();
|
||||
setFocusable(false);
|
||||
setAlign(AlignLeft);
|
||||
}
|
||||
|
||||
void UILabel::render()
|
||||
|
@ -39,7 +15,35 @@ void UILabel::render()
|
|||
m_font->renderText(m_text, m_rect, m_align, m_foregroundColor);
|
||||
}
|
||||
|
||||
void UILabel::setText(const std::string& text)
|
||||
{
|
||||
m_text = text;
|
||||
|
||||
// auto resize
|
||||
if(!m_fixedSize)
|
||||
resizeToText();
|
||||
else if(!m_rect.isValid()) {
|
||||
Size textSize = m_font->calculateTextRectSize(m_text);
|
||||
if(m_rect.width() <= 0)
|
||||
m_rect.setWidth(textSize.width());
|
||||
if(m_rect.height() <= 0)
|
||||
m_rect.setHeight(textSize.height());
|
||||
}
|
||||
}
|
||||
|
||||
void UILabel::resizeToText()
|
||||
{
|
||||
resize(m_font->calculateTextRectSize(m_text));
|
||||
}
|
||||
|
||||
void UILabel::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "text")
|
||||
setText(node->value());
|
||||
else if(node->tag() == "align")
|
||||
setAlign(fw::translateAlignment(node->value()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,21 +6,20 @@
|
|||
class UILabel : public UIWidget
|
||||
{
|
||||
public:
|
||||
UILabel();
|
||||
|
||||
static UILabelPtr create();
|
||||
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void setup();
|
||||
virtual void render();
|
||||
|
||||
void resizeToText();
|
||||
|
||||
void setText(const std::string& text) { m_text = text; }
|
||||
void setText(const std::string& text);
|
||||
void setAlign(AlignmentFlag align) { m_align = align; }
|
||||
|
||||
std::string getText() const { return m_text; }
|
||||
AlignmentFlag getAlign() const { return m_align; }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
|
||||
private:
|
||||
std::string m_text;
|
||||
AlignmentFlag m_align;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "uilayout.h"
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef UILAYOUT_H
|
||||
#define UILAYOUT_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/luascript/luaobject.h>
|
||||
|
||||
class UILayout : public LuaObject
|
||||
{
|
||||
public:
|
||||
UILayout(UIWidgetPtr parentWidget) : m_parentWidget(parentWidget) { }
|
||||
|
||||
virtual void update() = 0;
|
||||
virtual void addWidget(const UIWidgetPtr& widget) = 0;
|
||||
virtual void removeWidget(const UIWidgetPtr& widget) = 0;
|
||||
|
||||
UIWidgetPtr getParentWidget() { return m_parentWidget.lock(); }
|
||||
|
||||
virtual UIAnchorLayoutPtr asUIAnchorLayout() { return nullptr; }
|
||||
|
||||
protected:
|
||||
UIWidgetWeakPtr m_parentWidget;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -15,19 +15,10 @@ UILineEdit::UILineEdit()
|
|||
m_onAction = [this]() { this->callLuaField("onAction"); };
|
||||
}
|
||||
|
||||
UILineEditPtr UILineEdit::create()
|
||||
{
|
||||
UILineEditPtr lineEdit(new UILineEdit);
|
||||
return lineEdit;
|
||||
}
|
||||
|
||||
void UILineEdit::render()
|
||||
{
|
||||
UIWidget::render();
|
||||
|
||||
if(!m_rect.isValid())
|
||||
return;
|
||||
|
||||
//TODO: text rendering could be much optimized by using vertex buffer or caching the render into a texture
|
||||
|
||||
int textLength = m_text.length();
|
||||
|
@ -37,10 +28,10 @@ void UILineEdit::render()
|
|||
g_graphics.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||
|
||||
// render cursor
|
||||
if(isExplicitlyEnabled() && hasFocus() && m_cursorPos >= 0) {
|
||||
if(isExplicitlyEnabled() && isActive() && m_cursorPos >= 0) {
|
||||
assert(m_cursorPos <= textLength);
|
||||
// draw every 330ms
|
||||
const int delay = 330;
|
||||
// draw every 333ms
|
||||
const int delay = 333;
|
||||
int ticks = g_platform.getTicks();
|
||||
if(ticks - m_cursorTicks <= delay) {
|
||||
Rect cursorRect;
|
||||
|
@ -61,7 +52,7 @@ void UILineEdit::update()
|
|||
int textLength = m_text.length();
|
||||
|
||||
// prevent glitches
|
||||
if(!m_rect.isValid())
|
||||
if(m_rect.isEmpty())
|
||||
return;
|
||||
|
||||
// map glyphs positions
|
||||
|
@ -331,24 +322,27 @@ void UILineEdit::onStyleApply(const OTMLNodePtr& styleNode)
|
|||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
setText(styleNode->valueAt("text", getText()));
|
||||
|
||||
if(OTMLNodePtr node = styleNode->get("onAction")) {
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
if(node->tag() == "text") {
|
||||
setText(node->value());
|
||||
setCursorPos(m_text.length());
|
||||
} else if(node->tag() == "onAction") {
|
||||
g_lua.loadFunction(node->value(), "@" + node->source() + "[" + node->tag() + "]");
|
||||
luaSetField(node->tag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UILineEdit::onGeometryUpdate(const Rect& oldRect, const Rect& newRect)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void UILineEdit::onFocusChange(bool focused, UI::FocusReason reason)
|
||||
void UILineEdit::onFocusChange(bool focused, FocusReason reason)
|
||||
{
|
||||
if(focused) {
|
||||
if(reason == UI::TabFocusReason)
|
||||
setCursorPos(0);
|
||||
if(reason == TabFocusReason)
|
||||
setCursorPos(m_text.length());
|
||||
else
|
||||
blinkCursor();
|
||||
}
|
||||
|
@ -370,21 +364,21 @@ bool UILineEdit::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers)
|
|||
setCursorPos(m_text.length());
|
||||
else if(keyCode == KC_TAB) {
|
||||
if(UIWidgetPtr parent = getParent())
|
||||
parent->focusNextChild(UI::TabFocusReason);
|
||||
parent->focusNextChild(TabFocusReason);
|
||||
} else if(keyCode == KC_RETURN) {
|
||||
if(m_onAction)
|
||||
m_onAction();
|
||||
} else if(keyCode != 0) {
|
||||
} else if(keyChar != 0)
|
||||
appendCharacter(keyChar);
|
||||
} else
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UILineEdit::onMousePress(const Point& mousePos, UI::MouseButton button)
|
||||
bool UILineEdit::onMousePress(const Point& mousePos, MouseButton button)
|
||||
{
|
||||
if(button == UI::MouseLeftButton) {
|
||||
if(button == MouseLeftButton) {
|
||||
int pos = getTextPos(mousePos);
|
||||
if(pos >= 0)
|
||||
setCursorPos(pos);
|
||||
|
|
|
@ -8,8 +8,6 @@ class UILineEdit : public UIWidget
|
|||
public:
|
||||
UILineEdit();
|
||||
|
||||
static UILineEditPtr create();
|
||||
|
||||
virtual void render();
|
||||
|
||||
void update();
|
||||
|
@ -31,9 +29,9 @@ public:
|
|||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect);
|
||||
virtual void onFocusChange(bool focused, UI::FocusReason reason);
|
||||
virtual void onFocusChange(bool focused, FocusReason reason);
|
||||
virtual bool onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers);
|
||||
virtual bool onMousePress(const Point& mousePos, UI::MouseButton button);
|
||||
virtual bool onMousePress(const Point& mousePos, MouseButton button);
|
||||
|
||||
private:
|
||||
void blinkCursor();
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
#include "uilist.h"
|
||||
|
||||
UIList::UIList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UIList::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UIList::render()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool UIList::onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UIList::onMousePress(const Point& mousePos, UI::MouseButton button)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UIList::onMouseMove(const Point& mousePos, const Point& mouseMoved)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef UILIST_H
|
||||
#define UILIST_H
|
||||
|
||||
#include "uiwidget.h"
|
||||
|
||||
class UIList : public UIWidget
|
||||
{
|
||||
public:
|
||||
UIList();
|
||||
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void render();
|
||||
|
||||
protected:
|
||||
virtual bool onKeyPress(uchar keyCode, char keyChar, int keyboardModifiers);
|
||||
virtual bool onMousePress(const Point& mousePos, UI::MouseButton button);
|
||||
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
|
||||
|
||||
private:
|
||||
std::list<std::string> m_items;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,9 +9,9 @@ UIManager g_ui;
|
|||
void UIManager::init()
|
||||
{
|
||||
// creates root widget
|
||||
m_rootWidget = UIWidgetPtr(new UIWidget);
|
||||
m_rootWidget = UIWidget::create<UIWidget>();
|
||||
m_rootWidget->setup();
|
||||
m_rootWidget->setId("root");
|
||||
m_rootWidget->setHovered(true);
|
||||
m_rootWidget->resize(g_graphics.getScreenSize());
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ void UIManager::render()
|
|||
void UIManager::resize(const Size& size)
|
||||
{
|
||||
if(m_rootWidget)
|
||||
m_rootWidget->resize(size);
|
||||
m_rootWidget->resize(g_graphics.getScreenSize());
|
||||
}
|
||||
|
||||
void UIManager::inputEvent(const PlatformEvent& event)
|
||||
|
@ -38,13 +38,13 @@ void UIManager::inputEvent(const PlatformEvent& event)
|
|||
// translate input event to ui events
|
||||
if(m_rootWidget) {
|
||||
if(event.type & EventKeyboardAction) {
|
||||
int keyboardModifiers = UI::KeyboardNoModifier;
|
||||
int keyboardModifiers = KeyboardNoModifier;
|
||||
if(event.ctrl)
|
||||
keyboardModifiers |= UI::KeyboardCtrlModifier;
|
||||
keyboardModifiers |= KeyboardCtrlModifier;
|
||||
if(event.shift)
|
||||
keyboardModifiers |= UI::KeyboardShiftModifier;
|
||||
keyboardModifiers |= KeyboardShiftModifier;
|
||||
if(event.alt)
|
||||
keyboardModifiers |= UI::KeyboardAltModifier;
|
||||
keyboardModifiers |= KeyboardAltModifier;
|
||||
|
||||
if(event.type == EventKeyDown)
|
||||
m_rootWidget->onKeyPress(event.keycode, event.keychar, keyboardModifiers);
|
||||
|
@ -52,24 +52,25 @@ void UIManager::inputEvent(const PlatformEvent& event)
|
|||
m_rootWidget->onKeyRelease(event.keycode, event.keychar, keyboardModifiers);
|
||||
} else if(event.type & EventMouseAction) {
|
||||
if(event.type == EventMouseMove) {
|
||||
m_rootWidget->updateState(HoverState);
|
||||
m_rootWidget->onMouseMove(event.mousePos, event.mouseMoved);
|
||||
}
|
||||
else if(event.type & EventMouseWheel) {
|
||||
UI::MouseWheelDirection dir = UI::MouseNoWheel;
|
||||
MouseWheelDirection dir = MouseNoWheel;
|
||||
if(event.type & EventDown)
|
||||
dir = UI::MouseWheelDown;
|
||||
dir = MouseWheelDown;
|
||||
else if(event.type & EventUp)
|
||||
dir = UI::MouseWheelUp;
|
||||
dir = MouseWheelUp;
|
||||
|
||||
m_rootWidget->onMouseWheel(event.mousePos, dir);
|
||||
} else {
|
||||
UI::MouseButton button = UI::MouseNoButton;
|
||||
MouseButton button = MouseNoButton;
|
||||
if(event.type & EventMouseLeftButton)
|
||||
button = UI::MouseLeftButton;
|
||||
button = MouseLeftButton;
|
||||
else if(event.type & EventMouseMidButton)
|
||||
button = UI::MouseMidButton;
|
||||
button = MouseMidButton;
|
||||
else if(event.type & EventMouseRightButton)
|
||||
button = UI::MouseRightButton;
|
||||
button = MouseRightButton;
|
||||
|
||||
if(event.type & EventDown)
|
||||
m_rootWidget->onMousePress(event.mousePos, button);
|
||||
|
@ -132,7 +133,7 @@ OTMLNodePtr UIManager::getStyle(const std::string& styleName)
|
|||
return m_styles[styleName];
|
||||
}
|
||||
|
||||
UIWidgetPtr UIManager::loadUI(const std::string& file)
|
||||
UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent)
|
||||
{
|
||||
try {
|
||||
OTMLDocumentPtr doc = OTMLDocument::parse(file);
|
||||
|
@ -146,7 +147,7 @@ UIWidgetPtr UIManager::loadUI(const std::string& file)
|
|||
else {
|
||||
if(widget)
|
||||
throw std::runtime_error("cannot have multiple main widgets in .otui files");
|
||||
widget = loadWidgetFromOTML(node);
|
||||
widget = loadWidgetFromOTML(node, parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,33 +158,29 @@ UIWidgetPtr UIManager::loadUI(const std::string& file)
|
|||
}
|
||||
}
|
||||
|
||||
UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode)
|
||||
UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent)
|
||||
{
|
||||
OTMLNodePtr styleNode = getStyle(widgetNode->tag())->clone();
|
||||
styleNode->merge(widgetNode);
|
||||
|
||||
std::string widgetType = styleNode->valueAt("__widgetType");
|
||||
|
||||
UIWidgetPtr widget;
|
||||
if(widgetType == "UIWidget")
|
||||
widget = UIWidgetPtr(new UIWidget);
|
||||
else if(widgetType == "UILabel")
|
||||
widget = UIWidgetPtr(new UILabel);
|
||||
else if(widgetType == "UIButton")
|
||||
widget = UIWidgetPtr(new UIButton);
|
||||
else if(widgetType == "UILineEdit")
|
||||
widget = UIWidgetPtr(new UILineEdit);
|
||||
else if(widgetType == "UIWindow")
|
||||
widget = UIWidgetPtr(new UIWindow);
|
||||
else
|
||||
throw OTMLException(styleNode, "cannot determine widget type");
|
||||
// call widget creation from lua
|
||||
//g_lua.getGlobalField(widgetType, "create");
|
||||
g_lua.getGlobal(widgetType);
|
||||
g_lua.getField("create");
|
||||
g_lua.remove(-2);
|
||||
g_lua.protectedCall(0, 1);
|
||||
|
||||
widget->onStyleApply(styleNode);
|
||||
widget->updateLayout();
|
||||
UIWidgetPtr widget = g_lua.polymorphicPop<UIWidgetPtr>();
|
||||
if(parent)
|
||||
parent->addChild(widget);
|
||||
|
||||
widget->setStyleFromNode(styleNode);
|
||||
|
||||
for(const OTMLNodePtr& childNode : widgetNode->children()) {
|
||||
if(!childNode->isUnique())
|
||||
widget->addChild(loadWidgetFromOTML(childNode));
|
||||
loadWidgetFromOTML(childNode, widget);
|
||||
}
|
||||
|
||||
return widget;
|
||||
|
|
|
@ -19,8 +19,8 @@ public:
|
|||
void importStyleFromOTML(const OTMLNodePtr& styleNode);
|
||||
OTMLNodePtr getStyle(const std::string& styleName);
|
||||
|
||||
UIWidgetPtr loadUI(const std::string& file);
|
||||
UIWidgetPtr loadWidgetFromOTML(const OTMLNodePtr& widgetNode);
|
||||
UIWidgetPtr loadUI(const std::string& file, const UIWidgetPtr& parent = nullptr);
|
||||
UIWidgetPtr loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent);
|
||||
|
||||
UIWidgetPtr getRootWidget() { return m_rootWidget; }
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#include "uiverticallayout.h"
|
||||
#include "uiwidget.h"
|
||||
|
||||
UIVerticalLayout::UIVerticalLayout(UIWidgetPtr parentWidget)
|
||||
: UILayout(parentWidget)
|
||||
{
|
||||
}
|
||||
|
||||
void UIVerticalLayout::update()
|
||||
{
|
||||
UIWidgetPtr parentWidget = getParentWidget();
|
||||
UIWidgetList widgets = parentWidget->getChildren();
|
||||
Point pos = parentWidget->getPosition();
|
||||
for(const UIWidgetPtr& widget : widgets) {
|
||||
Size size = widget->getSize();
|
||||
pos.y += widget->getMarginTop();
|
||||
if(widget->isSizeFixed()) {
|
||||
pos.x = parentWidget->getX() + (parentWidget->getWidth() - (widget->getMarginLeft() + widget->getWidth() + widget->getMarginRight()))/2;
|
||||
pos.x = std::max(pos.x, parentWidget->getX());
|
||||
} else {
|
||||
size.setWidth(parentWidget->getWidth() - (widget->getMarginLeft() + widget->getMarginRight()));
|
||||
pos.x = std::max(pos.x, parentWidget->getX() + (parentWidget->getWidth() - size.width())/2);
|
||||
}
|
||||
widget->setRect(Rect(pos, size));
|
||||
pos.y += widget->getHeight() + widget->getMarginBottom();
|
||||
}
|
||||
}
|
||||
|
||||
void UIVerticalLayout::addWidget(const UIWidgetPtr& widget)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void UIVerticalLayout::removeWidget(const UIWidgetPtr& widget)
|
||||
{
|
||||
update();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef UIVERTICALLAYOUT_H
|
||||
#define UIVERTICALLAYOUT_H
|
||||
|
||||
#include "uilayout.h"
|
||||
|
||||
class UIVerticalLayout : public UILayout
|
||||
{
|
||||
public:
|
||||
UIVerticalLayout(UIWidgetPtr parentWidget);
|
||||
|
||||
virtual void update();
|
||||
virtual void addWidget(const UIWidgetPtr& widget);
|
||||
virtual void removeWidget(const UIWidgetPtr& widget);
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,6 @@
|
|||
#include "declarations.h"
|
||||
#include <framework/luascript/luaobject.h>
|
||||
#include <framework/graphics/declarations.h>
|
||||
#include <framework/otml/declarations.h>
|
||||
|
||||
class UIWidget : public LuaObject
|
||||
{
|
||||
|
@ -12,59 +11,65 @@ public:
|
|||
UIWidget();
|
||||
virtual ~UIWidget();
|
||||
|
||||
static UIWidgetPtr create() { return UIWidgetPtr(new UIWidget); }
|
||||
template<class T>
|
||||
static std::shared_ptr<T> create() { auto t = std::shared_ptr<T>(new T); t->setup(); return t; }
|
||||
|
||||
/// Must be called just after the widget creation
|
||||
virtual void setup() { }
|
||||
void destroy();
|
||||
|
||||
/// Remove this widget from parent then destroy it and its children
|
||||
virtual void destroy();
|
||||
|
||||
/// Draw widget on screen
|
||||
virtual void setup();
|
||||
virtual void render();
|
||||
|
||||
void setEnabled(bool enable) { m_enabled = enable; }
|
||||
void setEnabled(bool enabled) { m_enabled = enabled; updateState(DisabledState); }
|
||||
void setVisible(bool visible) { m_visible = visible; }
|
||||
void setPressed(bool pressed) { m_pressed = pressed; updateState(PressedState); }
|
||||
void setId(const std::string& id) { m_id = id; }
|
||||
void setFocusable(bool focusable) { m_focusable = focusable; }
|
||||
void setHovered(bool hovered) { m_hovered = hovered; }
|
||||
void setVisible(bool visible) { m_visible = visible; }
|
||||
void setParent(const UIWidgetPtr& parent);
|
||||
void setStyle(const std::string& styleName);
|
||||
void setStyleFromNode(const OTMLNodePtr& styleNode);
|
||||
void setLayout(const UILayoutPtr& layout) { m_layout = layout; }
|
||||
void setParent(const UIWidgetPtr& parent);
|
||||
void setRect(const Rect& rect);
|
||||
void setX(int x) { move(Point(x, getY())); }
|
||||
void setY(int y) { move(Point(getX(), y)); }
|
||||
void setX(int x) { moveTo(Point(x, getY())); }
|
||||
void setY(int y) { moveTo(Point(getX(), y)); }
|
||||
void setWidth(int width) { resize(Size(width, getHeight())); }
|
||||
void setHeight(int height) { resize(Size(getWidth(), height)); }
|
||||
void resize(const Size& size) { setRect(Rect(getPosition(), size)); }
|
||||
void move(const Point& pos) { setRect(Rect(pos, getSize())); }
|
||||
|
||||
void setImage(const ImagePtr& image) { m_image = image; }
|
||||
virtual void setFont(const FontPtr& font) { m_font = font; }
|
||||
void setOpacity(int opacity) { m_opacity = opacity; }
|
||||
void setBackgroundColor(const Color& color) { m_backgroundColor = color; }
|
||||
void setForegroundColor(const Color& color) { m_foregroundColor = color; }
|
||||
void setMarginLeft(int margin) { m_marginLeft = margin; updateLayout(); }
|
||||
void setMarginRight(int margin) { m_marginRight = margin; updateLayout(); }
|
||||
void setMarginTop(int margin) { m_marginTop = margin; updateLayout(); }
|
||||
void setMarginBottom(int margin) { m_marginBottom = margin; updateLayout(); }
|
||||
void setMarginLeft(int margin) { m_marginLeft = margin; updateParentLayout(); }
|
||||
void setMarginRight(int margin) { m_marginRight = margin; updateParentLayout(); }
|
||||
void setMarginTop(int margin) { m_marginTop = margin; updateParentLayout(); }
|
||||
void setMarginBottom(int margin) { m_marginBottom = margin; updateParentLayout(); }
|
||||
void setSizeFixed(bool fixed) { m_fixedSize = fixed; updateParentLayout(); }
|
||||
void setLastFocusReason(FocusReason reason) { m_lastFocusReason = reason; }
|
||||
|
||||
void resize(const Size& size) { setRect(Rect(getPosition(), size)); }
|
||||
void moveTo(const Point& pos) { setRect(Rect(pos, getSize())); }
|
||||
void hide() { setVisible(false); }
|
||||
void show() { setVisible(true); }
|
||||
void disable() { setEnabled(false); }
|
||||
void enable() { setEnabled(true); }
|
||||
|
||||
bool isEnabled();
|
||||
bool isActive() const { return hasState(ActiveState); }
|
||||
bool isEnabled() const { return !hasState(DisabledState); }
|
||||
bool isDisabled() const { return hasState(DisabledState); }
|
||||
bool isFocused() const { return hasState(FocusState); }
|
||||
bool isHovered() const { return hasState(HoverState); }
|
||||
bool isPressed() const { return hasState(PressedState); }
|
||||
bool isVisible();
|
||||
bool isExplicitlyEnabled() const { return m_enabled; }
|
||||
bool isExplicitlyVisible() const { return m_visible; }
|
||||
bool isHovered() const { return m_hovered; }
|
||||
bool isFocusable() const { return m_focusable; }
|
||||
bool isDestroyed() const { return m_destroyed; }
|
||||
bool isSizeFixed() const { return m_fixedSize; }
|
||||
bool hasChildren() const { return m_children.size() > 0; }
|
||||
bool hasFocus();
|
||||
bool hasChild(const UIWidgetPtr& child);
|
||||
bool hasState(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(); }
|
||||
UIWidgetPtr getRootParent();
|
||||
Point getPosition() const { return m_rect.topLeft(); }
|
||||
|
@ -74,7 +79,6 @@ public:
|
|||
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; }
|
||||
|
@ -84,6 +88,7 @@ public:
|
|||
int getMarginRight() const { return m_marginRight; }
|
||||
int getMarginTop() const { return m_marginTop; }
|
||||
int getMarginBottom() const { return m_marginBottom; }
|
||||
FocusReason getLastFocusReason() const { return m_lastFocusReason; }
|
||||
|
||||
UIWidgetList getChildren() const { return m_children; }
|
||||
UIWidgetPtr getFocusedChild() const { return m_focusedChild; }
|
||||
|
@ -91,43 +96,34 @@ public:
|
|||
UIWidgetPtr getChildBefore(const UIWidgetPtr& relativeChild);
|
||||
UIWidgetPtr getChildById(const std::string& childId);
|
||||
UIWidgetPtr getChildByPos(const Point& childPos);
|
||||
UIWidgetPtr getChildByIndex(int childIndex);
|
||||
UIWidgetPtr getChildByIndex(int index);
|
||||
UIWidgetPtr recursiveGetChildById(const std::string& id);
|
||||
UIWidgetPtr recursiveGetChildByPos(const Point& childPos);
|
||||
UIWidgetPtr backwardsGetWidgetById(const std::string& id);
|
||||
|
||||
void addChild(const UIWidgetPtr& childToAdd);
|
||||
void insertChild(const UIWidgetPtr& childToInsert, int index);
|
||||
void removeChild(const UIWidgetPtr& childToRemove);
|
||||
void focusChild(const UIWidgetPtr& childToFocus, UI::FocusReason reason);
|
||||
void focusNextChild(UI::FocusReason reason);
|
||||
void moveChildToTop(const UIWidgetPtr& childToMove);
|
||||
void lockChild(const UIWidgetPtr& childToLock);
|
||||
void unlockChild(const UIWidgetPtr& childToUnlock);
|
||||
void addChild(const UIWidgetPtr& child);
|
||||
void insertChild(int index, const UIWidgetPtr& child);
|
||||
void removeChild(const UIWidgetPtr& child);
|
||||
void focusChild(const UIWidgetPtr& child, FocusReason reason);
|
||||
void focusNextChild(FocusReason reason);
|
||||
void moveChildToTop(const UIWidgetPtr& child);
|
||||
void lockChild(const UIWidgetPtr& child);
|
||||
void unlockChild(const UIWidgetPtr& child);
|
||||
|
||||
void updateParentLayout();
|
||||
void updateLayout();
|
||||
void updateChildrenLayout();
|
||||
|
||||
bool addAnchor(AnchorEdge edge, const std::string& hookedWidgetId, AnchorEdge hookedEdge);
|
||||
void centerIn(const std::string& hookedWidgetId);
|
||||
void fill(const std::string& hookedWidgetId);
|
||||
virtual void updateState(WidgetState state);
|
||||
void updateStates();
|
||||
virtual void updateStyle();
|
||||
void applyStyle(const OTMLNodePtr& styleNode);
|
||||
|
||||
UIWidgetPtr asUIWidget() { return std::static_pointer_cast<UIWidget>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
void internalUpdateLayout();
|
||||
void internalUpdateChildrenLayout();
|
||||
void internalDestroy();
|
||||
void internalDestroyCheck();
|
||||
|
||||
void addAnchoredWidget(const UIWidgetPtr& widget);
|
||||
void recalculateAnchoredWidgets();
|
||||
void clearAnchoredWidgets();
|
||||
void computeAnchoredWidgets();
|
||||
void resetLayoutUpdateState(bool resetOwn);
|
||||
|
||||
bool m_layoutUpdated;
|
||||
bool m_updateEventScheduled;
|
||||
bool m_layoutUpdateScheduled;
|
||||
bool m_childrenLayoutUpdateScheduled;
|
||||
|
||||
protected:
|
||||
/// Triggered when widget style is changed
|
||||
|
@ -135,7 +131,7 @@ protected:
|
|||
/// Triggered when widget is moved or resized
|
||||
virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect);
|
||||
/// Triggered when widget gets or loses focus
|
||||
virtual void onFocusChange(bool focused, UI::FocusReason reason);
|
||||
virtual void onFocusChange(bool focused, FocusReason reason);
|
||||
/// Triggered when the mouse enters or leaves widget area
|
||||
virtual void onHoverChange(bool hovered);
|
||||
/// Triggered when user presses key while widget has focus
|
||||
|
@ -143,33 +139,33 @@ protected:
|
|||
/// Triggered when user releases key while widget has focus
|
||||
virtual bool onKeyRelease(uchar keyCode, char keyChar, int keyboardModifiers);
|
||||
/// Triggered when a mouse button is pressed down while mouse pointer is inside widget area
|
||||
virtual bool onMousePress(const Point& mousePos, UI::MouseButton button);
|
||||
virtual bool onMousePress(const Point& mousePos, MouseButton button);
|
||||
/// Triggered when a mouse button is released
|
||||
virtual bool onMouseRelease(const Point& mousePos, UI::MouseButton button);
|
||||
virtual bool onMouseRelease(const Point& mousePos, MouseButton button);
|
||||
/// Triggered when mouse moves (even when the mouse is outside widget area)
|
||||
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
|
||||
/// Triggered when mouse middle button wheels inside widget area
|
||||
virtual bool onMouseWheel(const Point& mousePos, UI::MouseWheelDirection direction);
|
||||
virtual bool onMouseWheel(const Point& mousePos, MouseWheelDirection direction);
|
||||
|
||||
friend class UIManager;
|
||||
|
||||
private:
|
||||
void destroyCheck();
|
||||
|
||||
protected:
|
||||
std::string m_id;
|
||||
FocusReason m_lastFocusReason;
|
||||
bool m_enabled;
|
||||
bool m_visible;
|
||||
bool m_hovered;
|
||||
bool m_focusable;
|
||||
bool m_destroyed;
|
||||
bool m_fixedSize;
|
||||
bool m_pressed;
|
||||
Rect m_rect;
|
||||
UIAnchorList m_anchors;
|
||||
UIWeakWidgetList m_anchoredWidgets;
|
||||
UILayoutPtr m_layout;
|
||||
UIWidgetWeakPtr m_parent;
|
||||
UIWidgetList m_children;
|
||||
UIWidgetList m_lockedWidgets;
|
||||
UIWidgetList m_lockedChildren;
|
||||
UIWidgetPtr m_focusedChild;
|
||||
std::string m_id;
|
||||
OTMLNodePtr m_style;
|
||||
OTMLNodePtr m_stateStyle;
|
||||
uint m_states;
|
||||
|
||||
// basic style components used by all widgets
|
||||
ImagePtr m_image;
|
||||
|
|
|
@ -1,43 +1,18 @@
|
|||
#include "uiwindow.h"
|
||||
#include <framework/graphics/borderimage.h>
|
||||
#include <framework/graphics/font.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/otml/otml.h>
|
||||
|
||||
UIWindow::UIWindow()
|
||||
void UIWindow::setup()
|
||||
{
|
||||
UIWidget::setup();
|
||||
m_moving = false;
|
||||
}
|
||||
|
||||
UIWindowPtr UIWindow::create()
|
||||
{
|
||||
UIWindowPtr window(new UIWindow);
|
||||
return window;
|
||||
}
|
||||
|
||||
void UIWindow::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
if(OTMLNodePtr headNode = styleNode->get("head")) {
|
||||
if(OTMLNodePtr node = headNode->get("border-image"))
|
||||
m_headImage = BorderImage::loadFromOTML(node);
|
||||
m_headHeight = headNode->valueAt("height", m_headImage->getDefaultSize().height());
|
||||
m_headMargin = headNode->valueAt("margin", 0);
|
||||
m_titleAlign = fw::translateAlignment(headNode->valueAt("text align", std::string("center")));
|
||||
} else {
|
||||
m_headHeight = 0;
|
||||
m_headMargin = 0;
|
||||
m_titleAlign = AlignCenter;
|
||||
}
|
||||
|
||||
if(OTMLNodePtr bodyNode = styleNode->get("body")) {
|
||||
if(OTMLNodePtr node = bodyNode->get("border-image"))
|
||||
m_bodyImage = BorderImage::loadFromOTML(node);
|
||||
}
|
||||
|
||||
m_title = styleNode->valueAt("title", fw::empty_string);
|
||||
}
|
||||
|
||||
void UIWindow::render()
|
||||
{
|
||||
// draw window head
|
||||
|
@ -45,6 +20,7 @@ void UIWindow::render()
|
|||
headRect.setHeight(m_headHeight);
|
||||
|
||||
if(m_headImage && m_headHeight > 0) {
|
||||
g_graphics.bindColor(m_backgroundColor);
|
||||
m_headImage->draw(headRect);
|
||||
|
||||
// draw window head text
|
||||
|
@ -59,13 +35,37 @@ void UIWindow::render()
|
|||
// draw window body
|
||||
Rect bodyRect = getRect();
|
||||
bodyRect.setTop(headRect.bottom() + 1);
|
||||
if(m_bodyImage)
|
||||
if(m_bodyImage) {
|
||||
g_graphics.bindColor(m_backgroundColor);
|
||||
m_bodyImage->draw(bodyRect);
|
||||
}
|
||||
|
||||
// render children
|
||||
UIWidget::render();
|
||||
}
|
||||
|
||||
void UIWindow::onStyleApply(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
UIWidget::onStyleApply(styleNode);
|
||||
|
||||
for(OTMLNodePtr node : styleNode->children()) {
|
||||
if(node->tag() == "head") {
|
||||
if(OTMLNodePtr cnode = node->get("border-image"))
|
||||
m_headImage = BorderImage::loadFromOTML(cnode);
|
||||
m_headHeight = node->valueAt("height", m_headImage->getDefaultSize().height());
|
||||
m_headMargin = node->valueAt("margin", 0);
|
||||
m_titleAlign = fw::translateAlignment(node->valueAt("text align", std::string("center")));
|
||||
}
|
||||
else if(node->tag() == "body") {
|
||||
if(OTMLNodePtr cnode = node->get("border-image"))
|
||||
m_bodyImage = BorderImage::loadFromOTML(cnode);
|
||||
}
|
||||
else if(node->tag() == "title") {
|
||||
setTitle(node->value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UIWindow::onGeometryUpdate(const Rect& oldRect, const Rect& newRect)
|
||||
{
|
||||
// bind window rect to parent rect
|
||||
|
@ -87,18 +87,18 @@ void UIWindow::onGeometryUpdate(const Rect& oldRect, const Rect& newRect)
|
|||
setRect(boundRect);
|
||||
}
|
||||
|
||||
void UIWindow::onFocusChange(bool focused, UI::FocusReason reason)
|
||||
void UIWindow::onFocusChange(bool focused, FocusReason reason)
|
||||
{
|
||||
// when a window is focused it goes to the top
|
||||
if(focused) {
|
||||
if(UIWidgetPtr parent = getParent())
|
||||
parent->moveChildToTop(asUIWidget());
|
||||
}
|
||||
}
|
||||
|
||||
bool UIWindow::onMousePress(const Point& mousePos, UI::MouseButton button)
|
||||
bool UIWindow::onMousePress(const Point& mousePos, MouseButton button)
|
||||
{
|
||||
Rect headRect = getRect();
|
||||
headRect.setHeight(m_headHeight);
|
||||
if(headRect.contains(mousePos)) {
|
||||
if(!getChildByPos(mousePos)) {
|
||||
m_moving = true;
|
||||
m_movingReference = mousePos - getRect().topLeft();
|
||||
return true;
|
||||
|
@ -106,7 +106,7 @@ bool UIWindow::onMousePress(const Point& mousePos, UI::MouseButton button)
|
|||
return UIWidget::onMousePress(mousePos, button);
|
||||
}
|
||||
|
||||
bool UIWindow::onMouseRelease(const Point& mousePos, UI::MouseButton button)
|
||||
bool UIWindow::onMouseRelease(const Point& mousePos, MouseButton button)
|
||||
{
|
||||
if(m_moving) {
|
||||
m_moving = false;
|
||||
|
@ -118,7 +118,7 @@ bool UIWindow::onMouseRelease(const Point& mousePos, UI::MouseButton button)
|
|||
bool UIWindow::onMouseMove(const Point& mousePos, const Point& mouseMoved)
|
||||
{
|
||||
if(m_moving) {
|
||||
move(mousePos - m_movingReference);
|
||||
moveTo(mousePos - m_movingReference);
|
||||
return true;
|
||||
}
|
||||
return UIWidget::onMouseMove(mousePos, mouseMoved);
|
||||
|
|
|
@ -6,21 +6,18 @@
|
|||
class UIWindow : public UIWidget
|
||||
{
|
||||
public:
|
||||
UIWindow();
|
||||
|
||||
static UIWindowPtr create();
|
||||
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void setup();
|
||||
virtual void render();
|
||||
|
||||
void setTitle(const std::string& title) { m_title = title; }
|
||||
std::string getTitle() const { return m_title; }
|
||||
|
||||
protected:
|
||||
virtual void onStyleApply(const OTMLNodePtr& styleNode);
|
||||
virtual void onGeometryUpdate(const Rect& oldRect, const Rect& newRect);
|
||||
virtual void onFocusChange(bool focused, UI::FocusReason reason);
|
||||
virtual bool onMousePress(const Point& mousePos, UI::MouseButton button);
|
||||
virtual bool onMouseRelease(const Point& mousePos, UI::MouseButton button);
|
||||
virtual void onFocusChange(bool focused, FocusReason reason);
|
||||
virtual bool onMousePress(const Point& mousePos, MouseButton button);
|
||||
virtual bool onMouseRelease(const Point& mousePos, MouseButton button);
|
||||
virtual bool onMouseMove(const Point& mousePos, const Point& mouseMoved);
|
||||
|
||||
private:
|
||||
|
|
|
@ -9,7 +9,7 @@ typedef uint32 RGBA;
|
|||
class Color
|
||||
{
|
||||
public:
|
||||
Color() : color(0xFFFFFFFF) { }
|
||||
Color() : color(0x0) { }
|
||||
Color(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) : color(((a & 0xff)<<24) | ((b & 0xff)<<16) | ((g & 0xff)<<8) | (r & 0xff)) { }
|
||||
Color(const Color& other) : color(other.color) { }
|
||||
Color(RGBA rgba) : color(rgba) { }
|
||||
|
|
|
@ -21,23 +21,26 @@ AlignmentFlag fw::translateAlignment(std::string aligment)
|
|||
return AlignTopCenter;
|
||||
else if(aligment == "bottom")
|
||||
return AlignBottomCenter;
|
||||
else
|
||||
else if(aligment == "center")
|
||||
return AlignCenter;
|
||||
return AlignNone;
|
||||
}
|
||||
|
||||
AnchorEdge fw::translateAnchorEdge(const std::string& anchorPoint)
|
||||
AnchorEdge fw::translateAnchorEdge(std::string anchorEdge)
|
||||
{
|
||||
if(anchorPoint == "left")
|
||||
boost::to_lower(anchorEdge);
|
||||
boost::erase_all(anchorEdge, " ");
|
||||
if(anchorEdge == "left")
|
||||
return AnchorLeft;
|
||||
else if(anchorPoint == "right")
|
||||
else if(anchorEdge == "right")
|
||||
return AnchorRight;
|
||||
else if(anchorPoint == "top")
|
||||
else if(anchorEdge == "top")
|
||||
return AnchorTop;
|
||||
else if(anchorPoint == "bottom")
|
||||
else if(anchorEdge == "bottom")
|
||||
return AnchorBottom;
|
||||
else if(anchorPoint == "horizontalCenter")
|
||||
else if(anchorEdge == "horizontalcenter")
|
||||
return AnchorHorizontalCenter;
|
||||
else if(anchorPoint == "verticalCenter")
|
||||
else if(anchorEdge == "verticalcenter")
|
||||
return AnchorVerticalCenter;
|
||||
return AnchorNone;
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
namespace fw {
|
||||
|
||||
AlignmentFlag translateAlignment(std::string aligment);
|
||||
AnchorEdge translateAnchorEdge(const std::string& anchorPoint);
|
||||
AnchorEdge translateAnchorEdge(std::string anchorEdge);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include <otclient/otclient.h>
|
||||
#include <csignal>
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
#include <csignal>
|
||||
|
||||
void signal_handler(int sig)
|
||||
{
|
||||
static bool signaled = false;
|
||||
|
|
|
@ -296,10 +296,10 @@ void OTClient::onPlatformEvent(const PlatformEvent& event)
|
|||
// TODO: move these events to lua
|
||||
UIWidgetPtr console = g_ui.getRootWidget()->getChildById("consolePanel");
|
||||
if(!console->isExplicitlyVisible()) {
|
||||
g_ui.getRootWidget()->focusChild(console, UI::ActiveFocusReason);
|
||||
g_ui.getRootWidget()->moveChildToTop(console);
|
||||
g_ui.getRootWidget()->lockChild(console);
|
||||
console->setVisible(true);
|
||||
} else {
|
||||
g_ui.getRootWidget()->unlockChild(console);
|
||||
console->setVisible(false);
|
||||
}
|
||||
fireUi = false;
|
||||
|
|
Loading…
Reference in New Issue