Save miniwindows states

This commit is contained in:
Henrique Santiago 2012-06-21 16:31:22 -03:00
parent 96c363d997
commit a7c17cec2e
22 changed files with 317 additions and 60 deletions

View File

@ -34,3 +34,7 @@ Panel
OptionCheckBox OptionCheckBox
id: enableMusic id: enableMusic
!text: tr('Enable music') !text: tr('Enable music')
OptionCheckBox
id: showLeftPanel
!text: tr('Show left panel')

View File

@ -14,7 +14,8 @@ local options = { vsync = false,
showLevelsInConsole = true, showLevelsInConsole = true,
showPrivateMessagesInConsole = false, showPrivateMessagesInConsole = false,
showPrivateMessagesOnScreen = true, showPrivateMessagesOnScreen = true,
enableMusic = true } enableMusic = true,
showLeftPanel = false }
local generalPanel local generalPanel
local graphicsPanel local graphicsPanel
@ -129,6 +130,10 @@ function Options.setOption(key, value)
addEvent(function() addEvent(function()
g_sounds.enableMusic(value) g_sounds.enableMusic(value)
end) end)
elseif key == 'showLeftPanel' then
addEvent(function()
GameInterface.getLeftPanel():setOn(value)
end)
end end
Settings.set(key, value) Settings.set(key, value)
options[key] = value options[key] = value

View File

@ -17,7 +17,7 @@ OptionCheckBox < CheckBox
MainWindow MainWindow
id: optionsWindow id: optionsWindow
!text: tr('Options') !text: tr('Options')
size: 350 240 size: 350 280
@onEnter: Options.hide() @onEnter: Options.hide()
@onEscape: Options.hide() @onEscape: Options.hide()

View File

@ -4,7 +4,7 @@ SpinBox < UISpinBox
size: 86 20 size: 86 20
text-offset: 0 3 text-offset: 0 3
text-margin: 3 text-margin: 3
image-source: images/panel_flat.png image-source: /images/panel_flat.png
image-border: 1 image-border: 1
$disabled: $disabled:

View File

