mirror of
https://github.com/edubart/otclient.git
synced 2025-10-14 11:34:54 +02:00
BEAWARE all game functionality is disabled with this commit for a while
* rework client modules * hide main window when loading * remake top menu functions * rework modules autoload * improve path resolving for otml and lua * move core_widgets to core_lib * fix tooltip issues * split some styles * add bit32 lua library * fix assert issues * fix compilation on linux 32 systems * rework gcc compile options * renable and fix some warnings * remove unused constants * speedup sprite cache * move UIGame to lua (not funcional yet) * fix a lot of issues in x11 window * fix crash handler * add some warnings do uiwidget and much more...
This commit is contained in:
7
modules/core_lib/widgets/uibutton.lua
Normal file
7
modules/core_lib/widgets/uibutton.lua
Normal file
@@ -0,0 +1,7 @@
|
||||
UIButton = extends(UIWidget)
|
||||
|
||||
function UIButton.create()
|
||||
local button = UIButton.internalCreate()
|
||||
button:setFocusable(false)
|
||||
return button
|
||||
end
|
13
modules/core_lib/widgets/uicheckbox.lua
Normal file
13
modules/core_lib/widgets/uicheckbox.lua
Normal file
@@ -0,0 +1,13 @@
|
||||
UICheckBox = extends(UIWidget)
|
||||
|
||||
function UICheckBox.create()
|
||||
local checkbox = UICheckBox.internalCreate()
|
||||
checkbox:setFocusable(false)
|
||||
checkbox:setTextAlign(AlignLeft)
|
||||
return checkbox
|
||||
end
|
||||
|
||||
function UICheckBox:onMousePress(mousePos, mouseButton)
|
||||
self:setChecked(not self:isChecked())
|
||||
return true
|
||||
end
|
69
modules/core_lib/widgets/uicombobox.lua
Normal file
69
modules/core_lib/widgets/uicombobox.lua
Normal file
@@ -0,0 +1,69 @@
|
||||
UIComboBox = extends(UIWidget)
|
||||
|
||||
function UIComboBox.create()
|
||||
local combobox = UIComboBox.internalCreate()
|
||||
combobox.m_options = {}
|
||||
combobox.m_currentIndex = -1
|
||||
return combobox
|
||||
end
|
||||
|
||||
function UIComboBox:setCurrentOption(text)
|
||||
if not self.m_options then return end
|
||||
for i,v in ipairs(self.m_options) do
|
||||
if v.text == text and self.m_currentIndex ~= i then
|
||||
self.m_currentIndex = i
|
||||
self:setText(text)
|
||||
self:onOptionChange(text, v.data)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UIComboBox:setCurrentIndex(index)
|
||||
if index >= 1 and index <= #self.m_options then
|
||||
local v = self.m_options[index]
|
||||
self.m_currentIndex = index
|
||||
self:setText(v.text)
|
||||
self:onOptionChange(v.text, v.data)
|
||||
end
|
||||
end
|
||||
|
||||
function UIComboBox:addOption(text, data)
|
||||
table.insert(self.m_options, { text = text, data = data })
|
||||
local index = #self.m_options
|
||||
if index == 1 then self:setCurrentOption(text) end
|
||||
return index
|
||||
end
|
||||
|
||||
function UIComboBox:onMousePress(mousePos, mouseButton)
|
||||
local menu = createWidget(self:getStyleName() .. 'PopupMenu', self)
|
||||
for i,v in ipairs(self.m_options) do
|
||||
menu:addOption(v.text, function() self:setCurrentOption(v.text) end)
|
||||
end
|
||||
menu:setWidth(self:getWidth())
|
||||
menu:display({ x = self:getX(), y = self:getY() + self:getHeight() })
|
||||
connect(menu, { onDestroy = function() self:setOn(false) end })
|
||||
self:setOn(true)
|
||||
return true
|
||||
end
|
||||
|
||||
function UIComboBox:onMouseWheel(mousePos, direction)
|
||||
if direction == MouseWheelUp and self.m_currentIndex > 1 then
|
||||
self:setCurrentIndex(self.m_currentIndex - 1)
|
||||
elseif direction == MouseWheelDown and self.m_currentIndex < #self.m_options then
|
||||
self:setCurrentIndex(self.m_currentIndex + 1)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function UIComboBox:onStyleApply(styleName, styleNode)
|
||||
if styleNode.options then
|
||||
for k,option in pairs(styleNode.options) do
|
||||
self:addOption(option)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UIComboBox:onOptionChange(optionText, optionData)
|
||||
-- nothing todo
|
||||
end
|
9
modules/core_lib/widgets/uilabel.lua
Normal file
9
modules/core_lib/widgets/uilabel.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
UILabel = extends(UIWidget)
|
||||
|
||||
function UILabel.create()
|
||||
local label = UILabel.internalCreate()
|
||||
label:setPhantom(true)
|
||||
label:setFocusable(false)
|
||||
label:setTextAlign(AlignLeft)
|
||||
return label
|
||||
end
|
65
modules/core_lib/widgets/uimessagebox.lua
Normal file
65
modules/core_lib/widgets/uimessagebox.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
UIMessageBox = extends(UIWindow)
|
||||
|
||||
MessageBoxOk = 1
|
||||
MessageBoxCancel = 2
|
||||
|
||||
-- messagebox cannot be created from otui files
|
||||
UIMessageBox.create = nil
|
||||
|
||||
function UIMessageBox.display(title, message, flags)
|
||||
local messagebox = UIMessageBox.internalCreate()
|
||||
rootWidget:addChild(messagebox)
|
||||
|
||||
messagebox:setStyle('MessageBoxWindow')
|
||||
messagebox:setText(title)
|
||||
|
||||
local messageLabel = createWidget('MessageBoxLabel', messagebox)
|
||||
messageLabel:setText(message)
|
||||
messageLabel:resizeToText()
|
||||
|
||||
messagebox:setWidth(math.max(messageLabel:getWidth() + 48, messagebox:getWidth()))
|
||||
messagebox:setHeight(math.max(messageLabel:getHeight() + 64, messagebox:getHeight()))
|
||||
|
||||
-- setup messagebox first button
|
||||
local buttonRight = createWidget('MessageBoxRightButton', messagebox)
|
||||
|
||||
if flags == MessageBoxOk then
|
||||
buttonRight:setText('Ok')
|
||||
connect(buttonRight, { onClick = function(self) self:getParent():ok() end })
|
||||
connect(messagebox, { onEnter = function(self) self:ok() end })
|
||||
connect(messagebox, { onEscape = function(self) self:ok() end })
|
||||
elseif flags == MessageBoxCancel then
|
||||
buttonRight:setText('Cancel')
|
||||
connect(buttonRight, { onClick = function(self) self:getParent():cancel() end })
|
||||
connect(messagebox, { onEnter = function(self) self:cancel() end })
|
||||
connect(messagebox, { onEscape = function(self) self:cancel() end })
|
||||
end
|
||||
|
||||
messagebox:lock()
|
||||
|
||||
return messagebox
|
||||
end
|
||||
|
||||
function displayInfoBox(title, message)
|
||||
return UIMessageBox.display(title, message, MessageBoxOk)
|
||||
end
|
||||
|
||||
function displayErrorBox(title, message)
|
||||
return UIMessageBox.display(title, message, MessageBoxOk)
|
||||
end
|
||||
|
||||
function displayCancelBox(title, message)
|
||||
return UIMessageBox.display(title, message, MessageBoxCancel)
|
||||
end
|
||||
|
||||
function UIMessageBox:ok()
|
||||
signalcall(self.onOk, self)
|
||||
self.onOk = nil
|
||||
self:destroy()
|
||||
end
|
||||
|
||||
function UIMessageBox:cancel()
|
||||
signalcall(self.onCancel, self)
|
||||
self.onCancel = nil
|
||||
self:destroy()
|
||||
end
|
79
modules/core_lib/widgets/uipopupmenu.lua
Normal file
79
modules/core_lib/widgets/uipopupmenu.lua
Normal file
@@ -0,0 +1,79 @@
|
||||
UIPopupMenu = extends(UIWidget)
|
||||
|
||||
local currentMenu
|
||||
|
||||
function UIPopupMenu.create()
|
||||
local menu = UIPopupMenu.internalCreate()
|
||||
local layout = UIVerticalLayout.create(menu)
|
||||
layout:setFitChildren(true)
|
||||
menu:setLayout(layout)
|
||||
return menu
|
||||
end
|
||||
|
||||
function UIPopupMenu:display(pos)
|
||||
-- don't display if not options was added
|
||||
if self:getChildCount() == 0 then
|
||||
self:destroy()
|
||||
return
|
||||
end
|
||||
|
||||
if currentMenu then
|
||||
currentMenu:destroy()
|
||||
end
|
||||
|
||||
rootWidget:addChild(self)
|
||||
self:setPosition(pos)
|
||||
self:grabMouse()
|
||||
self:grabKeyboard()
|
||||
currentMenu = self
|
||||
end
|
||||
|
||||
function UIPopupMenu:onGeometryChange()
|
||||
self:bindRectToParent()
|
||||
end
|
||||
|
||||
function UIPopupMenu:addOption(optionName, optionCallback)
|
||||
local optionWidget = createWidget(self:getStyleName() .. 'Button', self)
|
||||
local lastOptionWidget = self:getLastChild()
|
||||
optionWidget.onClick = function(self)
|
||||
optionCallback()
|
||||
self:getParent():destroy()
|
||||
end
|
||||
optionWidget:setText(optionName)
|
||||
local width = optionWidget:getTextSize().width + optionWidget:getMarginLeft() + optionWidget:getMarginRight() + 6
|
||||
self:setWidth(math.max(self:getWidth(), width))
|
||||
end
|
||||
|
||||
function UIPopupMenu:addSeparator()
|
||||
createWidget(self:getStyleName() .. 'Separator', self)
|
||||
end
|
||||
|
||||
function UIPopupMenu:onDestroy()
|
||||
if currentMenu == self then
|
||||
currentMenu = nil
|
||||
end
|
||||
end
|
||||
|
||||
function UIPopupMenu:onMousePress(mousePos, mouseButton)
|
||||
-- clicks outside menu area destroys the menu
|
||||
if not self:containsPoint(mousePos) then
|
||||
self:destroy()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function UIPopupMenu:onKeyPress(keyCode, keyboardModifiers)
|
||||
if keyCode == KeyEscape then
|
||||
self:destroy()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- close all menus when the window is resized
|
||||
local function onRootGeometryUpdate()
|
||||
if currentMenu then
|
||||
currentMenu:destroy()
|
||||
end
|
||||
end
|
||||
connect(rootWidget, { onGeometryChange = onRootGeometryUpdate} )
|
31
modules/core_lib/widgets/uiprogressbar.lua
Normal file
31
modules/core_lib/widgets/uiprogressbar.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
UIProgressBar = extends(UIWidget)
|
||||
|
||||
function UIProgressBar.create()
|
||||
local progressbar = UIProgressBar.internalCreate()
|
||||
progressbar:setFocusable(false)
|
||||
progressbar:setPhantom(true)
|
||||
progressbar.m_percent = 0
|
||||
progressbar:updateBackground()
|
||||
return progressbar
|
||||
end
|
||||
|
||||
function UIProgressBar:setPercent(percent)
|
||||
self.m_percent = math.max(math.min(percent, 100), 0)
|
||||
self:updateBackground()
|
||||
end
|
||||
|
||||
|
||||
function UIProgressBar:getPercent()
|
||||
return self.m_percent
|
||||
end
|
||||
|
||||
function UIProgressBar:updateBackground()
|
||||
local width = math.max((self.m_percent * self:getWidth())/100, 1)
|
||||
local height = self:getHeight()
|
||||
self:setBackgroundSize({width=width, height=height})
|
||||
end
|
||||
|
||||
|
||||
function UIProgressBar:onGeometryChange(oldRect, newRect)
|
||||
self:updateBackground()
|
||||
end
|
88
modules/core_lib/widgets/uispinbox.lua
Normal file
88
modules/core_lib/widgets/uispinbox.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
UISpinBox = extends(UILineEdit)
|
||||
|
||||
function UISpinBox.create()
|
||||
local spinbox = UISpinBox.internalCreate()
|
||||
spinbox:setValidCharacters('0123456789')
|
||||
spinbox.m_minimum = 0
|
||||
spinbox.m_maximum = 0
|
||||
spinbox:setCurrentIndex(0)
|
||||
spinbox:setText("0")
|
||||
return spinbox
|
||||
end
|
||||
|
||||
function UISpinBox:setCurrentIndex(index)
|
||||
if index >= self.m_minimum and index <= self.m_maximum then
|
||||
if self:getText():len() > 0 then
|
||||
self:setText(index)
|
||||
end
|
||||
self.m_currentIndex = index
|
||||
self:onIndexChange(index)
|
||||
end
|
||||
end
|
||||
|
||||
function UISpinBox:setMinimum(minimum)
|
||||
if minimum > self.m_maximum then
|
||||
print("[UISpinBox:setMinimum]: minimum value cant be greater than maximum")
|
||||
return false
|
||||
end
|
||||
if self.m_currentIndex < minimum then
|
||||
self:setCurrentIndex(minimum)
|
||||
end
|
||||
self.m_minimum = minimum
|
||||
end
|
||||
|
||||
function UISpinBox:setMaximum(maximum)
|
||||
if maximum < self.m_minimum then
|
||||
print("[UISpinBox:setMaximum]: maximum value cant be lower than minimum")
|
||||
return false
|
||||
end
|
||||
if self.m_currentIndex > maximum then
|
||||
self:setCurrentIndex(maximum)
|
||||
end
|
||||
self.m_maximum = maximum
|
||||
end
|
||||
|
||||
function UISpinBox:getCurrentIndex()
|
||||
return self.m_currentIndex
|
||||
end
|
||||
|
||||
function UISpinBox:onMouseWheel(mousePos, direction)
|
||||
if direction == MouseWheelUp then
|
||||
self:setCurrentIndex(self.m_currentIndex + 1)
|
||||
elseif direction == MouseWheelDown then
|
||||
self:setCurrentIndex(self.m_currentIndex - 1)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function UISpinBox:onTextChange(text, oldText)
|
||||
|
||||
if text:len() == 0 then
|
||||
self:setCurrentIndex(self.m_minimum)
|
||||
return
|
||||
end
|
||||
|
||||
local number = tonumber(text)
|
||||
if not number or number > self.m_maximum or number < self.m_minimum then
|
||||
self:setText(oldText)
|
||||
return
|
||||
end
|
||||
|
||||
self:setCurrentIndex(number)
|
||||
end
|
||||
|
||||
function UISpinBox:onIndexChange(index)
|
||||
-- nothing todo
|
||||
end
|
||||
|
||||
function UISpinBox:onStyleApply(styleName, styleNode)
|
||||
-- tonumber converts to 0 if not valid
|
||||
if styleNode.maximum and tonumber(styleNode.maximum) then
|
||||
self:setMaximum(tonumber(styleNode.maximum))
|
||||
end
|
||||
|
||||
if styleNode.minimum and tonumber(styleNode.minimum) then
|
||||
self:setMinimum(tonumber(styleNode.minimum))
|
||||
end
|
||||
end
|
||||
|
124
modules/core_lib/widgets/uitabbar.lua
Normal file
124
modules/core_lib/widgets/uitabbar.lua
Normal file
@@ -0,0 +1,124 @@
|
||||
UITabBar = extends(UIWidget)
|
||||
|
||||
-- private functions
|
||||
local function onTabClick(tab)
|
||||
tab.tabBar:selectTab(tab)
|
||||
end
|
||||
|
||||
local function tabBlink(tab)
|
||||
if not tab.blinking then return end
|
||||
tab:setOn(not tab:isOn())
|
||||
scheduleEvent(function() tabBlink(tab) end, 500)
|
||||
end
|
||||
|
||||
-- public functions
|
||||
function UITabBar.create()
|
||||
local tabbar = UITabBar.internalCreate()
|
||||
tabbar:setFocusable(false)
|
||||
tabbar.tabs = {}
|
||||
return tabbar
|
||||
end
|
||||
|
||||
function UITabBar:setContentWidget(widget)
|
||||
self.contentWidget = widget
|
||||
if #self.tabs > 0 then
|
||||
self.contentWidget:addChild(self.tabs[1].tabPanel)
|
||||
end
|
||||
end
|
||||
|
||||
function UITabBar:addTab(text, panel)
|
||||
if panel == nil then
|
||||
panel = createWidget(self:getStyleName() .. 'Panel')
|
||||
end
|
||||
|
||||
local tab = createWidget(self:getStyleName() .. 'Button', self)
|
||||
tab.tabPanel = panel
|
||||
tab.tabBar = self
|
||||
tab:setText(text)
|
||||
tab:setWidth(tab:getTextSize().width + tab:getPaddingLeft() + tab:getPaddingRight())
|
||||
connect(tab, { onClick = onTabClick })
|
||||
|
||||
table.insert(self.tabs, tab)
|
||||
if #self.tabs == 1 then
|
||||
self:selectTab(tab)
|
||||
end
|
||||
|
||||
return tab
|
||||
end
|
||||
|
||||
function UITabBar:removeTab(tab)
|
||||
local index = table.find(self.tabs, tab)
|
||||
if index == nil then return end
|
||||
if self.currentTab == tab then
|
||||
self:selectPrevTab()
|
||||
end
|
||||
table.remove(self.tabs, index)
|
||||
tab:destroy()
|
||||
end
|
||||
|
||||
function UITabBar:getTab(text)
|
||||
for k,tab in pairs(self.tabs) do
|
||||
if tab:getText():lower() == text:lower() then
|
||||
return tab
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UITabBar:selectTab(tab)
|
||||
if self.currentTab == tab then return end
|
||||
if self.contentWidget then
|
||||
local selectedWidget = self.contentWidget:getFirstChild()
|
||||
if selectedWidget then
|
||||
self.contentWidget:removeChild(selectedWidget)
|
||||
end
|
||||
self.contentWidget:addChild(tab.tabPanel)
|
||||
tab.tabPanel:fill('parent')
|
||||
end
|
||||
|
||||
if self.currentTab then
|
||||
self.currentTab:setChecked(false)
|
||||
end
|
||||
signalcall(self.onTabChange, self, tab)
|
||||
self.currentTab = tab
|
||||
tab:setChecked(true)
|
||||
tab:setOn(false)
|
||||
tab.blinking = false
|
||||
end
|
||||
|
||||
function UITabBar:selectNextTab()
|
||||
if self.currentTab == nil then return end
|
||||
local index = table.find(self.tabs, self.currentTab)
|
||||
if index == nil then return end
|
||||
local nextTab = self.tabs[index + 1] or self.tabs[1]
|
||||
if not nextTab then return end
|
||||
self:selectTab(nextTab)
|
||||
end
|
||||
|
||||
function UITabBar:selectPrevTab()
|
||||
if self.currentTab == nil then return end
|
||||
local index = table.find(self.tabs, self.currentTab)
|
||||
if index == nil then return end
|
||||
local prevTab = self.tabs[index - 1] or self.tabs[#self.tabs]
|
||||
if not prevTab then return end
|
||||
self:selectTab(prevTab)
|
||||
end
|
||||
|
||||
function UITabBar:blinkTab(tab)
|
||||
if tab:isChecked() or tab.blinking then return end
|
||||
tab.blinking = true
|
||||
tabBlink(tab)
|
||||
end
|
||||
|
||||
function UITabBar:getTabPanel(tab)
|
||||
return tab.tabPanel
|
||||
end
|
||||
|
||||
function UITabBar:getCurrentTabPanel()
|
||||
if self.currentTab then
|
||||
return self.currentTab.tabPanel
|
||||
end
|
||||
end
|
||||
|
||||
function UITabBar:getCurrentTab()
|
||||
return self.currentTab
|
||||
end
|
19
modules/core_lib/widgets/uiwidget.lua
Normal file
19
modules/core_lib/widgets/uiwidget.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
function UIWidget:setMargin(...)
|
||||
local params = {...}
|
||||
if #params == 1 then
|
||||
self:setMarginTop(params[1])
|
||||
self:setMarginRight(params[1])
|
||||
self:setMarginBottom(params[1])
|
||||
self:setMarginLeft(params[1])
|
||||
elseif #params == 2 then
|
||||
self:setMarginTop(params[1])
|
||||
self:setMarginRight(params[2])
|
||||
self:setMarginBottom(params[1])
|
||||
self:setMarginLeft(params[2])
|
||||
elseif #params == 4 then
|
||||
self:setMarginTop(params[1])
|
||||
self:setMarginRight(params[2])
|
||||
self:setMarginBottom(params[3])
|
||||
self:setMarginLeft(params[4])
|
||||
end
|
||||
end
|
38
modules/core_lib/widgets/uiwindow.lua
Normal file
38
modules/core_lib/widgets/uiwindow.lua
Normal file
@@ -0,0 +1,38 @@
|
||||
UIWindow = extends(UIWidget)
|
||||
|
||||
function UIWindow.create()
|
||||
local window = UIWindow.internalCreate()
|
||||
window:setTextAlign(AlignTopCenter)
|
||||
window:setDragable(true)
|
||||
return window
|
||||
end
|
||||
|
||||
function UIWindow:onKeyDown(keyCode, keyboardModifiers)
|
||||
if keyboardModifiers == KeyboardNoModifier then
|
||||
if keyCode == KeyEnter then
|
||||
signalcall(self.onEnter, self)
|
||||
elseif keyCode == KeyEscape then
|
||||
signalcall(self.onEscape, self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UIWindow:onFocusChange(focused)
|
||||
if focused then self:raise() end
|
||||
end
|
||||
|
||||
function UIWindow:onDragEnter(mousePos)
|
||||
self:breakAnchors()
|
||||
self.movingReference = { x = mousePos.x - self:getX(), y = mousePos.y - self:getY() }
|
||||
return true
|
||||
end
|
||||
|
||||
function UIWindow:onDragLeave(droppedWidget, mousePos)
|
||||
-- TODO: auto detect and reconnect anchors
|
||||
end
|
||||
|
||||
function UIWindow:onDragMove(mousePos, mouseMoved)
|
||||
local pos = { x = mousePos.x - self.movingReference.x, y = mousePos.y - self.movingReference.y }
|
||||
self:setPosition(pos)
|
||||
self:bindRectToParent()
|
||||
end
|
Reference in New Issue
Block a user