diff --git a/modules/client_skins/skins/default/styles/tabbars.otui b/modules/client_skins/skins/default/styles/tabbars.otui index 8c59fc3f..e0abd3ec 100644 --- a/modules/client_skins/skins/default/styles/tabbars.otui +++ b/modules/client_skins/skins/default/styles/tabbars.otui @@ -11,13 +11,8 @@ TabBarButton < UIButton color: #aaaaaa anchors.top: parent.top padding: 5 + anchors.left: parent.left - $first: - anchors.left: parent.left - - $!first: - anchors.left: prev.right - margin-left: 5 $hover !checked: image-clip: 0 20 20 20 diff --git a/modules/corelib/ui/uisplitter.lua b/modules/corelib/ui/uisplitter.lua index 028cf82b..fd359dd9 100644 --- a/modules/corelib/ui/uisplitter.lua +++ b/modules/corelib/ui/uisplitter.lua @@ -9,7 +9,9 @@ function UISplitter.create() end function UISplitter:onHoverChange(hovered) - if hovered then + -- Check if margin can be changed + local margin = (self.vertical and self:getMarginBottom() or self:getMarginRight()) + if hovered and (self:canUpdateMargin(margin + 1) ~= margin or self:canUpdateMargin(margin - 1) ~= margin) then if g_mouse.isCursorChanged() or g_mouse.isPressed() then return end if self:getWidth() > self:getHeight() then g_mouse.setVerticalCursor() diff --git a/modules/corelib/ui/uitabbar.lua b/modules/corelib/ui/uitabbar.lua index c80acee7..1350e4f9 100644 --- a/modules/corelib/ui/uitabbar.lua +++ b/modules/corelib/ui/uitabbar.lua @@ -6,6 +6,60 @@ local function onTabClick(tab) tab.tabBar:selectTab(tab) end +local function updateMargins(tabBar) + if #tabBar.tabs == 0 then return end + + local currentMargin = 0 + for i = 1, #tabBar.tabs do + if i == 1 then + tabBar.tabs[i]:setMarginLeft(0) + else + tabBar.tabs[i]:setMarginLeft(5 * (i - 1) + currentMargin) + end + currentMargin = currentMargin + tabBar.tabs[i]:getWidth() + end +end + +local function onTabMousePress(tab, mousePos, mouseButton) + if mouseButton == MouseLeftButton and tab.tabBar.tabsMoveable then + tab.tabBar.selected = tab + end +end + +local function onTabMouseRelease(tab, mousePos, mouseButton) + local tabs = tab.tabBar.tabs + if tab.tabBar.selected then + local lastMargin = -5 + for i = 1, #tabs do + local nextMargin = tabs[i + 1] and (tabs[i + 1] == tab and (tabs[i]:getMarginLeft() + tabs[i]:getWidth() + 5) or tabs[i + 1]:getMarginLeft()) or tab.tabBar:getWidth() + if tab:getMarginLeft() >= lastMargin and tab:getMarginLeft() < nextMargin then + if tabs[i] ~= tab then + local newIndex = table.find(tab.tabBar.tabs, tab.tabBar.tabs[i]) + table.remove(tab.tabBar.tabs, table.find(tab.tabBar.tabs, tab)) + table.insert(tab.tabBar.tabs, newIndex, tab) + updateMargins(tab.tabBar) + break + else + updateMargins(tab.tabBar) + break + end + end + lastMargin = tab.tabBar.tabs[i]:getMarginLeft() == 0 and -5 or tab.tabBar.tabs[i]:getMarginLeft() + end + end + + tab.tabBar.selected = nil +end + +local function onTabMouseMove(tab, mousePos, mouseMoved) + if tab == tab.tabBar.selected then + local newMargin = tab:getMarginLeft() + mouseMoved.x + if newMargin >= -5 and newMargin < tab.tabBar:getWidth() - tab:getWidth() then + tab:setMarginLeft(newMargin) + end + end +end + local function tabBlink(tab) if not tab.blinking then return end tab:setOn(not tab:isOn()) @@ -17,6 +71,8 @@ function UITabBar.create() local tabbar = UITabBar.internalCreate() tabbar:setFocusable(false) tabbar.tabs = {} + tabbar.selected = nil -- dragged tab + tabsMoveable = false return tabbar end @@ -41,16 +97,52 @@ function UITabBar:addTab(text, panel) tab:setText(text) tab:setWidth(tab:getTextSize().width + tab:getPaddingLeft() + tab:getPaddingRight()) tab.onClick = onTabClick + tab.onMousePress = onTabMousePress + tab.onMouseRelease = onTabMouseRelease + tab.onMouseMove = onTabMouseMove tab.onDestroy = function() tab.tabPanel:destroy() end table.insert(self.tabs, tab) if #self.tabs == 1 then self:selectTab(tab) + tab:setMarginLeft(0) + else + local newMargin = 5 * (#self.tabs - 1) + for i = 1, #self.tabs - 1 do + newMargin = newMargin + self.tabs[i]:getWidth() + end + tab:setMarginLeft(newMargin) end return tab end +-- Additional function to move the tab by lua +function UITabBar:moveTab(tab, units) + local index = table.find(self.tabs, tab) + if index == nil then return end + + local focus = false + if self.currentTab == tab then + self:selectPrevTab() + focus = true + end + + table.remove(self.tabs, index) + + local newIndex = math.min(#self.tabs+1, math.max(index + units, 1)) + table.insert(self.tabs, newIndex, tab) + if focus then self:selectTab(tab) end + updateMargins(self) + return newIndex +end + +function UITabBar:onStyleApply(styleName, styleNode) + if styleNode['moveable'] then + self.tabsMoveable = styleNode['moveable'] + end +end + function UITabBar:removeTab(tab) local index = table.find(self.tabs, tab) if index == nil then return end diff --git a/modules/game_console/console.otui b/modules/game_console/console.otui index 9643b837..f156f0f2 100644 --- a/modules/game_console/console.otui +++ b/modules/game_console/console.otui @@ -78,6 +78,7 @@ Panel anchors.top: prev.top anchors.right: next.left margin-left: 5 + moveable: true TabButton id: nextChannelButton diff --git a/modules/game_interface/gameinterface.lua b/modules/game_interface/gameinterface.lua index 057277fe..c3d80e35 100644 --- a/modules/game_interface/gameinterface.lua +++ b/modules/game_interface/gameinterface.lua @@ -22,6 +22,7 @@ function init() gameRootPanel = g_ui.displayUI('gameinterface.otui') gameRootPanel:hide() gameRootPanel:lower() + gameRootPanel.onGeometryChange = updateStretchShrink mouseGrabberWidget = gameRootPanel:getChildById('mouseGrabber') mouseGrabberWidget.onMouseRelease = onMouseGrabberRelease