@ -5,9 +5,102 @@ function UIMiniWindow.create()
return miniwindow return miniwindow
end end
function UIMiniWindow:getClassName()
return 'UIMiniWindow'
end
function UIMiniWindow:open(dontSave)
self:setVisible(true)
if not dontSave then
self:setSettings({closed = false})
end
signalcall(self.onOpen, self)
end
function UIMiniWindow:close(dontSave)
self:setVisible(false)
if not dontSave then
self:setSettings({closed = true})
end
signalcall(self.onClose, self)
end
function UIMiniWindow:minimize(dontSave)
self:setOn(true)
self:getChildById('contentsPanel'):hide()
self:getChildById('miniwindowScrollBar'):hide()
self:getChildById('bottomResizeBorder'):hide()
self:getChildById('minimizeButton'):setOn(true)
self.savedHeight = self:getHeight()
self:setHeight(self.minimizedHeight)
if not dontSave then
self:setSettings({minimized = true})
end
signalcall(self.onMinimize, self)
end
function UIMiniWindow:maximize(dontSave)
self:setOn(false)
self:getChildById('contentsPanel'):show()
self:getChildById('miniwindowScrollBar'):show()
self:getChildById('bottomResizeBorder'):show()
self:getChildById('minimizeButton'):setOn(false)
self:setHeight(self.savedHeight)
if not dontSave then
self:setSettings({minimized = false})
end
signalcall(self.onMaximize, self)
end
function UIMiniWindow:onSetup() function UIMiniWindow:onSetup()
self:getChildById('closeButton').onClick = function() signalcall(self.onClose, self) end self:getChildById('closeButton').onClick =
self:getChildById('minimizeButton').onClick = function() signalcall(self.onMinimize, self) end function()
self:close()
end
self:getChildById('minimizeButton').onClick =
function()
if self:isOn() then
self:maximize()
else
self:minimize()
end
end
local settings = Settings.getNode('MiniWindows')
if settings then
local selfSettings = settings[self:getId()]
if selfSettings then
if selfSettings.parentId then
local parent = rootWidget:recursiveGetChildById(selfSettings.parentId)
if parent then
if parent:getClassName() == 'UIMiniWindowContainer' and selfSettings.index and parent:isOn() then
parent:scheduleInsert(self, selfSettings.index)
elseif selfSettings.position then
self:setParent(parent)
self:setPosition(topoint(selfSettings.position))
self:bindRectToParent()
end
end
end
if selfSettings.minimized then
self:minimize(true)
end
if selfSettings.closed then
self:close(true)
end
end
end
end end
function UIMiniWindow:onDragEnter(mousePos) function UIMiniWindow:onDragEnter(mousePos)
@ -18,6 +111,7 @@ function UIMiniWindow:onDragEnter(mousePos)
local containerParent = parent:getParent() local containerParent = parent:getParent()
parent:removeChild(self) parent:removeChild(self)
containerParent:addChild(self) containerParent:addChild(self)
parent:saveChildren()
end end
local oldPos = self:getPosition() local oldPos = self:getPosition()
@ -84,6 +178,15 @@ function UIMiniWindow:onDragLeave(droppedWidget, mousePos)
self.setMovedChildMargin = nil self.setMovedChildMargin = nil
self.movedIndex = nil self.movedIndex = nil
end end
local parent = self:getParent()
if parent then
if parent:getClassName() == 'UIMiniWindowContainer' then
parent:saveChildren()
else
self:saveParentPosition(parent:getId(), self:getPosition())
end
end
end end
function UIMiniWindow:onFocusChange(focused) function UIMiniWindow:onFocusChange(focused)
@ -95,28 +198,34 @@ function UIMiniWindow:onFocusChange(focused)
end end
end end
function UIMiniWindow:onClose() function UIMiniWindow:setSettings(data)
end local settings = Settings.getNode('MiniWindows')
if not settings then
function UIMiniWindow:onMinimize() settings = {}
if self:isOn() then
self:setOn(false)
self:getChildById('contentsPanel'):show()
self:getChildById('miniwindowScrollBar'):show()
self:getChildById('bottomResizeBorder'):show()
self:getChildById('minimizeButton'):setOn(false)
self:setHeight(self.savedHeight)
else
self.savedHeight = self:getHeight()
self:setHeight(self.minimizedHeight)
self:setOn(true)
self:getChildById('contentsPanel'):hide()
self:getChildById('miniwindowScrollBar'):hide()
self:getChildById('bottomResizeBorder'):hide()
self:getChildById('minimizeButton'):setOn(true)
end end
local id = self:getId()
if not settings[id] then
settings[id] = {}
end
for key,value in pairs(data) do
settings[id][key] = value
end
Settings.setNode('MiniWindows', settings)
end end
function UIMiniWindow:getClassName() function UIMiniWindow:saveParentPosition(parentId, position)
return 'UIMiniWindow' local selfSettings = {}
selfSettings.parentId = parentId
selfSettings.position = pointtostring(position)
self:setSettings(selfSettings)
end
function UIMiniWindow:saveParentIndex(parentId, index)
local selfSettings = {}
selfSettings.parentId = parentId
selfSettings.index = index
self:setSettings(selfSettings)
end end

View File

