Navigation for large tab amounts, closes #211

This commit is contained in:
Sam 2013-12-03 20:25:13 +01:00
parent 319f32cdaa
commit f615b80fbc
3 changed files with 226 additions and 25 deletions

View File

@ -16,6 +16,24 @@ local function updateMargins(tabBar, ignored)
end end
end end
local function updateNavigation(tabBar)
if prevNavigation then
if #tabBar.preTabs > 0 or table.find(tabBar.tabs, tabBar.currentTab) ~= 1 then
prevNavigation:enable()
else
prevNavigation:disable()
end
end
if nextNavigation then
if #tabBar.postTabs > 0 or table.find(tabBar.tabs, tabBar.currentTab) ~= #tabBar.tabs then
nextNavigation:enable()
else
nextNavigation:disable()
end
end
end
local function updateIndexes(tabBar, tab, xoff) local function updateIndexes(tabBar, tab, xoff)
local tabs = tabBar.tabs local tabs = tabBar.tabs
local currentMargin = 0 local currentMargin = 0
@ -33,10 +51,11 @@ local function updateIndexes(tabBar, tab, xoff)
table.remove(tabs, table.find(tabs, tab)) table.remove(tabs, table.find(tabs, tab))
table.insert(tabs, newIndex, tab) table.insert(tabs, newIndex, tab)
end end
updateNavigation(tabBar)
end end
local function getMaxMargin(tabBar, tab) local function getMaxMargin(tabBar, tab)
if #tabBar.tabs == 0 then return end if #tabBar.tabs == 0 then return 0 end
local maxMargin = 0 local maxMargin = 0
for i = 1, #tabBar.tabs do for i = 1, #tabBar.tabs do
@ -44,7 +63,91 @@ local function getMaxMargin(tabBar, tab)
maxMargin = maxMargin + tabBar.tabs[i]:getWidth() maxMargin = maxMargin + tabBar.tabs[i]:getWidth()
end end
end end
return maxMargin + tabBar.tabSpacing * (#tabBar.tabs- 1) return maxMargin + tabBar.tabSpacing * (#tabBar.tabs - 1)
end
local function updateTabs(tabBar)
if #tabBar.postTabs > 0 then
local i = 1
while i <= #tabBar.postTabs do
local tab = tabBar.postTabs[i]
if getMaxMargin(tabBar) + tab:getWidth() > tabBar:getWidth() then
break
end
table.remove(tabBar.postTabs, i)
table.insert(tabBar.tabs, tab)
tab:setVisible(true)
end
end
if #tabBar.preTabs > 0 then
for i = #tabBar.preTabs, 1, -1 do
local tab = tabBar.preTabs[i]
if getMaxMargin(tabBar) + tab:getWidth() > tabBar:getWidth() then
break
end
table.remove(tabBar.preTabs, i)
table.insert(tabBar.tabs, 1, tab)
tab:setVisible(true)
end
end
updateNavigation(tabBar)
updateMargins(tabBar)
if not tabBar.currentTab and #tabBar.tabs > 0 then
tabBar:selectTab(tabBar.tabs[1])
end
end
local function hideTabs(tabBar, fromBack, toArray, width)
while #tabBar.tabs > 0 and getMaxMargin(tabBar) + width > tabBar:getWidth() do
local index = fromBack and #tabBar.tabs or 1
local tab = tabBar.tabs[index]
table.remove(tabBar.tabs, index)
if fromBack then
table.insert(toArray, 1, tab)
else
table.insert(toArray, tab)
end
if tabBar.currentTab == tab then
if #tabBar.tabs > 0 then
tabBar:selectTab(tabBar.tabs[#tabBar.tabs])
else
tabBar.currentTab:setChecked(false)
tabBar.currentTab = nil
end
end
tab:setVisible(false)
end
end
local function showPreTab(tabBar)
if #tabBar.preTabs == 0 then
return nil
end
local tmpTab = tabBar.preTabs[#tabBar.preTabs]
hideTabs(tabBar, true, tabBar.postTabs, tmpTab:getWidth())
table.remove(tabBar.preTabs, #tabBar.preTabs)
table.insert(tabBar.tabs, 1, tmpTab)
tmpTab:setVisible(true)
return tmpTab
end
local function showPostTab(tabBar)
if #tabBar.postTabs == 0 then
return nil
end
local tmpTab = tabBar.postTabs[1]
hideTabs(tabBar, false, tabBar.preTabs, tmpTab:getWidth())
table.remove(tabBar.postTabs, 1)
table.insert(tabBar.tabs, tmpTab)
tmpTab:setVisible(true)
return tmpTab
end end
local function onTabMousePress(tab, mousePos, mouseButton) local function onTabMousePress(tab, mousePos, mouseButton)
@ -104,6 +207,14 @@ function UIMoveableTabBar.create()
tabbar.selected = nil -- dragged tab tabbar.selected = nil -- dragged tab
tabbar.tabSpacing = 0 tabbar.tabSpacing = 0
tabbar.tabsMoveable = false tabbar.tabsMoveable = false
tabbar.preTabs = {}
tabbar.postTabs = {}
tabbar.prevNavigation = nil
tabbar.nextNavigation = nil
tabbar.onGeometryChange = function()
hideTabs(tabbar, true, tabbar.postTabs, 0)
updateTabs(tabbar)
end
return tabbar return tabbar
end end
@ -141,18 +252,26 @@ function UIMoveableTabBar:addTab(text, panel, menuCallback)
tab.onDragMove = onTabDragMove tab.onDragMove = onTabDragMove
tab.onDestroy = function() tab.tabPanel:destroy() end tab.onDestroy = function() tab.tabPanel:destroy() end
table.insert(self.tabs, tab) if #self.tabs == 0 then
if #self.tabs == 1 then
self:selectTab(tab) self:selectTab(tab)
tab:setMarginLeft(0) tab:setMarginLeft(0)
table.insert(self.tabs, tab)
else else
local newMargin = self.tabSpacing * (#self.tabs - 1) local newMargin = self.tabSpacing * #self.tabs
for i = 1, #self.tabs - 1 do for i = 1, #self.tabs do
newMargin = newMargin + self.tabs[i]:getWidth() newMargin = newMargin + self.tabs[i]:getWidth()
end end
tab:setMarginLeft(newMargin) tab:setMarginLeft(newMargin)
hideTabs(self, true, self.postTabs, tab:getWidth())
table.insert(self.tabs, tab)
if #self.tabs == 1 then
self:selectTab(tab)
end
updateMargins(self)
end end
updateNavigation(self)
return tab return tab
end end
@ -183,17 +302,33 @@ function UIMoveableTabBar:onStyleApply(styleName, styleNode)
end end
function UIMoveableTabBar:removeTab(tab) function UIMoveableTabBar:removeTab(tab)
local index = table.find(self.tabs, tab) local tabTables = {self.tabs, self.preTabs, self.postTabs}
if index == nil then return end local index = nil
local tabTable = nil
for i = 1, #tabTables do
index = table.find(tabTables[i], tab)
if index ~= nil then
tabTable = tabTables[i]
break
end
end
if tabTable == nil then
return
end
if self.currentTab == tab then if self.currentTab == tab then
self:selectPrevTab() self:selectPrevTab()
if #self.tabs == 1 then
self.currentTab = nil
end end
table.remove(self.tabs, index) end
table.remove(tabTable, index)
if tab.blinkEvent then if tab.blinkEvent then
removeEvent(tab.blinkEvent) removeEvent(tab.blinkEvent)
end end
tab:destroy() tab:destroy()
updateMargins(self) updateTabs(self)
end end
function UIMoveableTabBar:getTab(text) function UIMoveableTabBar:getTab(text)
@ -202,6 +337,16 @@ function UIMoveableTabBar:getTab(text)
return tab return tab
end end
end end
for k,tab in pairs(self.preTabs) do
if tab:getText():lower() == text:lower() then
return tab
end
end
for k,tab in pairs(self.postTabs) do
if tab:getText():lower() == text:lower() then
return tab
end
end
end end
function UIMoveableTabBar:selectTab(tab) function UIMoveableTabBar:selectTab(tab)
@ -226,23 +371,62 @@ function UIMoveableTabBar:selectTab(tab)
local parent = tab:getParent() local parent = tab:getParent()
parent:focusChild(tab, MouseFocusReason) parent:focusChild(tab, MouseFocusReason)
updateNavigation(self)
end end
function UIMoveableTabBar:selectNextTab() function UIMoveableTabBar:selectNextTab()
if self.currentTab == nil then return end if self.currentTab == nil then
return
end
local index = table.find(self.tabs, self.currentTab) local index = table.find(self.tabs, self.currentTab)
if index == nil then return end if index == nil then
local nextTab = self.tabs[index + 1] or self.tabs[1] return
if not nextTab then return end end
local newIndex = index + 1
if newIndex > #self.tabs then
if #self.postTabs > 0 then
local widget = showPostTab(self)
self:selectTab(widget)
updateTabs(self)
end
return
end
local nextTab = self.tabs[newIndex]
if not nextTab then
return
end
self:selectTab(nextTab) self:selectTab(nextTab)
end end
function UIMoveableTabBar:selectPrevTab() function UIMoveableTabBar:selectPrevTab()
if self.currentTab == nil then return end if self.currentTab == nil then
return
end
local index = table.find(self.tabs, self.currentTab) local index = table.find(self.tabs, self.currentTab)
if index == nil then return end if index == nil then
local prevTab = self.tabs[index - 1] or self.tabs[#self.tabs] return
if not prevTab then return end end
local newIndex = index - 1
if newIndex <= 0 then
if #self.preTabs > 0 then
local widget = showPreTab(self)
self:selectTab(widget)
updateTabs(self)
end
return
end
local prevTab = self.tabs[newIndex]
if not prevTab then
return
end
self:selectTab(prevTab) self:selectTab(prevTab)
end end
@ -265,3 +449,16 @@ end
function UIMoveableTabBar:getCurrentTab() function UIMoveableTabBar:getCurrentTab()
return self.currentTab return self.currentTab
end end
function UIMoveableTabBar:setNavigation(prevButton, nextButton)
prevNavigation = prevButton
nextNavigation = nextButton
if prevNavigation then
prevNavigation.onClick = function() self:selectPrevTab() end
end
if nextNavigation then
nextNavigation.onClick = function() self:selectNextTab() end
end
updateNavigation(self)
end

View File

@ -124,9 +124,6 @@ function init()
return true return true
end end
defaultTab = addTab(tr('Default'), true)
serverTab = addTab(tr('Server Log'), false)
g_keyboard.bindKeyPress('Shift+Up', function() navigateMessageHistory(1) end, consolePanel) g_keyboard.bindKeyPress('Shift+Up', function() navigateMessageHistory(1) end, consolePanel)
g_keyboard.bindKeyPress('Shift+Down', function() navigateMessageHistory(-1) end, consolePanel) g_keyboard.bindKeyPress('Shift+Down', function() navigateMessageHistory(-1) end, consolePanel)
g_keyboard.bindKeyPress('Tab', function() consoleTabBar:selectNextTab() end, consolePanel) g_keyboard.bindKeyPress('Tab', function() consoleTabBar:selectNextTab() end, consolePanel)
@ -135,8 +132,7 @@ function init()
g_keyboard.bindKeyPress('Ctrl+A', function() consoleTextEdit:clearText() end, consolePanel) g_keyboard.bindKeyPress('Ctrl+A', function() consoleTextEdit:clearText() end, consolePanel)
-- apply buttom functions after loaded -- apply buttom functions after loaded
consolePanel:getChildById('nextChannelButton').onClick = function() consoleTabBar:selectNextTab() end consoleTabBar:setNavigation(consolePanel:getChildById('prevChannelButton'), consolePanel:getChildById('nextChannelButton'))
consolePanel:getChildById('prevChannelButton').onClick = function() consoleTabBar:selectPrevTab() end
consoleTabBar.onTabChange = onTabChange consoleTabBar.onTabChange = onTabChange
-- tibia like hotkeys -- tibia like hotkeys
@ -146,6 +142,10 @@ function init()
consoleToggleChat = consolePanel:getChildById('toggleChat') consoleToggleChat = consolePanel:getChildById('toggleChat')
load() load()
if g_game.isOnline() then
online()
end
end end
function toggleChat() function toggleChat()
@ -287,8 +287,8 @@ function clear()
end end
channels = {} channels = {}
defaultTab.tabPanel:getChildById('consoleBuffer'):destroyChildren() consoleTabBar:removeTab(defaultTab)
serverTab.tabPanel:getChildById('consoleBuffer'):destroyChildren() consoleTabBar:removeTab(serverTab)
local npcTab = consoleTabBar:getTab('NPCs') local npcTab = consoleTabBar:getTab('NPCs')
if npcTab then if npcTab then
@ -1233,6 +1233,9 @@ function onClickIgnoreButton()
end end
function online() function online()
defaultTab = addTab(tr('Default'), true)
serverTab = addTab(tr('Server Log'), false)
if g_game.getProtocolVersion() < 862 then if g_game.getProtocolVersion() < 862 then
g_keyboard.bindKeyDown('Ctrl+R', openPlayerReportRuleViolationWindow) g_keyboard.bindKeyDown('Ctrl+R', openPlayerReportRuleViolationWindow)
end end

View File

@ -80,6 +80,7 @@ Panel
anchors.right: next.left anchors.right: next.left
margin-left: 5 margin-left: 5
margin-top: 3 margin-top: 3
margin-right: 5
moveable: true moveable: true
TabButton TabButton