@ -2,6 +2,7 @@ UIMiniWindowContainer = extends(UIWidget)
function UIMiniWindowContainer.create() function UIMiniWindowContainer.create()
local container = UIMiniWindowContainer.internalCreate() local container = UIMiniWindowContainer.internalCreate()
container.scheduledWidgets = {}
container:setFocusable(false) container:setFocusable(false)
container:setPhantom(true) container:setPhantom(true)
return container return container
@ -14,7 +15,9 @@ function UIMiniWindowContainer:onDrop(widget, mousePos)
return true return true
end end
oldParent:removeChild(widget) if oldParent then
oldParent:removeChild(widget)
end
if widget.movedWidget then if widget.movedWidget then
local index = self:getChildIndex(widget.movedWidget) local index = self:getChildIndex(widget.movedWidget)
@ -27,6 +30,56 @@ function UIMiniWindowContainer:onDrop(widget, mousePos)
end end
end end
function UIMiniWindowContainer:swapInsert(widget, index)
local oldParent = widget:getParent()
local oldIndex = self:getChildIndex(widget)
if oldParent == self and oldIndex ~= index then
local oldWidget = self:getChildByIndex(index)
self:removeChild(oldWidget)
self:insertChild(oldIndex, oldWidget)
self:removeChild(widget)
self:insertChild(index, widget)
end
end
function UIMiniWindowContainer:scheduleInsert(widget, index)
if index - 1 > self:getChildCount() then
if self.scheduledWidgets[index] then
warning('replacing scheduled widget id ' .. widget:getId())
end
self.scheduledWidgets[index] = widget
else
local oldParent = widget:getParent()
if oldParent ~= self then
oldParent:removeChild(widget)
self:insertChild(index, widget)
else
self:swapInsert(widget, index)
end
while true do
local placed = false
for nIndex,nWidget in pairs(self.scheduledWidgets) do
if nIndex - 1 <= self:getChildCount() then
self:insertChild(nIndex, nWidget)
self.scheduledWidgets[nIndex] = nil
placed = true
break
end
end
if not placed then break end
end
end
end
function UIMiniWindowContainer:saveChildren()
local children = self:getChildren()
for i=1,#children do
children[i]:saveParentIndex(self:getId(), i)
end
end
function UIMiniWindowContainer:getClassName() function UIMiniWindowContainer:getClassName()
return 'UIMiniWindowContainer' return 'UIMiniWindowContainer'
end end

View File

@ -80,12 +80,24 @@ function UIResizeBorder:onStyleApply(styleName, styleNode)
end end
end end
function UIResizeBorder:onVisibilityChange(visible)
if visible and self.maximum == self.minimum then
self:hide()
end
end
function UIResizeBorder:setMaximum(maximum) function UIResizeBorder:setMaximum(maximum)
self.maximum = maximum self.maximum = maximum
if self.maximum == self.minimum then
self:hide()
end
end end
function UIResizeBorder:setMinimum(minimum) function UIResizeBorder:setMinimum(minimum)
self.minimum = minimum self.minimum = minimum
if self.maximum == self.minimum then
self:hide()
end
end end
function UIResizeBorder:getMaximum() return self.maximum end function UIResizeBorder:getMaximum() return self.maximum end

View File

@ -36,7 +36,7 @@ table.insert(lifeBarColors, {percentAbove = -1, color = '#4F0000' } )
-- public functions -- public functions
function Battle.init() function Battle.init()
battleWindow = displayUI('battle.otui', GameInterface.getLeftPanel()) battleWindow = displayUI('battle.otui', GameInterface.getRightPanel())
battleButton = TopMenu.addGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', Battle.toggle) battleButton = TopMenu.addGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', 'battle.png', Battle.toggle)
battleButton:setOn(true) battleButton:setOn(true)
Keyboard.bindKeyDown('Ctrl+B', Battle.toggle) Keyboard.bindKeyDown('Ctrl+B', Battle.toggle)
@ -93,9 +93,17 @@ function Battle.terminate()
end end
function Battle.toggle() function Battle.toggle()
local visible = not battleWindow:isExplicitlyVisible() if battleButton:isOn() then
battleWindow:setVisible(visible) battleWindow:close()
battleButton:setOn(visible) battleButton:setOn(false)
else
battleWindow:open()
battleButton:setOn(true)
end
end
function Battle.onMiniWindowClose()
battleButton:setOn(false)
end end
function Battle.addAllCreatures() function Battle.addAllCreatures()

View File

@ -41,7 +41,7 @@ MiniWindow
!text: tr('Battle') !text: tr('Battle')
height: 166 height: 166
icon: battle.png icon: battle.png
@onClose: Battle.toggle() @onClose: Battle.onMiniWindowClose()
MiniWindowContents MiniWindowContents
BattlePlayers BattlePlayers

View File

@ -129,8 +129,15 @@ function CombatControls.offline()
end end
function CombatControls.toggle() function CombatControls.toggle()
local visible = not combatControlsWindow:isExplicitlyVisible() if combatControlsButton:isOn() then
combatControlsWindow:setVisible(visible) combatControlsWindow:close()
combatControlsButton:setOn(visible) combatControlsButton:setOn(false)
else
combatControlsWindow:open()
combatControlsButton:setOn(true)
end
end end
function CombatControls.onMiniWindowClose()
combatControlsButton:setOn(false)
end

View File

@ -20,10 +20,11 @@ SafeFightBox < CombatBox
image-source: /game_combatcontrols/icons/safefight.png image-source: /game_combatcontrols/icons/safefight.png
MiniWindow MiniWindow
id: combatControlsWindow
!text: tr('Combat Controls') !text: tr('Combat Controls')
icon: combatcontrols.png icon: combatcontrols.png
height: 64 height: 64
@onClose: CombatControls.toggle() @onClose: CombatControls.onMiniWindowClose()
MiniWindowContents MiniWindowContents
FightOffensiveBox FightOffensiveBox

View File

@ -35,7 +35,7 @@ function HealthBar.init()
connect(g_game, { onGameEnd = HealthBar.offline }) connect(g_game, { onGameEnd = HealthBar.offline })
healthBarWindow = displayUI('healthbar.otui', GameInterface.getLeftPanel()) healthBarWindow = displayUI('healthbar.otui', GameInterface.getRightPanel())
healthBarButton = TopMenu.addGameToggleButton('healthBarButton', tr('Health Bar'), 'healthbar.png', HealthBar.toggle) healthBarButton = TopMenu.addGameToggleButton('healthBarButton', tr('Health Bar'), 'healthbar.png', HealthBar.toggle)
healthBarButton:setOn(true) healthBarButton:setOn(true)
healthBar = healthBarWindow:recursiveGetChildById('healthBar') healthBar = healthBarWindow:recursiveGetChildById('healthBar')
@ -71,9 +71,17 @@ function HealthBar.terminate()
end end
function HealthBar.toggle() function HealthBar.toggle()
local visible = not healthBarWindow:isExplicitlyVisible() if healthBarButton:isOn() then
healthBarWindow:setVisible(visible) healthBarWindow:close()
healthBarButton:setOn(visible) healthBarButton:setOn(false)
else
healthBarWindow:open()
healthBarButton:setOn(true)
end
end
function HealthBar.onMiniWindowClose()
healthBarButton:setOn(false)
end end
function HealthBar.offline() function HealthBar.offline()

View File

@ -45,7 +45,7 @@ MiniWindow
id: healthBarWindow id: healthBarWindow
!text: tr('Health Bar') !text: tr('Health Bar')
height: 86 height: 86
@onClose: HealthBar.toggle() @onClose: HealthBar.onMiniWindowClose()
MiniWindowContents MiniWindowContents
HealthBar HealthBar
@ -61,4 +61,3 @@ MiniWindow
margin-top: 5 margin-top: 5
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.horizontalcenter: parent.horizontalcenter anchors.horizontalcenter: parent.horizontalcenter

View File

@ -9,6 +9,15 @@ local gameBottomPanel
local logoutButton local logoutButton
local mouseGrabberWidget local mouseGrabberWidget
local function onLeftPanelVisibilityChange(leftPanel, visible)
if not visible then
local children = leftPanel:getChildren()
for i=1,#children do
children[i]:setParent(gameRightPanel)
end
end
end
function GameInterface.init() function GameInterface.init()
connect(g_game, { onGameStart = GameInterface.show }, true) connect(g_game, { onGameStart = GameInterface.show }, true)
connect(g_game, { onGameEnd = GameInterface.hide }, true) connect(g_game, { onGameEnd = GameInterface.hide }, true)
@ -24,6 +33,7 @@ function GameInterface.init()
gameRightPanel = gameRootPanel:getChildById('gameRightPanel') gameRightPanel = gameRootPanel:getChildById('gameRightPanel')
gameLeftPanel = gameRootPanel:getChildById('gameLeftPanel') gameLeftPanel = gameRootPanel:getChildById('gameLeftPanel')
gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel') gameBottomPanel = gameRootPanel:getChildById('gameBottomPanel')
connect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange })
logoutButton = TopMenu.addRightButton('logoutButton', 'Logout', '/images/logout.png', GameInterface.tryLogout) logoutButton = TopMenu.addRightButton('logoutButton', 'Logout', '/images/logout.png', GameInterface.tryLogout)
logoutButton:hide() logoutButton:hide()
@ -63,6 +73,7 @@ end
function GameInterface.terminate() function GameInterface.terminate()
disconnect(g_game, { onGameStart = GameInterface.show }) disconnect(g_game, { onGameStart = GameInterface.show })
disconnect(g_game, { onGameEnd = GameInterface.hide }) disconnect(g_game, { onGameEnd = GameInterface.hide })
disconnect(gameLeftPanel, { onVisibilityChange = onLeftPanelVisibilityChange })
logoutButton:destroy() logoutButton:destroy()
logoutButton = nil logoutButton = nil

View File

@ -40,6 +40,11 @@ UIWidget
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
focusable: false focusable: false
visible: true
on: true
$!on:
width: 0
visible: false
GameSidePanel GameSidePanel
id: gameRightPanel id: gameRightPanel
@ -49,6 +54,7 @@ UIWidget
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
focusable: false focusable: false
on: true
Splitter Splitter
id: bottomSplitter id: bottomSplitter

View File

@ -14,7 +14,6 @@ function Inventory.init()
Keyboard.bindKeyDown('Ctrl+I', Inventory.toggle) Keyboard.bindKeyDown('Ctrl+I', Inventory.toggle)
inventoryWindow = displayUI('inventory.otui', GameInterface.getRightPanel()) inventoryWindow = displayUI('inventory.otui', GameInterface.getRightPanel())
inventoryWindow.onClose = Inventory.toggle
inventoryPanel = inventoryWindow:getChildById('contentsPanel') inventoryPanel = inventoryWindow:getChildById('contentsPanel')
inventoryButton = TopMenu.addGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', 'inventory.png', Inventory.toggle) inventoryButton = TopMenu.addGameToggleButton('inventoryButton', tr('Inventory') .. ' (Ctrl+I)', 'inventory.png', Inventory.toggle)
inventoryButton:setOn(true) inventoryButton:setOn(true)
@ -50,9 +49,17 @@ function Inventory.refresh()
end end
function Inventory.toggle() function Inventory.toggle()
local visible = not inventoryWindow:isExplicitlyVisible() if inventoryButton:isOn() then
inventoryWindow:setVisible(visible) inventoryWindow:close()
inventoryButton:setOn(visible) inventoryButton:setOn(false)
else
inventoryWindow:open()
inventoryButton:setOn(true)
end
end
function Inventory.onMiniWindowClose()
inventoryButton:setOn(false)
end end
-- hooked events -- hooked events

View File

@ -1,9 +1,9 @@
MiniWindow MiniWindow
id: inventoryMiniWindow id: inventoryWindow
!text: tr('Inventory') !text: tr('Inventory')
icon: inventory.png icon: inventory.png
height: 180 height: 180
@onClose: Inventory.toggle() @onClose: Inventory.onMiniWindowClose()
MiniWindowContents MiniWindowContents
Item Item

View File

@ -35,7 +35,7 @@ function Skills.init()
onSkillChange = Skills.onSkillChange onSkillChange = Skills.onSkillChange
}) })
skillsWindow = displayUI('skills.otui', GameInterface.getLeftPanel()) skillsWindow = displayUI('skills.otui', GameInterface.getRightPanel())
skillsButton = TopMenu.addGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', 'skills.png', Skills.toggle) skillsButton = TopMenu.addGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', 'skills.png', Skills.toggle)
skillsButton:setOn(true) skillsButton:setOn(true)
Keyboard.bindKeyDown('Ctrl+S', Skills.toggle) Keyboard.bindKeyDown('Ctrl+S', Skills.toggle)
@ -84,9 +84,17 @@ function Skills.refresh()
end end
function Skills.toggle() function Skills.toggle()
local visible = not skillsWindow:isExplicitlyVisible() if skillsButton:isOn() then
skillsWindow:setVisible(visible) skillsWindow:close()
skillsButton:setOn(visible) skillsButton:setOn(false)
else
skillsWindow:open()
skillsButton:setOn(true)
end
end
function Skills.onMiniWindowClose()
skillsButton:setOn(false)
end end
function Skills.onSkillButtonClick(button) function Skills.onSkillButtonClick(button)

View File

@ -33,9 +33,9 @@ SkillPercentPanel < ProgressBar
MiniWindow MiniWindow
id: skillWindow id: skillWindow
!text: tr('Skills') !text: tr('Skills')
height: 350 height: 150
icon: skills.png icon: skills.png
@onClose: Skills.toggle() @onClose: Skills.onMiniWindowClose()
MiniWindowContents MiniWindowContents
anchors.fill: parent anchors.fill: parent

View File

@ -14,7 +14,7 @@ function VipList.init()
Keyboard.bindKeyDown('Ctrl+P', VipList.toggle) Keyboard.bindKeyDown('Ctrl+P', VipList.toggle)
vipWindow = displayUI('viplist.otui', GameInterface.getLeftPanel()) vipWindow = displayUI('viplist.otui', GameInterface.getRightPanel())
vipButton = TopMenu.addGameToggleButton('vipListButton', tr('VIP list') .. ' (Ctrl+P)', 'viplist.png', VipList.toggle) vipButton = TopMenu.addGameToggleButton('vipListButton', tr('VIP list') .. ' (Ctrl+P)', 'viplist.png', VipList.toggle)
vipButton:setOn(true) vipButton:setOn(true)
@ -48,9 +48,17 @@ function VipList.clear()
end end
function VipList.toggle() function VipList.toggle()
local visible = not vipWindow:isExplicitlyVisible() if vipButton:isOn() then
vipWindow:setVisible(visible) vipWindow:close()
vipButton:setOn(visible) vipButton:setOn(false)
else
vipWindow:open()
vipButton:setOn(true)
end
end
function VipList.onMiniWindowClose()
vipButton:setOn(false)
end end
function VipList.createAddWindow() function VipList.createAddWindow()

View File

@ -8,7 +8,7 @@ MiniWindow
!text: tr('VIP List') !text: tr('VIP List')
height: 100 height: 100
icon: viplist.png icon: viplist.png
@onClose: VipList.toggle() @onClose: VipList.onMiniWindowClose()
MiniWindowContents MiniWindowContents
layout: verticalBox layout: verticalBox

View File

@ -375,6 +375,11 @@ void UIWidget::moveChildToIndex(const UIWidgetPtr& child, int index)
if(!child) if(!child)
return; return;
if((uint)index - 1 > m_children.size()) {
g_logger.error(stdext::format("moving %s to index %d on %s", child->getId(), index, m_id));
return;
}
// remove and push child again // remove and push child again
auto it = std::find(m_children.begin(), m_children.end(), child); auto it = std::find(m_children.begin(), m_children.end(), child);
if(it == m_children.end()) { if(it == m_children.end()) {
@ -384,6 +389,7 @@ void UIWidget::moveChildToIndex(const UIWidgetPtr& child, int index)
m_children.erase(it); m_children.erase(it);
m_children.insert(m_children.begin() + index - 1, child); m_children.insert(m_children.begin() + index - 1, child);
updateChildrenIndexStates(); updateChildrenIndexStates();
updateLayout();
} }
void UIWidget::lockChild(const UIWidgetPtr& child) void UIWidget::lockChild(const UIWidgetPtr& child)
@ -751,7 +757,10 @@ void UIWidget::destroyChildren()
void UIWidget::setId(const std::string& id) void UIWidget::setId(const std::string& id)
{ {
m_id = id; if(id != m_id) {
m_id = id;
callLuaField("onIdChange", id);
}
} }
void UIWidget::setParent(const UIWidgetPtr& parent) void UIWidget::setParent(const UIWidgetPtr& parent)
@ -885,6 +894,8 @@ void UIWidget::setVisible(bool visible)
g_ui.onWidgetAppear(asUIWidget()); g_ui.onWidgetAppear(asUIWidget());
else else
g_ui.onWidgetDisappear(asUIWidget()); g_ui.onWidgetDisappear(asUIWidget());
callLuaField("onVisibilityChange", visible);
} }
} }