Minimap, hotkeys and lot of other changes
* Begin working on a new layout system for UIMinimap and later UIMap, this new layout system allows to add widgets to the minimap * Add option to disable motd * Rework hotkey binding * Lots of fixes in hotkeys manager * Add fullmap view using Ctrl+Shift+M * Prevent some crashs in ThingType draw * Add function to load minimap from PNG files * Fixes in minimap saving * Fixes in Tile::isClickable * Add UIMapAnchorLayout, new layout for maps * Fix freezes in win32 when pressing alt key
This commit is contained in:
parent
f8b078ea91
commit
9a54bfcc90
|
@ -37,3 +37,4 @@ otclient.layout
|
||||||
LOCALTODO
|
LOCALTODO
|
||||||
tags
|
tags
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
.directory
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 210 B |
|
@ -2,9 +2,13 @@ MinimapFlag < UIWidget
|
||||||
size: 11 11
|
size: 11 11
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
focusable: false
|
||||||
|
|
||||||
MinimapFlags < UIWidget
|
MinimapCross < UIWidget
|
||||||
anchors.fill: parent
|
focusable: false
|
||||||
|
phantom: true
|
||||||
|
image: /images/game/minimap/cross
|
||||||
|
size: 16 16
|
||||||
|
|
||||||
MinimapFloorUpButton < Button
|
MinimapFloorUpButton < Button
|
||||||
size: 20 20
|
size: 20 20
|
||||||
|
@ -61,12 +65,7 @@ Minimap < UIMinimap
|
||||||
draggable: true
|
draggable: true
|
||||||
focusable: false
|
focusable: false
|
||||||
cross: true
|
cross: true
|
||||||
@onGeometryChange: self:updateFlags()
|
color: black
|
||||||
|
|
||||||
MinimapFlags
|
|
||||||
id: flags
|
|
||||||
phantom: true
|
|
||||||
focusable: false
|
|
||||||
|
|
||||||
MinimapFloorUpButton
|
MinimapFloorUpButton
|
||||||
id: floorUp
|
id: floorUp
|
||||||
|
@ -245,22 +244,3 @@ MinimapFlagWindow < MainWindow
|
||||||
width: 64
|
width: 64
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
// Minimap Full Panel
|
|
||||||
|
|
||||||
MinimapFullPanel < FlatPanel
|
|
||||||
phantom: false
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.top: topMenu.bottom
|
|
||||||
|
|
||||||
ImageView
|
|
||||||
id: image
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Button
|
|
||||||
!text: tr('Close')
|
|
||||||
margin-right: 4
|
|
||||||
margin-top: 4
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
@onClick: self:getParent():destroy()
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ Module
|
||||||
load-later:
|
load-later:
|
||||||
- client_styles
|
- client_styles
|
||||||
- client_locales
|
- client_locales
|
||||||
//- client_particles
|
|
||||||
- client_topmenu
|
- client_topmenu
|
||||||
- client_background
|
- client_background
|
||||||
- client_entergame
|
- client_entergame
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
-- private variables
|
-- private variables
|
||||||
local background
|
local background
|
||||||
|
local clientVersionLabel
|
||||||
|
|
||||||
-- public functions
|
-- public functions
|
||||||
function init()
|
function init()
|
||||||
background = g_ui.displayUI('background')
|
background = g_ui.displayUI('background')
|
||||||
background:lower()
|
background:lower()
|
||||||
|
|
||||||
local clientVersionLabel = background:getChildById('clientVersionLabel')
|
clientVersionLabel = background:getChildById('clientVersionLabel')
|
||||||
clientVersionLabel:setText(g_app.getName() .. ' ' .. g_app.getVersion() .. '\n' ..
|
clientVersionLabel:setText(g_app.getName() .. ' ' .. g_app.getVersion() .. '\n' ..
|
||||||
'Rev ' .. g_app.getBuildRevision() .. ' ('.. g_app.getBuildCommit() .. ')\n' ..
|
'Rev ' .. g_app.getBuildRevision() .. ' ('.. g_app.getBuildCommit() .. ')\n' ..
|
||||||
'Built on ' .. g_app.getBuildDate())
|
'Built on ' .. g_app.getBuildDate())
|
||||||
|
|
||||||
if not g_game.isOnline() then
|
if not g_game.isOnline() then
|
||||||
g_effects.fadeIn(clientVersionLabel, 1500)
|
addEvent(function() g_effects.fadeIn(clientVersionLabel, 1500) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
connect(g_game, { onGameStart = hide })
|
connect(g_game, { onGameStart = hide })
|
||||||
|
@ -40,3 +41,7 @@ end
|
||||||
function hideVersionLabel()
|
function hideVersionLabel()
|
||||||
background:getChildById('clientVersionLabel'):hide()
|
background:getChildById('clientVersionLabel'):hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function setVersionText(text)
|
||||||
|
clientVersionLabel:setText(text)
|
||||||
|
end
|
||||||
|
|
|
@ -111,7 +111,7 @@ end
|
||||||
|
|
||||||
function onGameConnectionError(message, code)
|
function onGameConnectionError(message, code)
|
||||||
CharacterList.destroyLoadBox()
|
CharacterList.destroyLoadBox()
|
||||||
errorBox = displayErrorBox(tr("Login Error"), message)
|
errorBox = displayErrorBox(tr("Connection Error"), message)
|
||||||
errorBox.onOk = function()
|
errorBox.onOk = function()
|
||||||
errorBox = nil
|
errorBox = nil
|
||||||
CharacterList.showAgain()
|
CharacterList.showAgain()
|
||||||
|
|
|
@ -8,6 +8,7 @@ local motdButton
|
||||||
local enterGameButton
|
local enterGameButton
|
||||||
local protocolBox
|
local protocolBox
|
||||||
local protocolLogin
|
local protocolLogin
|
||||||
|
local motdEnabled = true
|
||||||
|
|
||||||
-- private functions
|
-- private functions
|
||||||
local function onError(protocol, message, errorCode)
|
local function onError(protocol, message, errorCode)
|
||||||
|
@ -27,7 +28,9 @@ end
|
||||||
local function onMotd(protocol, motd)
|
local function onMotd(protocol, motd)
|
||||||
G.motdNumber = tonumber(motd:sub(0, motd:find("\n")))
|
G.motdNumber = tonumber(motd:sub(0, motd:find("\n")))
|
||||||
G.motdMessage = motd:sub(motd:find("\n") + 1, #motd)
|
G.motdMessage = motd:sub(motd:find("\n") + 1, #motd)
|
||||||
|
if motdEnabled then
|
||||||
motdButton:show()
|
motdButton:show()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onCharacterList(protocol, characters, account, otui)
|
local function onCharacterList(protocol, characters, account, otui)
|
||||||
|
@ -45,6 +48,7 @@ local function onCharacterList(protocol, characters, account, otui)
|
||||||
CharacterList.create(characters, account, otui)
|
CharacterList.create(characters, account, otui)
|
||||||
CharacterList.show()
|
CharacterList.show()
|
||||||
|
|
||||||
|
if motdEnabled then
|
||||||
local lastMotdNumber = g_settings.getNumber("motd")
|
local lastMotdNumber = g_settings.getNumber("motd")
|
||||||
if G.motdNumber and G.motdNumber ~= lastMotdNumber then
|
if G.motdNumber and G.motdNumber ~= lastMotdNumber then
|
||||||
g_settings.set("motd", motdNumber)
|
g_settings.set("motd", motdNumber)
|
||||||
|
@ -52,6 +56,7 @@ local function onCharacterList(protocol, characters, account, otui)
|
||||||
connect(motdWindow, { onOk = function() CharacterList.show() motdWindow = nil end })
|
connect(motdWindow, { onOk = function() CharacterList.show() motdWindow = nil end })
|
||||||
CharacterList.hide()
|
CharacterList.hide()
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onChangeProtocol(combobox, option)
|
local function onChangeProtocol(combobox, option)
|
||||||
|
@ -81,7 +86,7 @@ function EnterGame.init()
|
||||||
motdButton:hide()
|
motdButton:hide()
|
||||||
g_keyboard.bindKeyDown('Ctrl+G', EnterGame.openWindow)
|
g_keyboard.bindKeyDown('Ctrl+G', EnterGame.openWindow)
|
||||||
|
|
||||||
if G.motdNumber then
|
if motdEnabled and G.motdNumber then
|
||||||
motdButton:show()
|
motdButton:show()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,13 +132,15 @@ function EnterGame.firstShow()
|
||||||
local host = g_settings.get('host')
|
local host = g_settings.get('host')
|
||||||
local autologin = g_settings.getBoolean('autologin')
|
local autologin = g_settings.getBoolean('autologin')
|
||||||
if #host > 0 and #password > 0 and #account > 0 and autologin then
|
if #host > 0 and #password > 0 and #account > 0 and autologin then
|
||||||
autoLoginEvent = addEvent(EnterGame.doLogin)
|
connect(g_app, { onRun = function()
|
||||||
|
if not g_settings.getBoolean('autologin') then return end
|
||||||
|
EnterGame.doLogin()
|
||||||
|
end})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function EnterGame.terminate()
|
function EnterGame.terminate()
|
||||||
g_keyboard.unbindKeyDown('Ctrl+G')
|
g_keyboard.unbindKeyDown('Ctrl+G')
|
||||||
removeEvent(autoLoginEvent)
|
|
||||||
enterGame:destroy()
|
enterGame:destroy()
|
||||||
enterGame = nil
|
enterGame = nil
|
||||||
enterGameButton:destroy()
|
enterGameButton:destroy()
|
||||||
|
@ -186,7 +193,6 @@ function EnterGame.clearAccountFields()
|
||||||
end
|
end
|
||||||
|
|
||||||
function EnterGame.doLogin()
|
function EnterGame.doLogin()
|
||||||
autoLoginEvent = nil
|
|
||||||
G.account = enterGame:getChildById('accountNameTextEdit'):getText()
|
G.account = enterGame:getChildById('accountNameTextEdit'):getText()
|
||||||
G.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
|
G.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
|
||||||
G.host = enterGame:getChildById('serverHostTextEdit'):getText()
|
G.host = enterGame:getChildById('serverHostTextEdit'):getText()
|
||||||
|
@ -252,10 +258,6 @@ function EnterGame.setDefaultServer(host, port, protocol)
|
||||||
protocolBox:setCurrentOption(protocol)
|
protocolBox:setCurrentOption(protocol)
|
||||||
accountTextEdit:setText('')
|
accountTextEdit:setText('')
|
||||||
passwordTextEdit:setText('')
|
passwordTextEdit:setText('')
|
||||||
|
|
||||||
if autoLoginEvent then
|
|
||||||
autoLoginEvent:cancel()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -297,3 +299,7 @@ function EnterGame.setServerInfo(message)
|
||||||
label:setText(message)
|
label:setText(message)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function EnterGame.disableMotd()
|
||||||
|
motdEnabled = false
|
||||||
|
motdButton:hide()
|
||||||
|
end
|
||||||
|
|
|
@ -25,6 +25,8 @@ end
|
||||||
function terminate()
|
function terminate()
|
||||||
disconnect(g_game, { onGameStart = onGameStart,
|
disconnect(g_game, { onGameStart = onGameStart,
|
||||||
onGameEnd = onGameEnd })
|
onGameEnd = onGameEnd })
|
||||||
|
removeEvent(firstReportEvent)
|
||||||
|
removeEvent(sendReportEvent)
|
||||||
end
|
end
|
||||||
|
|
||||||
function configure(host, port, delay)
|
function configure(host, port, delay)
|
||||||
|
@ -45,13 +47,15 @@ end
|
||||||
|
|
||||||
function onGameStart()
|
function onGameStart()
|
||||||
if not HOST then return end
|
if not HOST then return end
|
||||||
|
removeEvent(firstReportEvent)
|
||||||
|
removeEvent(sendReportEvent)
|
||||||
firstReportEvent = addEvent(sendReport, FIRST_REPORT_DELAY*1000)
|
firstReportEvent = addEvent(sendReport, FIRST_REPORT_DELAY*1000)
|
||||||
sendReportEvent = cycleEvent(sendReport, REPORT_DELAY*1000)
|
sendReportEvent = cycleEvent(sendReport, REPORT_DELAY*1000)
|
||||||
end
|
end
|
||||||
|
|
||||||
function onGameEnd()
|
function onGameEnd()
|
||||||
removeEvent(sendReportEvent)
|
|
||||||
removeEvent(firstReportEvent)
|
removeEvent(firstReportEvent)
|
||||||
|
removeEvent(sendReportEvent)
|
||||||
end
|
end
|
||||||
|
|
||||||
function onConnect(protocol)
|
function onConnect(protocol)
|
||||||
|
@ -84,6 +88,7 @@ function onConnect(protocol)
|
||||||
post = post .. '&cpu=' .. g_platform.getCPUName()
|
post = post .. '&cpu=' .. g_platform.getCPUName()
|
||||||
post = post .. '&mem=' .. g_platform.getTotalSystemMemory()
|
post = post .. '&mem=' .. g_platform.getTotalSystemMemory()
|
||||||
post = post .. '&os_name=' .. g_platform.getOSName()
|
post = post .. '&os_name=' .. g_platform.getOSName()
|
||||||
|
post = post .. getAdditionalData()
|
||||||
|
|
||||||
local message = ''
|
local message = ''
|
||||||
message = message .. "POST /report HTTP/1.1\r\n"
|
message = message .. "POST /report HTTP/1.1\r\n"
|
||||||
|
@ -98,6 +103,10 @@ function onConnect(protocol)
|
||||||
protocol:recv()
|
protocol:recv()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function getAdditionalData()
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
|
||||||
function onRecv(protocol, message)
|
function onRecv(protocol, message)
|
||||||
if string.find(message, 'HTTP/1.1 200 OK') then
|
if string.find(message, 'HTTP/1.1 200 OK') then
|
||||||
--pinfo('Stats sent to server successfully!')
|
--pinfo('Stats sent to server successfully!')
|
||||||
|
|
|
@ -4,7 +4,6 @@ g_keyboard = {}
|
||||||
-- private functions
|
-- private functions
|
||||||
function translateKeyCombo(keyCombo)
|
function translateKeyCombo(keyCombo)
|
||||||
if not keyCombo or #keyCombo == 0 then return nil end
|
if not keyCombo or #keyCombo == 0 then return nil end
|
||||||
table.sort(keyCombo)
|
|
||||||
local keyComboDesc = ''
|
local keyComboDesc = ''
|
||||||
for k,v in pairs(keyCombo) do
|
for k,v in pairs(keyCombo) do
|
||||||
local keyDesc = KeyCodeDescs[v]
|
local keyDesc = KeyCodeDescs[v]
|
||||||
|
@ -65,47 +64,29 @@ function determineKeyComboDesc(keyCode, keyboardModifiers)
|
||||||
end
|
end
|
||||||
table.insert(keyCombo, keyCode)
|
table.insert(keyCombo, keyCode)
|
||||||
end
|
end
|
||||||
table.sort(keyCombo)
|
|
||||||
return translateKeyCombo(keyCombo)
|
return translateKeyCombo(keyCombo)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onWidgetKeyDown(widget, keyCode, keyboardModifiers)
|
local function onWidgetKeyDown(widget, keyCode, keyboardModifiers)
|
||||||
if keyCode == KeyUnknown then return false end
|
if keyCode == KeyUnknown then return false end
|
||||||
local callback = widget.boundAloneKeyDownCombos[determineKeyComboDesc(keyCode, KeyboardNoModifier)]
|
local callback = widget.boundAloneKeyDownCombos[determineKeyComboDesc(keyCode, KeyboardNoModifier)]
|
||||||
if callback then
|
signalcall(callback, widget, keyCode)
|
||||||
callback(widget, keyCode)
|
|
||||||
end
|
|
||||||
callback = widget.boundKeyDownCombos[determineKeyComboDesc(keyCode, keyboardModifiers)]
|
callback = widget.boundKeyDownCombos[determineKeyComboDesc(keyCode, keyboardModifiers)]
|
||||||
if callback then
|
return signalcall(callback, widget, keyCode)
|
||||||
callback(widget, keyCode)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onWidgetKeyUp(widget, keyCode, keyboardModifiers)
|
local function onWidgetKeyUp(widget, keyCode, keyboardModifiers)
|
||||||
if keyCode == KeyUnknown then return false end
|
if keyCode == KeyUnknown then return false end
|
||||||
local callback = widget.boundAloneKeyUpCombos[determineKeyComboDesc(keyCode, KeyboardNoModifier)]
|
local callback = widget.boundAloneKeyUpCombos[determineKeyComboDesc(keyCode, KeyboardNoModifier)]
|
||||||
if callback then
|
signalcall(callback, widget, keyCode)
|
||||||
callback(widget, keyCode)
|
|
||||||
end
|
|
||||||
callback = widget.boundKeyUpCombos[determineKeyComboDesc(keyCode, keyboardModifiers)]
|
callback = widget.boundKeyUpCombos[determineKeyComboDesc(keyCode, keyboardModifiers)]
|
||||||
if callback then
|
return signalcall(callback, widget, keyCode)
|
||||||
callback(widget, keyCode)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onWidgetKeyPress(widget, keyCode, keyboardModifiers, autoRepeatTicks)
|
local function onWidgetKeyPress(widget, keyCode, keyboardModifiers, autoRepeatTicks)
|
||||||
if keyCode == KeyUnknown then return false end
|
if keyCode == KeyUnknown then return false end
|
||||||
local keyComboDesc = determineKeyComboDesc(keyCode, keyboardModifiers)
|
local callback = widget.boundKeyPressCombos[determineKeyComboDesc(keyCode, keyboardModifiers)]
|
||||||
local comboConf = widget.boundKeyPressCombos[keyComboDesc]
|
return signalcall(callback, widget, keyCode, autoRepeatTicks)
|
||||||
if comboConf and (autoRepeatTicks >= comboConf.autoRepeatDelay or autoRepeatTicks == 0) and comboConf.callback then
|
|
||||||
comboConf.callback(widget, keyCode)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function connectKeyDownEvent(widget)
|
local function connectKeyDownEvent(widget)
|
||||||
|
@ -133,13 +114,10 @@ function g_keyboard.bindKeyDown(keyComboDesc, callback, widget, alone)
|
||||||
widget = widget or rootWidget
|
widget = widget or rootWidget
|
||||||
connectKeyDownEvent(widget)
|
connectKeyDownEvent(widget)
|
||||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||||
if widget.boundKeyDownCombos[keyComboDesc] then
|
|
||||||
pwarning('KeyDown event \'' .. keyComboDesc .. '\' redefined on widget ' .. widget:getId())
|
|
||||||
end
|
|
||||||
if alone then
|
if alone then
|
||||||
widget.boundAloneKeyDownCombos[keyComboDesc] = callback
|
connect(widget.boundAloneKeyDownCombos, keyComboDesc, callback)
|
||||||
else
|
else
|
||||||
widget.boundKeyDownCombos[keyComboDesc] = callback
|
connect(widget.boundKeyDownCombos, keyComboDesc, callback)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -147,53 +125,50 @@ function g_keyboard.bindKeyUp(keyComboDesc, callback, widget, alone)
|
||||||
widget = widget or rootWidget
|
widget = widget or rootWidget
|
||||||
connectKeyUpEvent(widget)
|
connectKeyUpEvent(widget)
|
||||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||||
if widget.boundKeyUpCombos[keyComboDesc] then
|
|
||||||
pwarning('KeyUp event \'' .. keyComboDesc .. '\' redefined on widget ' .. widget:getId())
|
|
||||||
end
|
|
||||||
if alone then
|
if alone then
|
||||||
widget.boundAloneKeyUpCombos[keyComboDesc] = callback
|
connect(widget.boundAloneKeyUpCombos, keyComboDesc, callback)
|
||||||
else
|
else
|
||||||
widget.boundKeyUpCombos[keyComboDesc] = callback
|
connect(widget.boundKeyUpCombos, keyComboDesc, callback)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function g_keyboard.bindKeyPress(keyComboDesc, callback, widget, autoRepeatDelay)
|
function g_keyboard.bindKeyPress(keyComboDesc, callback, widget)
|
||||||
autoRepeatDelay = autoRepeatDelay or 500
|
|
||||||
widget = widget or rootWidget
|
widget = widget or rootWidget
|
||||||
connectKeyPressEvent(widget)
|
connectKeyPressEvent(widget)
|
||||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||||
if widget.boundKeyPressCombos[keyComboDesc] then
|
connect(widget.boundKeyPressCombos, keyComboDesc, callback)
|
||||||
pwarning('KeyPress event \'' .. keyComboDesc .. '\' redefined on widget ' .. widget:getId())
|
|
||||||
end
|
|
||||||
widget.boundKeyPressCombos[keyComboDesc] = { callback = callback, autoRepeatDelay = autoRepeatDelay }
|
|
||||||
widget:setAutoRepeatDelay(math.min(autoRepeatDelay, widget:getAutoRepeatDelay()))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function g_keyboard.unbindKeyDown(keyComboDesc, widget)
|
local function getUnbindArgs(arg1, arg2)
|
||||||
|
local callback
|
||||||
|
local widget
|
||||||
|
if type(arg1) == 'function' then callback = arg1
|
||||||
|
elseif type(arg2) == 'function' then callback = arg2 end
|
||||||
|
if type(arg1) == 'userdata' then widget = arg1
|
||||||
|
elseif type(arg2) == 'userdata' then widget = arg2 end
|
||||||
widget = widget or rootWidget
|
widget = widget or rootWidget
|
||||||
|
return callback, widget
|
||||||
|
end
|
||||||
|
|
||||||
|
function g_keyboard.unbindKeyDown(keyComboDesc, arg1, arg2)
|
||||||
|
local callback, widget = getUnbindArgs(arg1, arg2)
|
||||||
if widget.boundKeyDownCombos == nil then return end
|
if widget.boundKeyDownCombos == nil then return end
|
||||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||||
if keyComboDesc then
|
disconnect(widget.boundKeyDownCombos, keyComboDesc, callback)
|
||||||
widget.boundKeyDownCombos[keyComboDesc] = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function g_keyboard.unbindKeyUp(keyComboDesc, widget)
|
function g_keyboard.unbindKeyUp(keyComboDesc, widget)
|
||||||
widget = widget or rootWidget
|
local callback, widget = getUnbindArgs(arg1, arg2)
|
||||||
if widget.boundKeyUpCombos == nil then return end
|
if widget.boundKeyUpCombos == nil then return end
|
||||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||||
if keyComboDesc then
|
disconnect(widget.boundKeyUpCombos, keyComboDesc, callback)
|
||||||
widget.boundKeyUpCombos[keyComboDesc] = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function g_keyboard.unbindKeyPress(keyComboDesc, widget)
|
function g_keyboard.unbindKeyPress(keyComboDesc, widget, callback)
|
||||||
widget = widget or rootWidget
|
local callback, widget = getUnbindArgs(arg1, arg2)
|
||||||
if widget.boundKeyPressCombos == nil then return end
|
if widget.boundKeyPressCombos == nil then return end
|
||||||
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
local keyComboDesc = retranslateKeyComboDesc(keyComboDesc)
|
||||||
if keyComboDesc then
|
disconnect(widget.boundKeyPressCombos, keyComboDesc, callback)
|
||||||
widget.boundKeyPressCombos[keyComboDesc] = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function g_keyboard.getModifiers()
|
function g_keyboard.getModifiers()
|
||||||
|
|
|
@ -13,6 +13,12 @@ function table.dump(t, depth)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function table.clear(t)
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
t[k] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function table.copy(t)
|
function table.copy(t)
|
||||||
local res = {}
|
local res = {}
|
||||||
for k,v in pairs(t) do
|
for k,v in pairs(t) do
|
||||||
|
|
|
@ -224,7 +224,9 @@ end
|
||||||
|
|
||||||
function UIScrollBar:setText(text)
|
function UIScrollBar:setText(text)
|
||||||
local valueLabel = self:getChildById('valueLabel')
|
local valueLabel = self:getChildById('valueLabel')
|
||||||
|
if valueLabel then
|
||||||
valueLabel:setText(text)
|
valueLabel:setText(text)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIScrollBar:onGeometryChange()
|
function UIScrollBar:onGeometryChange()
|
||||||
|
|
|
@ -67,6 +67,11 @@ function connect(object, arg1, arg2, arg3)
|
||||||
elseif type(object[signal]) == 'function' then
|
elseif type(object[signal]) == 'function' then
|
||||||
object[signal] = { object[signal] }
|
object[signal] = { object[signal] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if type(slot) ~= 'function' then
|
||||||
|
perror(debug.traceback('unable to connect a non function value'))
|
||||||
|
end
|
||||||
|
|
||||||
if type(object[signal]) == 'table' then
|
if type(object[signal]) == 'table' then
|
||||||
if pushFront then
|
if pushFront then
|
||||||
table.insert(object[signal], 1, slot)
|
table.insert(object[signal], 1, slot)
|
||||||
|
@ -80,9 +85,15 @@ end
|
||||||
function disconnect(object, arg1, arg2)
|
function disconnect(object, arg1, arg2)
|
||||||
local signalsAndSlots
|
local signalsAndSlots
|
||||||
if type(arg1) == 'string' then
|
if type(arg1) == 'string' then
|
||||||
|
if arg2 == nil then
|
||||||
|
object[arg1] = nil
|
||||||
|
return
|
||||||
|
end
|
||||||
signalsAndSlots = { [arg1] = arg2 }
|
signalsAndSlots = { [arg1] = arg2 }
|
||||||
else
|
elseif type(arg1) == 'table' then
|
||||||
signalsAndSlots = arg1
|
signalsAndSlots = arg1
|
||||||
|
else
|
||||||
|
perror(debug.traceback('unable to disconnect'))
|
||||||
end
|
end
|
||||||
|
|
||||||
for signal,slot in pairs(signalsAndSlots) do
|
for signal,slot in pairs(signalsAndSlots) do
|
||||||
|
|
|
@ -34,6 +34,7 @@ perCharacter = true
|
||||||
mouseGrabberWidget = nil
|
mouseGrabberWidget = nil
|
||||||
useRadioGroup = nil
|
useRadioGroup = nil
|
||||||
currentHotkeys = nil
|
currentHotkeys = nil
|
||||||
|
boundCombosCallback = {}
|
||||||
hotkeysList = {}
|
hotkeysList = {}
|
||||||
|
|
||||||
-- public functions
|
-- public functions
|
||||||
|
@ -149,6 +150,7 @@ function load(forceDefaults)
|
||||||
if not forceDefaults then
|
if not forceDefaults then
|
||||||
if not table.empty(hotkeys) then
|
if not table.empty(hotkeys) then
|
||||||
for keyCombo, setting in pairs(hotkeys) do
|
for keyCombo, setting in pairs(hotkeys) do
|
||||||
|
keyCombo = tostring(keyCombo)
|
||||||
addKeyCombo(keyCombo, setting)
|
addKeyCombo(keyCombo, setting)
|
||||||
hotkeyList[keyCombo] = setting
|
hotkeyList[keyCombo] = setting
|
||||||
end
|
end
|
||||||
|
@ -163,12 +165,13 @@ function load(forceDefaults)
|
||||||
end
|
end
|
||||||
|
|
||||||
function unload()
|
function unload()
|
||||||
for _,child in pairs(currentHotkeys:getChildren()) do
|
for keyCombo,callback in pairs(boundCombosCallback) do
|
||||||
g_keyboard.unbindKeyPress(child.keyCombo)
|
g_keyboard.unbindKeyPress(keyCombo, callback)
|
||||||
end
|
end
|
||||||
|
boundCombosCallback = {}
|
||||||
currentHotkeys:destroyChildren()
|
currentHotkeys:destroyChildren()
|
||||||
currentHotkeyLabel = nil
|
currentHotkeyLabel = nil
|
||||||
updateHotkeyForm()
|
updateHotkeyForm(true)
|
||||||
hotkeyList = {}
|
hotkeyList = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -196,6 +199,8 @@ function save()
|
||||||
hotkeys = hotkeys[g_game.getCharacterName()]
|
hotkeys = hotkeys[g_game.getCharacterName()]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
table.clear(hotkeys)
|
||||||
|
|
||||||
for _,child in pairs(currentHotkeys:getChildren()) do
|
for _,child in pairs(currentHotkeys:getChildren()) do
|
||||||
hotkeys[child.keyCombo] = {
|
hotkeys[child.keyCombo] = {
|
||||||
autoSend = child.autoSend,
|
autoSend = child.autoSend,
|
||||||
|
@ -207,7 +212,7 @@ function save()
|
||||||
|
|
||||||
hotkeyList = hotkeys
|
hotkeyList = hotkeys
|
||||||
g_settings.setNode('game_hotkeys', hotkeySettings)
|
g_settings.setNode('game_hotkeys', hotkeySettings)
|
||||||
--g_settings.save()
|
g_settings.save()
|
||||||
end
|
end
|
||||||
|
|
||||||
function loadDefautComboKeys()
|
function loadDefautComboKeys()
|
||||||
|
@ -258,7 +263,7 @@ function onChooseItemMouseRelease(self, mousePosition, mouseButton)
|
||||||
currentHotkeyLabel.value = nil
|
currentHotkeyLabel.value = nil
|
||||||
currentHotkeyLabel.autoSend = false
|
currentHotkeyLabel.autoSend = false
|
||||||
updateHotkeyLabel(currentHotkeyLabel)
|
updateHotkeyLabel(currentHotkeyLabel)
|
||||||
updateHotkeyForm()
|
updateHotkeyForm(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
show()
|
show()
|
||||||
|
@ -281,7 +286,7 @@ function clearObject()
|
||||||
currentHotkeyLabel.autoSend = nil
|
currentHotkeyLabel.autoSend = nil
|
||||||
currentHotkeyLabel.value = nil
|
currentHotkeyLabel.value = nil
|
||||||
updateHotkeyLabel(currentHotkeyLabel)
|
updateHotkeyLabel(currentHotkeyLabel)
|
||||||
updateHotkeyForm()
|
updateHotkeyForm(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function addHotkey()
|
function addHotkey()
|
||||||
|
@ -294,6 +299,7 @@ function addHotkey()
|
||||||
end
|
end
|
||||||
|
|
||||||
function addKeyCombo(keyCombo, keySettings, focus)
|
function addKeyCombo(keyCombo, keySettings, focus)
|
||||||
|
if keyCombo == nil or #keyCombo == 0 then return end
|
||||||
if not keyCombo then return end
|
if not keyCombo then return end
|
||||||
local hotkeyLabel = currentHotkeys:getChildById(keyCombo)
|
local hotkeyLabel = currentHotkeys:getChildById(keyCombo)
|
||||||
if not hotkeyLabel then
|
if not hotkeyLabel then
|
||||||
|
@ -321,27 +327,28 @@ function addKeyCombo(keyCombo, keySettings, focus)
|
||||||
if keySettings then
|
if keySettings then
|
||||||
currentHotkeyLabel = hotkeyLabel
|
currentHotkeyLabel = hotkeyLabel
|
||||||
hotkeyLabel.keyCombo = keyCombo
|
hotkeyLabel.keyCombo = keyCombo
|
||||||
hotkeyLabel.autoSend = keySettings.autoSend
|
hotkeyLabel.autoSend = toboolean(keySettings.autoSend)
|
||||||
hotkeyLabel.itemId = keySettings.itemId
|
hotkeyLabel.itemId = tonumber(keySettings.itemId)
|
||||||
hotkeyLabel.useType = tonumber(keySettings.useType)
|
hotkeyLabel.useType = tonumber(keySettings.useType)
|
||||||
hotkeyLabel.value = keySettings.value
|
if keySettings.value then hotkeyLabel.value = tostring(keySettings.value) end
|
||||||
else
|
else
|
||||||
hotkeyLabel.keyCombo = keyCombo
|
hotkeyLabel.keyCombo = keyCombo
|
||||||
hotkeyLabel.autoSend = nil
|
hotkeyLabel.autoSend = false
|
||||||
hotkeyLabel.itemId = nil
|
hotkeyLabel.itemId = nil
|
||||||
hotkeyLabel.useType = nil
|
hotkeyLabel.useType = nil
|
||||||
hotkeyLabel.value = nil
|
hotkeyLabel.value = ''
|
||||||
end
|
end
|
||||||
|
|
||||||
updateHotkeyLabel(hotkeyLabel)
|
updateHotkeyLabel(hotkeyLabel)
|
||||||
|
|
||||||
g_keyboard.bindKeyPress(keyCombo, function() doKeyCombo(keyCombo) end, nil, 350)
|
boundCombosCallback[keyCombo] = function() doKeyCombo(keyCombo) end
|
||||||
|
g_keyboard.bindKeyPress(keyCombo, boundCombosCallback[keyCombo])
|
||||||
end
|
end
|
||||||
|
|
||||||
if focus then
|
if focus then
|
||||||
currentHotkeys:focusChild(hotkeyLabel)
|
currentHotkeys:focusChild(hotkeyLabel)
|
||||||
currentHotkeys:ensureChildVisible(hotkeyLabel)
|
currentHotkeys:ensureChildVisible(hotkeyLabel)
|
||||||
updateHotkeyForm()
|
updateHotkeyForm(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -398,7 +405,7 @@ function updateHotkeyLabel(hotkeyLabel)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateHotkeyForm()
|
function updateHotkeyForm(reset)
|
||||||
if currentHotkeyLabel then
|
if currentHotkeyLabel then
|
||||||
removeHotkeyButton:enable()
|
removeHotkeyButton:enable()
|
||||||
if currentHotkeyLabel.itemId ~= nil then
|
if currentHotkeyLabel.itemId ~= nil then
|
||||||
|
@ -435,8 +442,10 @@ function updateHotkeyForm()
|
||||||
hotkeyText:enable()
|
hotkeyText:enable()
|
||||||
hotkeyText:focus()
|
hotkeyText:focus()
|
||||||
hotKeyTextLabel:enable()
|
hotKeyTextLabel:enable()
|
||||||
hotkeyText:setText(currentHotkeyLabel.value)
|
if reset then
|
||||||
hotkeyText:setCursorPos(-1)
|
hotkeyText:setCursorPos(-1)
|
||||||
|
end
|
||||||
|
hotkeyText:setText(currentHotkeyLabel.value)
|
||||||
sendAutomatically:setChecked(currentHotkeyLabel.autoSend)
|
sendAutomatically:setChecked(currentHotkeyLabel.autoSend)
|
||||||
sendAutomatically:setEnabled(currentHotkeyLabel.value and #currentHotkeyLabel.value > 0)
|
sendAutomatically:setEnabled(currentHotkeyLabel.value and #currentHotkeyLabel.value > 0)
|
||||||
selectObjectButton:enable()
|
selectObjectButton:enable()
|
||||||
|
@ -461,7 +470,8 @@ end
|
||||||
|
|
||||||
function removeHotkey()
|
function removeHotkey()
|
||||||
if currentHotkeyLabel == nil then return end
|
if currentHotkeyLabel == nil then return end
|
||||||
g_keyboard.unbindKeyPress(currentHotkeyLabel.keyCombo)
|
g_keyboard.unbindKeyPress(currentHotkeyLabel.keyCombo, boundCombosCallback[currentHotkeyLabel.keyCombo])
|
||||||
|
boundCombosCallback[currentHotkeyLabel.keyCombo] = nil
|
||||||
currentHotkeyLabel:destroy()
|
currentHotkeyLabel:destroy()
|
||||||
currentHotkeyLabel = nil
|
currentHotkeyLabel = nil
|
||||||
end
|
end
|
||||||
|
@ -504,7 +514,7 @@ end
|
||||||
|
|
||||||
function onSelectHotkeyLabel(hotkeyLabel)
|
function onSelectHotkeyLabel(hotkeyLabel)
|
||||||
currentHotkeyLabel = hotkeyLabel
|
currentHotkeyLabel = hotkeyLabel
|
||||||
updateHotkeyForm()
|
updateHotkeyForm(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function hotkeyCapture(assignWindow, keyCode, keyboardModifiers)
|
function hotkeyCapture(assignWindow, keyCode, keyboardModifiers)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
WALK_AUTO_REPEAT_DELAY = 90
|
|
||||||
WALK_STEPS_RETRY = 10
|
WALK_STEPS_RETRY = 10
|
||||||
|
|
||||||
gameRootPanel = nil
|
gameRootPanel = nil
|
||||||
|
@ -25,7 +24,7 @@ function init()
|
||||||
onGameStart = onGameStart,
|
onGameStart = onGameStart,
|
||||||
onGMActions = onGMActions,
|
onGMActions = onGMActions,
|
||||||
onGameEnd = onGameEnd,
|
onGameEnd = onGameEnd,
|
||||||
onLoginAdvice = onLoginAdvice
|
onLoginAdvice = onLoginAdvice,
|
||||||
}, true)
|
}, true)
|
||||||
|
|
||||||
gameRootPanel = g_ui.displayUI('gameinterface')
|
gameRootPanel = g_ui.displayUI('gameinterface')
|
||||||
|
@ -57,6 +56,7 @@ function init()
|
||||||
end
|
end
|
||||||
|
|
||||||
function bindKeys()
|
function bindKeys()
|
||||||
|
gameRootPanel:setAutoRepeatDelay(250)
|
||||||
g_keyboard.bindKeyDown('Up', function() changeWalkDir(North) end, gameRootPanel, true)
|
g_keyboard.bindKeyDown('Up', function() changeWalkDir(North) end, gameRootPanel, true)
|
||||||
g_keyboard.bindKeyDown('Right', function() changeWalkDir(East) end, gameRootPanel, true)
|
g_keyboard.bindKeyDown('Right', function() changeWalkDir(East) end, gameRootPanel, true)
|
||||||
g_keyboard.bindKeyDown('Down', function() changeWalkDir(South) end, gameRootPanel, true)
|
g_keyboard.bindKeyDown('Down', function() changeWalkDir(South) end, gameRootPanel, true)
|
||||||
|
@ -81,30 +81,30 @@ function bindKeys()
|
||||||
g_keyboard.bindKeyUp('Numpad1', function() changeWalkDir(SouthWest, true) end, gameRootPanel, true)
|
g_keyboard.bindKeyUp('Numpad1', function() changeWalkDir(SouthWest, true) end, gameRootPanel, true)
|
||||||
g_keyboard.bindKeyUp('Numpad4', function() changeWalkDir(West, true) end, gameRootPanel, true)
|
g_keyboard.bindKeyUp('Numpad4', function() changeWalkDir(West, true) end, gameRootPanel, true)
|
||||||
g_keyboard.bindKeyUp('Numpad7', function() changeWalkDir(NorthWest, true) end, gameRootPanel, true)
|
g_keyboard.bindKeyUp('Numpad7', function() changeWalkDir(NorthWest, true) end, gameRootPanel, true)
|
||||||
g_keyboard.bindKeyPress('Up', function() smartWalk(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Up', function() smartWalk(North) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Right', function() smartWalk(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Right', function() smartWalk(East) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Down', function() smartWalk(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Down', function() smartWalk(South) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Left', function() smartWalk(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Left', function() smartWalk(West) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad8', function() smartWalk(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad8', function() smartWalk(North) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad9', function() smartWalk(NorthEast) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad9', function() smartWalk(NorthEast) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad6', function() smartWalk(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad6', function() smartWalk(East) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad3', function() smartWalk(SouthEast) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad3', function() smartWalk(SouthEast) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad2', function() smartWalk(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad2', function() smartWalk(South) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad1', function() smartWalk(SouthWest) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad1', function() smartWalk(SouthWest) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad4', function() smartWalk(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad4', function() smartWalk(West) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Numpad7', function() smartWalk(NorthWest) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Numpad7', function() smartWalk(NorthWest) end, gameRootPanel)
|
||||||
|
|
||||||
g_keyboard.bindKeyPress('Ctrl+Up', function() g_game.turn(North) changeWalkDir(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Up', function() g_game.turn(North) changeWalkDir(North) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+Right', function() g_game.turn(East) changeWalkDir(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Right', function() g_game.turn(East) changeWalkDir(East) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+Down', function() g_game.turn(South) changeWalkDir(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Down', function() g_game.turn(South) changeWalkDir(South) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+Left', function() g_game.turn(West) changeWalkDir(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Left', function() g_game.turn(West) changeWalkDir(West) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+Numpad8', function() g_game.turn(North) changeWalkDir(North) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Numpad8', function() g_game.turn(North) changeWalkDir(North) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+Numpad6', function() g_game.turn(East) changeWalkDir(East) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Numpad6', function() g_game.turn(East) changeWalkDir(East) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+Numpad2', function() g_game.turn(South) changeWalkDir(South) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Numpad2', function() g_game.turn(South) changeWalkDir(South) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+Numpad4', function() g_game.turn(West) changeWalkDir(West) end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Ctrl+Numpad4', function() g_game.turn(West) changeWalkDir(West) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel, WALK_AUTO_REPEAT_DELAY)
|
g_keyboard.bindKeyPress('Escape', function() g_game.cancelAttackAndFollow() end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel, 250)
|
g_keyboard.bindKeyPress('Ctrl+=', function() gameMapPanel:zoomIn() end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel, 250)
|
g_keyboard.bindKeyPress('Ctrl+-', function() gameMapPanel:zoomOut() end, gameRootPanel)
|
||||||
g_keyboard.bindKeyDown('Ctrl+Q', logout, gameRootPanel)
|
g_keyboard.bindKeyDown('Ctrl+Q', logout, gameRootPanel)
|
||||||
g_keyboard.bindKeyDown('Ctrl+L', logout, gameRootPanel)
|
g_keyboard.bindKeyDown('Ctrl+L', logout, gameRootPanel)
|
||||||
g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() modules.game_textmessage.clearMessages() end, gameRootPanel)
|
g_keyboard.bindKeyDown('Ctrl+W', function() g_map.cleanTexts() modules.game_textmessage.clearMessages() end, gameRootPanel)
|
||||||
|
@ -591,7 +591,6 @@ function processMouseAction(menuPosition, mouseButton, autoWalkPos, lookThing, u
|
||||||
player:stopAutoWalk()
|
player:stopAutoWalk()
|
||||||
|
|
||||||
if autoWalkPos and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseLeftButton then
|
if autoWalkPos and keyboardModifiers == KeyboardNoModifier and mouseButton == MouseLeftButton then
|
||||||
player.onAutoWalkFail = function() modules.game_textmessage.displayFailureMessage(tr('There is no way.')) end
|
|
||||||
player:autoWalk(autoWalkPos)
|
player:autoWalk(autoWalkPos)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,9 @@ minimapButton = nil
|
||||||
minimapWindow = nil
|
minimapWindow = nil
|
||||||
otmm = true
|
otmm = true
|
||||||
preloaded = false
|
preloaded = false
|
||||||
|
fullmapView = false
|
||||||
|
oldZoom = nil
|
||||||
|
oldPos = nil
|
||||||
|
|
||||||
function init()
|
function init()
|
||||||
minimapButton = modules.client_topmenu.addRightGameToggleButton('minimapButton', tr('Minimap') .. ' (Ctrl+M)', '/images/topbuttons/minimap', toggle)
|
minimapButton = modules.client_topmenu.addRightGameToggleButton('minimapButton', tr('Minimap') .. ' (Ctrl+M)', '/images/topbuttons/minimap', toggle)
|
||||||
|
@ -19,6 +22,7 @@ function init()
|
||||||
g_keyboard.bindKeyPress('Alt+Up', function() minimapWidget:move(0,1) end, gameRootPanel)
|
g_keyboard.bindKeyPress('Alt+Up', function() minimapWidget:move(0,1) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyPress('Alt+Down', function() minimapWidget:move(0,-1) end, gameRootPanel)
|
g_keyboard.bindKeyPress('Alt+Down', function() minimapWidget:move(0,-1) end, gameRootPanel)
|
||||||
g_keyboard.bindKeyDown('Ctrl+M', toggle)
|
g_keyboard.bindKeyDown('Ctrl+M', toggle)
|
||||||
|
g_keyboard.bindKeyDown('Ctrl+Shift+M', toggleFullMap)
|
||||||
|
|
||||||
minimapWindow:setup()
|
minimapWindow:setup()
|
||||||
|
|
||||||
|
@ -27,6 +31,10 @@ function init()
|
||||||
onGameEnd = offline,
|
onGameEnd = offline,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
connect(LocalPlayer, {
|
||||||
|
onPositionChange = updateCameraPosition
|
||||||
|
})
|
||||||
|
|
||||||
if g_game.isOnline() then
|
if g_game.isOnline() then
|
||||||
online()
|
online()
|
||||||
end
|
end
|
||||||
|
@ -48,6 +56,7 @@ function terminate()
|
||||||
g_keyboard.unbindKeyPress('Alt+Up', gameRootPanel)
|
g_keyboard.unbindKeyPress('Alt+Up', gameRootPanel)
|
||||||
g_keyboard.unbindKeyPress('Alt+Down', gameRootPanel)
|
g_keyboard.unbindKeyPress('Alt+Down', gameRootPanel)
|
||||||
g_keyboard.unbindKeyDown('Ctrl+M')
|
g_keyboard.unbindKeyDown('Ctrl+M')
|
||||||
|
g_keyboard.unbindKeyDown('Ctrl+Shift+M')
|
||||||
|
|
||||||
minimapWindow:destroy()
|
minimapWindow:destroy()
|
||||||
minimapButton:destroy()
|
minimapButton:destroy()
|
||||||
|
@ -74,7 +83,6 @@ end
|
||||||
|
|
||||||
function online()
|
function online()
|
||||||
loadMap(not preloaded)
|
loadMap(not preloaded)
|
||||||
minimapWidget:followLocalPlayer()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function offline()
|
function offline()
|
||||||
|
@ -114,6 +122,36 @@ function saveMap()
|
||||||
minimapWidget:save()
|
minimapWidget:save()
|
||||||
end
|
end
|
||||||
|
|
||||||
function getMinimap()
|
function updateCameraPosition()
|
||||||
return minimapWidget
|
local player = g_game.getLocalPlayer()
|
||||||
|
if not minimapWidget:isDragging() then
|
||||||
|
if not fullmapView then
|
||||||
|
minimapWidget:setCameraPosition(player:getPosition())
|
||||||
|
end
|
||||||
|
minimapWidget:setCrossPosition(player:getPosition())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function toggleFullMap()
|
||||||
|
if not fullmapView then
|
||||||
|
fullmapView = true
|
||||||
|
minimapWindow:hide()
|
||||||
|
minimapWidget:setParent(modules.game_interface.getRootPanel())
|
||||||
|
minimapWidget:fill('parent')
|
||||||
|
minimapWidget:setAlternativeWidgetsVisible(true)
|
||||||
|
else
|
||||||
|
fullmapView = false
|
||||||
|
minimapWidget:setParent(minimapWindow:getChildById('contentsPanel'))
|
||||||
|
minimapWidget:fill('parent')
|
||||||
|
minimapWindow:show()
|
||||||
|
minimapWidget:setAlternativeWidgetsVisible(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
local zoom = oldZoom or 0
|
||||||
|
local pos = oldPos or minimapWidget:getCameraPosition()
|
||||||
|
pos.z = 7
|
||||||
|
oldZoom = minimapWidget:getZoom()
|
||||||
|
oldPos = minimapWidget:getCameraPosition()
|
||||||
|
minimapWidget:setZoom(zoom)
|
||||||
|
minimapWidget:setCameraPosition(pos)
|
||||||
end
|
end
|
||||||
|
|
|
@ -151,7 +151,8 @@ function onTradeTypeChange(radioTabs, selected, deselected)
|
||||||
ignoreCapacity:setVisible(currentTradeType == BUY)
|
ignoreCapacity:setVisible(currentTradeType == BUY)
|
||||||
ignoreEquipped:setVisible(currentTradeType == SELL)
|
ignoreEquipped:setVisible(currentTradeType == SELL)
|
||||||
showAllItems:setVisible(currentTradeType == SELL)
|
showAllItems:setVisible(currentTradeType == SELL)
|
||||||
sellAllButton:setVisible(currentTradeType == SELL)
|
sellAllButton:setVisible(false)
|
||||||
|
--sellAllButton:setVisible(currentTradeType == SELL)
|
||||||
|
|
||||||
refreshTradeItems()
|
refreshTradeItems()
|
||||||
refreshPlayerGoods()
|
refreshPlayerGoods()
|
||||||
|
|
|
@ -252,6 +252,7 @@ MainWindow
|
||||||
margin-right: 10
|
margin-right: 10
|
||||||
visible: false
|
visible: false
|
||||||
@onClick: modules.game_npctrade.sellAll()
|
@onClick: modules.game_npctrade.sellAll()
|
||||||
|
visible: false
|
||||||
|
|
||||||
Button
|
Button
|
||||||
id: tradeButton
|
id: tradeButton
|
||||||
|
|
|
@ -123,3 +123,7 @@ function clearMessages()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function LocalPlayer:onAutoWalkFail(player)
|
||||||
|
modules.game_textmessage.displayFailureMessage(tr('There is no way.'))
|
||||||
|
end
|
||||||
|
|
|
@ -3,7 +3,8 @@ vipButton = nil
|
||||||
addVipWindow = nil
|
addVipWindow = nil
|
||||||
|
|
||||||
function init()
|
function init()
|
||||||
connect(g_game, { onGameEnd = clear,
|
connect(g_game, { onGameStart = refresh,
|
||||||
|
onGameEnd = clear,
|
||||||
onAddVip = onAddVip,
|
onAddVip = onAddVip,
|
||||||
onVipStateChange = onVipStateChange })
|
onVipStateChange = onVipStateChange })
|
||||||
|
|
||||||
|
@ -20,7 +21,8 @@ end
|
||||||
|
|
||||||
function terminate()
|
function terminate()
|
||||||
g_keyboard.unbindKeyDown('Ctrl+P')
|
g_keyboard.unbindKeyDown('Ctrl+P')
|
||||||
disconnect(g_game, { onGameEnd = clear,
|
disconnect(g_game, { onGameStart = refresh,
|
||||||
|
onGameEnd = clear,
|
||||||
onAddVip = onAddVip,
|
onAddVip = onAddVip,
|
||||||
onVipStateChange = onVipStateChange })
|
onVipStateChange = onVipStateChange })
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,39 @@
|
||||||
function UIMinimap:onSetup()
|
function UIMinimap:onSetup()
|
||||||
self.flagWindow = nil
|
self.flagWindow = nil
|
||||||
self.flagsWidget = self:getChildById('flags')
|
|
||||||
self.floorUpWidget = self:getChildById('floorUp')
|
self.floorUpWidget = self:getChildById('floorUp')
|
||||||
self.floorDownWidget = self:getChildById('floorDown')
|
self.floorDownWidget = self:getChildById('floorDown')
|
||||||
self.zoomInWidget = self:getChildById('zoomIn')
|
self.zoomInWidget = self:getChildById('zoomIn')
|
||||||
self.zoomOutWidget = self:getChildById('zoomOut')
|
self.zoomOutWidget = self:getChildById('zoomOut')
|
||||||
self.dx = 0
|
self.flags = {}
|
||||||
self.dy = 0
|
self.alternatives = {}
|
||||||
self.autowalk = true
|
self.autowalk = true
|
||||||
self.allowFollowLocalPlayer = true
|
|
||||||
self.onPositionChange = function() self:followLocalPlayer() end
|
|
||||||
self.onAddAutomapFlag = function(pos, icon, description) self:addFlag(pos, icon, description) end
|
self.onAddAutomapFlag = function(pos, icon, description) self:addFlag(pos, icon, description) end
|
||||||
self.onRemoveAutomapFlag = function(pos, icon, description) self:removeFlag(pos, icon, description) end
|
self.onRemoveAutomapFlag = function(pos, icon, description) self:removeFlag(pos, icon, description) end
|
||||||
connect(g_game, {
|
connect(g_game, {
|
||||||
onAddAutomapFlag = self.onAddAutomapFlag,
|
onAddAutomapFlag = self.onAddAutomapFlag,
|
||||||
onRemoveAutomapFlag = self.onRemoveAutomapFlag,
|
onRemoveAutomapFlag = self.onRemoveAutomapFlag,
|
||||||
})
|
})
|
||||||
connect(LocalPlayer, { onPositionChange = self.onPositionChange })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:onDestroy()
|
function UIMinimap:onDestroy()
|
||||||
disconnect(LocalPlayer, { onPositionChange = self.onPositionChange })
|
for _,widget in pairs(self.alternatives) do
|
||||||
|
widget:destroy()
|
||||||
|
end
|
||||||
|
self.alternatives = {}
|
||||||
disconnect(g_game, {
|
disconnect(g_game, {
|
||||||
onAddAutomapFlag = self.onAddAutomapFlag,
|
onAddAutomapFlag = self.onAddAutomapFlag,
|
||||||
onRemoveAutomapFlag = self.onRemoveAutomapFlag,
|
onRemoveAutomapFlag = self.onRemoveAutomapFlag,
|
||||||
})
|
})
|
||||||
self:destroyFlagWindow()
|
self:destroyFlagWindow()
|
||||||
self:destroyFullPanel()
|
self.flags = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:onVisibilityChange()
|
function UIMinimap:onVisibilityChange()
|
||||||
if not self:isVisible() then
|
if not self:isVisible() then
|
||||||
self:destroyFlagWindow()
|
self:destroyFlagWindow()
|
||||||
self:destroyFullPanel()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:hideFlags()
|
|
||||||
self.flagsWidget:hide()
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:hideFloor()
|
function UIMinimap:hideFloor()
|
||||||
self.floorUpWidget:hide()
|
self.floorUpWidget:hide()
|
||||||
self.floorDownWidget:hide()
|
self.floorDownWidget:hide()
|
||||||
|
@ -54,33 +48,21 @@ function UIMinimap:disableAutoWalk()
|
||||||
self.autowalk = false
|
self.autowalk = false
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:disableFollowPlayer()
|
|
||||||
self.allowFollowLocalPlayer = false
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:enableFullPanel(image)
|
|
||||||
self.fullImage = image
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:load()
|
function UIMinimap:load()
|
||||||
local settings = g_settings.getNode('Minimap')
|
local settings = g_settings.getNode('Minimap')
|
||||||
if settings then
|
if settings then
|
||||||
if settings.flags then
|
if settings.flags then
|
||||||
for i=1,#settings.flags do
|
for _,flag in pairs(settings.flags) do
|
||||||
local flag = settings.flags[i]
|
|
||||||
self:addFlag(flag.position, flag.icon, flag.description)
|
self:addFlag(flag.position, flag.icon, flag.description)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:setZoom(settings.zoom)
|
self:setZoom(settings.zoom)
|
||||||
end
|
end
|
||||||
self:updateFlags()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:save()
|
function UIMinimap:save()
|
||||||
local settings = { flags={} }
|
local settings = { flags={} }
|
||||||
local children = self.flagsWidget:getChildren()
|
for _,flag in pairs(self.flags) do
|
||||||
for i=1,#children do
|
|
||||||
local flag = children[i]
|
|
||||||
table.insert(settings.flags, {
|
table.insert(settings.flags, {
|
||||||
position = flag.pos,
|
position = flag.pos,
|
||||||
icon = flag.icon,
|
icon = flag.icon,
|
||||||
|
@ -91,19 +73,7 @@ function UIMinimap:save()
|
||||||
g_settings.setNode('Minimap', settings)
|
g_settings.setNode('Minimap', settings)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:addFlag(pos, icon, description)
|
local function onFlagMouseRelease(widget, pos, button)
|
||||||
local flag = self:getFlag(pos, icon, description)
|
|
||||||
if flag then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
flag = g_ui.createWidget('MinimapFlag', self.flagsWidget)
|
|
||||||
flag.pos = pos
|
|
||||||
flag.icon = icon
|
|
||||||
flag.description = description
|
|
||||||
flag:setIcon('/images/game/minimap/flag' .. icon)
|
|
||||||
flag:setTooltip(description)
|
|
||||||
flag.onMouseRelease = function(widget, pos, button)
|
|
||||||
if button == MouseRightButton then
|
if button == MouseRightButton then
|
||||||
local menu = g_ui.createWidget('PopupMenu')
|
local menu = g_ui.createWidget('PopupMenu')
|
||||||
menu:addOption(tr('Delete mark'), function() widget:destroy() end)
|
menu:addOption(tr('Delete mark'), function() widget:destroy() end)
|
||||||
|
@ -111,114 +81,106 @@ function UIMinimap:addFlag(pos, icon, description)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
|
||||||
|
|
||||||
self:updateFlag(flag)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:getFlag(pos, icon, description)
|
function UIMinimap:setCrossPosition(pos)
|
||||||
local children = self.flagsWidget:getChildren()
|
local cross = self.cross
|
||||||
for i=1,#children do
|
if not self.cross then
|
||||||
local flag = children[i]
|
cross = g_ui.createWidget('MinimapCross', self)
|
||||||
|
cross:setIcon('/images/game/minimap/cross')
|
||||||
|
self.cross = cross
|
||||||
|
end
|
||||||
|
|
||||||
|
cross.pos = pos
|
||||||
|
if pos then
|
||||||
|
self:centerInPosition(cross, pos)
|
||||||
|
else
|
||||||
|
cross:breakAnchors()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIMinimap:addFlag(pos, icon, description)
|
||||||
|
if not pos or not icon then return end
|
||||||
|
local flag = self:getFlag(pos, icon, description)
|
||||||
|
if flag or not icon then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
flag = g_ui.createWidget('MinimapFlag', self)
|
||||||
|
flag.pos = pos
|
||||||
|
flag.description = description
|
||||||
|
flag.icon = icon
|
||||||
|
flag:setIcon('/images/game/minimap/flag' .. icon)
|
||||||
|
flag:setTooltip(description)
|
||||||
|
flag.onMouseRelease = onFlagMouseRelease
|
||||||
|
table.insert(self.flags, flag)
|
||||||
|
self:centerInPosition(flag, pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIMinimap:addAlternativeWidget(widget, pos, maxZoom)
|
||||||
|
widget.pos = pos
|
||||||
|
widget.maxZoom = maxZoom or 0
|
||||||
|
widget.minZoom = minZoom
|
||||||
|
table.insert(self.alternatives, widget)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIMinimap:setAlternativeWidgetsVisible(show)
|
||||||
|
local layout = self:getLayout()
|
||||||
|
layout:disableUpdates()
|
||||||
|
for _,widget in pairs(self.alternatives) do
|
||||||
|
if show then
|
||||||
|
self:addChild(widget)
|
||||||
|
self:centerInPosition(widget, widget.pos)
|
||||||
|
else
|
||||||
|
self:removeChild(widget)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
layout:enableUpdates()
|
||||||
|
layout:update()
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIMinimap:onZoomChange(zoom)
|
||||||
|
for _,widget in pairs(self.alternatives) do
|
||||||
|
if (not widget.minZoom or widget.minZoom >= zoom) and widget.maxZoom <= zoom then
|
||||||
|
widget:show()
|
||||||
|
else
|
||||||
|
widget:hide()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIMinimap:getFlag(pos)
|
||||||
|
for _,flag in pairs(self.flags) do
|
||||||
if flag.pos.x == pos.x and flag.pos.y == pos.y and flag.pos.z == pos.z then
|
if flag.pos.x == pos.x and flag.pos.y == pos.y and flag.pos.z == pos.z then
|
||||||
return flag
|
return flag
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:removeFlag(pos, icon, description)
|
function UIMinimap:removeFlag(pos, icon, description)
|
||||||
local flag = self:getFlag(pos, icon, description)
|
local flag = self:getFlag(pos)
|
||||||
if flag then
|
if flag then
|
||||||
flag:destroy()
|
flag:destroy()
|
||||||
end
|
table.removevalue(self.flags, flag)
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:updateFlag(flag)
|
|
||||||
local point = self:getPoint(flag.pos)
|
|
||||||
if self:containsPoint(point) and self:getZoom() >= 0 and flag.pos.z == self:getCameraPosition().z then
|
|
||||||
flag:setVisible(true)
|
|
||||||
flag:setMarginLeft(point.x - self:getX() - flag:getWidth()/2)
|
|
||||||
flag:setMarginTop(point.y - self:getY() - flag:getHeight()/2)
|
|
||||||
else
|
|
||||||
flag:setVisible(false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:updateFlags()
|
|
||||||
local children = self.flagsWidget:getChildren()
|
|
||||||
for i=1,#children do
|
|
||||||
self:updateFlag(children[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
UIMinimap.realSetCameraPosition = UIMinimap.realSetCameraPosition or UIMinimap.setCameraPosition
|
|
||||||
function UIMinimap:setCameraPosition(pos)
|
|
||||||
self:realSetCameraPosition(pos)
|
|
||||||
self:updateFlags()
|
|
||||||
end
|
|
||||||
|
|
||||||
UIMinimap.realZoomIn = UIMinimap.realZoomIn or UIMinimap.zoomIn
|
|
||||||
function UIMinimap:zoomIn()
|
|
||||||
self:realZoomIn()
|
|
||||||
self:updateFlags()
|
|
||||||
end
|
|
||||||
|
|
||||||
UIMinimap.realZoomOut = UIMinimap.realZoomOut or UIMinimap.zoomOut
|
|
||||||
function UIMinimap:zoomOut()
|
|
||||||
self:realZoomOut()
|
|
||||||
self:updateFlags()
|
|
||||||
end
|
|
||||||
|
|
||||||
UIMinimap.realSetZoom = UIMinimap.realSetZoom or UIMinimap.setZoom
|
|
||||||
function UIMinimap:setZoom(zoom)
|
|
||||||
self:realSetZoom(zoom)
|
|
||||||
self:updateFlags()
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:floorUp(floors)
|
|
||||||
local pos = self:getCameraPosition()
|
|
||||||
pos.z = pos.z - floors
|
|
||||||
if pos.z >= FloorHigher then
|
|
||||||
self:setCameraPosition(pos)
|
|
||||||
end
|
|
||||||
self:updateFlags()
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:floorDown(floors)
|
|
||||||
local pos = self:getCameraPosition()
|
|
||||||
pos.z = pos.z + floors
|
|
||||||
if pos.z <= FloorLower then
|
|
||||||
self:setCameraPosition(pos)
|
|
||||||
end
|
|
||||||
self:updateFlags()
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:followLocalPlayer()
|
|
||||||
if not self:isDragging() and self.allowFollowLocalPlayer then
|
|
||||||
local player = g_game.getLocalPlayer()
|
|
||||||
self:followCreature(player)
|
|
||||||
self:updateFlags()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:reset()
|
function UIMinimap:reset()
|
||||||
self:followLocalPlayer()
|
|
||||||
self:setZoom(0)
|
self:setZoom(0)
|
||||||
|
if self.cross then
|
||||||
|
self:setCameraPosition(self.cross.pos)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:move(x, y)
|
function UIMinimap:move(x, y)
|
||||||
local topLeft, bottomRight = self:getArea()
|
|
||||||
self.dx = self.dx + ((bottomRight.x - topLeft.x) / self:getWidth() ) * x
|
|
||||||
self.dy = self.dy + ((bottomRight.y - topLeft.y) / self:getHeight()) * y
|
|
||||||
local dx = math.floor(self.dx)
|
|
||||||
local dy = math.floor(self.dy)
|
|
||||||
self.dx = self.dx - dx
|
|
||||||
self.dy = self.dy - dy
|
|
||||||
|
|
||||||
local cameraPos = self:getCameraPosition()
|
local cameraPos = self:getCameraPosition()
|
||||||
|
local scale = self:getScale()
|
||||||
|
if scale > 1 then scale = 1 end
|
||||||
|
local dx = x/scale
|
||||||
|
local dy = y/scale
|
||||||
local pos = {x = cameraPos.x - dx, y = cameraPos.y - dy, z = cameraPos.z}
|
local pos = {x = cameraPos.x - dx, y = cameraPos.y - dy, z = cameraPos.z}
|
||||||
self:setCameraPosition(pos)
|
self:setCameraPosition(pos)
|
||||||
self:updateFlags()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:onMouseWheel(mousePos, direction)
|
function UIMinimap:onMouseWheel(mousePos, direction)
|
||||||
|
@ -232,7 +194,6 @@ function UIMinimap:onMouseWheel(mousePos, direction)
|
||||||
elseif direction == MouseWheelUp and keyboardModifiers == KeyboardCtrlModifier then
|
elseif direction == MouseWheelUp and keyboardModifiers == KeyboardCtrlModifier then
|
||||||
self:floorDown(1)
|
self:floorDown(1)
|
||||||
end
|
end
|
||||||
self:updateFlags()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:onMousePress(pos, button)
|
function UIMinimap:onMousePress(pos, button)
|
||||||
|
@ -245,20 +206,18 @@ function UIMinimap:onMouseRelease(pos, button)
|
||||||
if not self.allowNextRelease then return true end
|
if not self.allowNextRelease then return true end
|
||||||
self.allowNextRelease = false
|
self.allowNextRelease = false
|
||||||
|
|
||||||
local mapPos = self:getPosition(pos)
|
local mapPos = self:getTilePosition(pos)
|
||||||
if not mapPos then return end
|
if not mapPos then return end
|
||||||
|
|
||||||
if button == MouseLeftButton then
|
if button == MouseLeftButton then
|
||||||
local player = g_game.getLocalPlayer()
|
local player = g_game.getLocalPlayer()
|
||||||
if self.autowalk then
|
if self.autowalk then
|
||||||
player.onAutoWalkFail = function() modules.game_textmessage.displayFailureMessage(tr('There is no way.')) end
|
|
||||||
player:autoWalk(mapPos)
|
player:autoWalk(mapPos)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
elseif button == MouseRightButton then
|
elseif button == MouseRightButton then
|
||||||
local menu = g_ui.createWidget('PopupMenu')
|
local menu = g_ui.createWidget('PopupMenu')
|
||||||
menu:addOption(tr('Create mark'), function() self:createFlagWindow(mapPos) end)
|
menu:addOption(tr('Create mark'), function() self:createFlagWindow(mapPos) end)
|
||||||
if self.fullImage then menu:addOption(tr('Full map'), function() self:createFullPanel() end) end
|
|
||||||
menu:display(pos)
|
menu:display(pos)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -266,11 +225,17 @@ function UIMinimap:onMouseRelease(pos, button)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:onDragEnter(pos)
|
function UIMinimap:onDragEnter(pos)
|
||||||
|
self.dragReference = pos
|
||||||
|
self.dragCameraReference = self:getCameraPosition()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:onDragMove(pos, moved)
|
function UIMinimap:onDragMove(pos, moved)
|
||||||
self:move(moved.x, moved.y)
|
local scale = self:getScale()
|
||||||
|
local dx = (self.dragReference.x - pos.x)/scale
|
||||||
|
local dy = (self.dragReference.y - pos.y)/scale
|
||||||
|
local pos = {x = self.dragCameraReference.x + dx, y = self.dragCameraReference.y + dy, z = self.dragCameraReference.z}
|
||||||
|
self:setCameraPosition(pos)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -278,20 +243,6 @@ function UIMinimap:onDragLeave(widget, pos)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:createFullPanel()
|
|
||||||
self.fullPanel = g_ui.createWidget('MinimapFullPanel', rootWidget)
|
|
||||||
self.fullPanel.onDestroy = function() self.fullPanel = nil end
|
|
||||||
local image = self.fullPanel:getChildById('image')
|
|
||||||
image:setImage(self.fullImage)
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:destroyFullPanel()
|
|
||||||
if self.fullPanel then
|
|
||||||
self.fullPanel:destroy()
|
|
||||||
self.fullPanel = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function UIMinimap:createFlagWindow(pos)
|
function UIMinimap:createFlagWindow(pos)
|
||||||
if self.flagWindow then return end
|
if self.flagWindow then return end
|
||||||
if not pos then return end
|
if not pos then return end
|
||||||
|
@ -318,9 +269,7 @@ function UIMinimap:createFlagWindow(pos)
|
||||||
self:addFlag(pos, flagRadioGroup:getSelectedWidget().icon, description:getText())
|
self:addFlag(pos, flagRadioGroup:getSelectedWidget().icon, description:getText())
|
||||||
self:destroyFlagWindow()
|
self:destroyFlagWindow()
|
||||||
end
|
end
|
||||||
cancelButton.onClick = function()
|
cancelButton.onClick = function() self:destroyFlagWindow() end
|
||||||
self:destroyFlagWindow()
|
|
||||||
end
|
|
||||||
|
|
||||||
self.flagWindow.onDestroy = function() flagRadioGroup:destroy() end
|
self.flagWindow.onDestroy = function() flagRadioGroup:destroy() end
|
||||||
end
|
end
|
||||||
|
@ -331,9 +280,3 @@ function UIMinimap:destroyFlagWindow()
|
||||||
self.flagWindow = nil
|
self.flagWindow = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMinimap:getArea()
|
|
||||||
local topLeft = self:getPosition({ x = self:getX() + 1, y = self:getY() + 1 })
|
|
||||||
local bottomRight = self:getPosition({ x = self:getX() + self:getWidth() - 2, y = self:getY() + self:getHeight() - 2 })
|
|
||||||
return topLeft, bottomRight
|
|
||||||
end
|
|
||||||
|
|
|
@ -98,6 +98,8 @@ set(client_SOURCES ${client_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/uiminimap.h
|
${CMAKE_CURRENT_LIST_DIR}/uiminimap.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.cpp
|
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.h
|
${CMAKE_CURRENT_LIST_DIR}/uiprogressrect.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/uimapanchorlayout.h
|
||||||
|
|
||||||
# util
|
# util
|
||||||
${CMAKE_CURRENT_LIST_DIR}/position.h
|
${CMAKE_CURRENT_LIST_DIR}/position.h
|
||||||
|
|
|
@ -94,11 +94,15 @@ class UICreature;
|
||||||
class UIMap;
|
class UIMap;
|
||||||
class UIMinimap;
|
class UIMinimap;
|
||||||
class UIProgressRect;
|
class UIProgressRect;
|
||||||
|
class UIMapAnchorLayout;
|
||||||
|
class UIPositionAnchor;
|
||||||
|
|
||||||
typedef stdext::shared_object_ptr<UIItem> UIItemPtr;
|
typedef stdext::shared_object_ptr<UIItem> UIItemPtr;
|
||||||
typedef stdext::shared_object_ptr<UICreature> UICreaturePtr;
|
typedef stdext::shared_object_ptr<UICreature> UICreaturePtr;
|
||||||
typedef stdext::shared_object_ptr<UIMap> UIMapPtr;
|
typedef stdext::shared_object_ptr<UIMap> UIMapPtr;
|
||||||
typedef stdext::shared_object_ptr<UIMinimap> UIMinimapPtr;
|
typedef stdext::shared_object_ptr<UIMinimap> UIMinimapPtr;
|
||||||
typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr;
|
typedef stdext::shared_object_ptr<UIProgressRect> UIProgressRectPtr;
|
||||||
|
typedef stdext::shared_object_ptr<UIMapAnchorLayout> UIMapAnchorLayoutPtr;
|
||||||
|
typedef stdext::shared_object_ptr<UIPositionAnchor> UIPositionAnchorPtr;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "uicreature.h"
|
#include "uicreature.h"
|
||||||
#include "uimap.h"
|
#include "uimap.h"
|
||||||
#include "uiminimap.h"
|
#include "uiminimap.h"
|
||||||
|
#include "uimapanchorlayout.h"
|
||||||
#include "uiprogressrect.h"
|
#include "uiprogressrect.h"
|
||||||
#include "outfit.h"
|
#include "outfit.h"
|
||||||
|
|
||||||
|
@ -121,6 +122,8 @@ void Client::registerLuaFunctions()
|
||||||
|
|
||||||
g_lua.registerSingletonClass("g_minimap");
|
g_lua.registerSingletonClass("g_minimap");
|
||||||
g_lua.bindSingletonFunction("g_minimap", "clean", &Minimap::clean, &g_minimap);
|
g_lua.bindSingletonFunction("g_minimap", "clean", &Minimap::clean, &g_minimap);
|
||||||
|
g_lua.bindSingletonFunction("g_minimap", "loadImage", &Minimap::loadImage, &g_minimap);
|
||||||
|
g_lua.bindSingletonFunction("g_minimap", "saveImage", &Minimap::saveImage, &g_minimap);
|
||||||
g_lua.bindSingletonFunction("g_minimap", "loadOtmm", &Minimap::loadOtmm, &g_minimap);
|
g_lua.bindSingletonFunction("g_minimap", "loadOtmm", &Minimap::loadOtmm, &g_minimap);
|
||||||
g_lua.bindSingletonFunction("g_minimap", "saveOtmm", &Minimap::saveOtmm, &g_minimap);
|
g_lua.bindSingletonFunction("g_minimap", "saveOtmm", &Minimap::saveOtmm, &g_minimap);
|
||||||
|
|
||||||
|
@ -597,20 +600,24 @@ void Client::registerLuaFunctions()
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("setMixZoom", &UIMinimap::setMinZoom);
|
g_lua.bindClassMemberFunction<UIMinimap>("setMixZoom", &UIMinimap::setMinZoom);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("setMaxZoom", &UIMinimap::setMaxZoom);
|
g_lua.bindClassMemberFunction<UIMinimap>("setMaxZoom", &UIMinimap::setMaxZoom);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("setCameraPosition", &UIMinimap::setCameraPosition);
|
g_lua.bindClassMemberFunction<UIMinimap>("setCameraPosition", &UIMinimap::setCameraPosition);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("setCross", &UIMinimap::setCross);
|
g_lua.bindClassMemberFunction<UIMinimap>("floorUp", &UIMinimap::floorUp);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("followCreature", &UIMinimap::followCreature);
|
g_lua.bindClassMemberFunction<UIMinimap>("floorDown", &UIMinimap::floorDown);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getPoint", &UIMinimap::getPoint);
|
g_lua.bindClassMemberFunction<UIMinimap>("getTilePoint", &UIMinimap::getTilePoint);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getPosition", &UIMinimap::getPosition);
|
g_lua.bindClassMemberFunction<UIMinimap>("getTilePosition", &UIMinimap::getTilePosition);
|
||||||
|
g_lua.bindClassMemberFunction<UIMinimap>("getTileRect", &UIMinimap::getTileRect);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getCameraPosition", &UIMinimap::getCameraPosition);
|
g_lua.bindClassMemberFunction<UIMinimap>("getCameraPosition", &UIMinimap::getCameraPosition);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getFollowingCreature", &UIMinimap::getFollowingCreature);
|
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getMinZoom", &UIMinimap::getMinZoom);
|
g_lua.bindClassMemberFunction<UIMinimap>("getMinZoom", &UIMinimap::getMinZoom);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getMaxZoom", &UIMinimap::getMaxZoom);
|
g_lua.bindClassMemberFunction<UIMinimap>("getMaxZoom", &UIMinimap::getMaxZoom);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getZoom", &UIMinimap::getZoom);
|
g_lua.bindClassMemberFunction<UIMinimap>("getZoom", &UIMinimap::getZoom);
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getCross", &UIMinimap::getCross);
|
|
||||||
g_lua.bindClassMemberFunction<UIMinimap>("getScale", &UIMinimap::getScale);
|
g_lua.bindClassMemberFunction<UIMinimap>("getScale", &UIMinimap::getScale);
|
||||||
|
g_lua.bindClassMemberFunction<UIMinimap>("anchorPosition", &UIMinimap::anchorPosition);
|
||||||
|
g_lua.bindClassMemberFunction<UIMinimap>("fillPosition", &UIMinimap::fillPosition);
|
||||||
|
g_lua.bindClassMemberFunction<UIMinimap>("centerInPosition", &UIMinimap::centerInPosition);
|
||||||
|
|
||||||
g_lua.registerClass<UIProgressRect, UIWidget>();
|
g_lua.registerClass<UIProgressRect, UIWidget>();
|
||||||
g_lua.bindClassStaticFunction<UIProgressRect>("create", []{ return UIProgressRectPtr(new UIProgressRect); } );
|
g_lua.bindClassStaticFunction<UIProgressRect>("create", []{ return UIProgressRectPtr(new UIProgressRect); } );
|
||||||
g_lua.bindClassMemberFunction<UIProgressRect>("setPercent", &UIProgressRect::setPercent);
|
g_lua.bindClassMemberFunction<UIProgressRect>("setPercent", &UIProgressRect::setPercent);
|
||||||
g_lua.bindClassMemberFunction<UIProgressRect>("getPercent", &UIProgressRect::getPercent);
|
g_lua.bindClassMemberFunction<UIProgressRect>("getPercent", &UIProgressRect::getPercent);
|
||||||
|
|
||||||
|
g_lua.registerClass<UIMapAnchorLayout, UIAnchorLayout>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,6 +621,8 @@ std::tuple<std::vector<Otc::Direction>, Otc::PathFindResult> Map::findPath(const
|
||||||
wasSeen = mtile.hasFlag(MinimapTileWasSeen);
|
wasSeen = mtile.hasFlag(MinimapTileWasSeen);
|
||||||
isNotWalkable = mtile.hasFlag(MinimapTileNotWalkable);
|
isNotWalkable = mtile.hasFlag(MinimapTileNotWalkable);
|
||||||
isNotPathable = mtile.hasFlag(MinimapTileNotPathable);
|
isNotPathable = mtile.hasFlag(MinimapTileNotPathable);
|
||||||
|
if(isNotWalkable || isNotPathable)
|
||||||
|
wasSeen = true;
|
||||||
speed = mtile.getSpeed();
|
speed = mtile.getSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,14 @@
|
||||||
|
|
||||||
#include "minimap.h"
|
#include "minimap.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
|
||||||
#include <framework/graphics/image.h>
|
#include <framework/graphics/image.h>
|
||||||
#include <framework/graphics/texture.h>
|
#include <framework/graphics/texture.h>
|
||||||
#include <framework/graphics/painter.h>
|
#include <framework/graphics/painter.h>
|
||||||
|
#include <framework/graphics/image.h>
|
||||||
#include <framework/graphics/framebuffermanager.h>
|
#include <framework/graphics/framebuffermanager.h>
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <framework/core/filestream.h>
|
#include <framework/core/filestream.h>
|
||||||
#include <boost/concept_check.hpp>
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
Minimap g_minimap;
|
Minimap g_minimap;
|
||||||
|
@ -51,10 +52,14 @@ void MinimapBlock::update()
|
||||||
bool shouldDraw = false;
|
bool shouldDraw = false;
|
||||||
for(int x=0;x<MMBLOCK_SIZE;++x) {
|
for(int x=0;x<MMBLOCK_SIZE;++x) {
|
||||||
for(int y=0;y<MMBLOCK_SIZE;++y) {
|
for(int y=0;y<MMBLOCK_SIZE;++y) {
|
||||||
uint32 col = Color::from8bit(getTile(x, y).color).rgba();
|
uint8 c = getTile(x, y).color;
|
||||||
image->setPixel(x, y, col);
|
uint32 col;
|
||||||
if(col != 0)
|
if(c != 255) {
|
||||||
|
col = Color::from8bit(c).rgba();
|
||||||
shouldDraw = true;
|
shouldDraw = true;
|
||||||
|
} else
|
||||||
|
col = Color::alpha.rgba();
|
||||||
|
image->setPixel(x, y, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,14 +98,14 @@ void Minimap::clean()
|
||||||
m_tileBlocks[i].clear();
|
m_tileBlocks[i].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scale)
|
void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scale, const Color& color)
|
||||||
{
|
{
|
||||||
if(screenRect.isEmpty())
|
if(screenRect.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
||||||
g_painter->saveState();
|
g_painter->saveState();
|
||||||
g_painter->setColor(Color::black);
|
g_painter->setColor(color);
|
||||||
g_painter->drawFilledRect(screenRect);
|
g_painter->drawFilledRect(screenRect);
|
||||||
g_painter->resetColor();
|
g_painter->resetColor();
|
||||||
g_painter->setClipRect(screenRect);
|
g_painter->setClipRect(screenRect);
|
||||||
|
@ -137,15 +142,16 @@ void Minimap::draw(const Rect& screenRect, const Position& mapCenter, float scal
|
||||||
tex->setSmooth(scale < 1.0f);
|
tex->setSmooth(scale < 1.0f);
|
||||||
g_painter->drawTexturedRect(dest, tex, src);
|
g_painter->drawTexturedRect(dest, tex, src);
|
||||||
}
|
}
|
||||||
|
//g_painter->drawBoundingRect(Rect(xs,ys, MMBLOCK_SIZE * scale, MMBLOCK_SIZE * scale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_painter->restoreSavedState();
|
g_painter->restoreSavedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Point Minimap::getPoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
|
Point Minimap::getTilePoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
|
||||||
{
|
{
|
||||||
if(screenRect.isEmpty() || MMBLOCK_SIZE*scale <= 1 || !mapCenter.isMapPosition())
|
if(screenRect.isEmpty() || pos.z != mapCenter.z)
|
||||||
return Point(-1,-1);
|
return Point(-1,-1);
|
||||||
|
|
||||||
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
||||||
|
@ -154,9 +160,9 @@ Point Minimap::getPoint(const Position& pos, const Rect& screenRect, const Posit
|
||||||
return posoff + screenRect.topLeft() - off + (Point(1,1)*scale)/2;
|
return posoff + screenRect.topLeft() - off + (Point(1,1)*scale)/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position Minimap::getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale)
|
Position Minimap::getTilePosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale)
|
||||||
{
|
{
|
||||||
if(screenRect.isEmpty() || MMBLOCK_SIZE*scale <= 1 || !mapCenter.isMapPosition())
|
if(screenRect.isEmpty())
|
||||||
return Position();
|
return Position();
|
||||||
|
|
||||||
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
Rect mapRect = calcMapRect(screenRect, mapCenter, scale);
|
||||||
|
@ -165,24 +171,25 @@ Position Minimap::getPosition(const Point& point, const Rect& screenRect, const
|
||||||
return Position(pos2d.x, pos2d.y, mapCenter.z);
|
return Position(pos2d.x, pos2d.y, mapCenter.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect Minimap::getTileRect(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale)
|
||||||
|
{
|
||||||
|
if(screenRect.isEmpty() || pos.z != mapCenter.z)
|
||||||
|
return Rect();
|
||||||
|
|
||||||
|
int tileSize = 32 * scale;
|
||||||
|
Rect tileRect(0,0,tileSize, tileSize);
|
||||||
|
tileRect.moveCenter(getTilePoint(pos, screenRect, mapCenter, scale));
|
||||||
|
return tileRect;
|
||||||
|
}
|
||||||
|
|
||||||
Rect Minimap::calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale)
|
Rect Minimap::calcMapRect(const Rect& screenRect, const Position& mapCenter, float scale)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w = screenRect.width() / scale, h = std::ceil(screenRect.height() / scale);
|
||||||
do {
|
|
||||||
w = std::ceil(screenRect.width() / scale);
|
|
||||||
h = std::ceil(screenRect.height() / scale);
|
|
||||||
if(w % 2 == 0)
|
|
||||||
w++;
|
|
||||||
if(h % 2 == 0)
|
|
||||||
h++;
|
|
||||||
scale *= 2;
|
|
||||||
} while(w > 8192 || h > 8192);
|
|
||||||
Rect mapRect(0,0,w,h);
|
Rect mapRect(0,0,w,h);
|
||||||
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
|
mapRect.moveCenter(Point(mapCenter.x, mapCenter.y));
|
||||||
return mapRect;
|
return mapRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Minimap::updateTile(const Position& pos, const TilePtr& tile)
|
void Minimap::updateTile(const Position& pos, const TilePtr& tile)
|
||||||
{
|
{
|
||||||
MinimapTile minimapTile;
|
MinimapTile minimapTile;
|
||||||
|
@ -200,6 +207,7 @@ void Minimap::updateTile(const Position& pos, const TilePtr& tile)
|
||||||
MinimapBlock& block = getBlock(pos);
|
MinimapBlock& block = getBlock(pos);
|
||||||
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
|
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
|
||||||
block.updateTile(pos.x - offsetPos.x, pos.y - offsetPos.y, minimapTile);
|
block.updateTile(pos.x - offsetPos.x, pos.y - offsetPos.y, minimapTile);
|
||||||
|
block.justSaw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +222,87 @@ const MinimapTile& Minimap::getTile(const Position& pos)
|
||||||
return nulltile;
|
return nulltile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Minimap::loadImage(const std::string& fileName, const Position& topLeft, float colorFactor)
|
||||||
|
{
|
||||||
|
if(colorFactor <= 0.01f)
|
||||||
|
colorFactor = 1.0f;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ImagePtr image = Image::load(fileName);
|
||||||
|
|
||||||
|
uint8 waterc = Color::to8bit(std::string("#3300cc"));
|
||||||
|
|
||||||
|
// non pathable colors
|
||||||
|
Color nonPathableColors[] = {
|
||||||
|
std::string("#ffff00"), // yellow
|
||||||
|
};
|
||||||
|
|
||||||
|
// non walkable colors
|
||||||
|
Color nonWalkableColors[] = {
|
||||||
|
std::string("#000000"), // oil, black
|
||||||
|
std::string("#006600"), // trees, dark green
|
||||||
|
std::string("#ff3300"), // walls, red
|
||||||
|
std::string("#666666"), // mountain, grey
|
||||||
|
std::string("#ff6600"), // lava, orange
|
||||||
|
std::string("#00ff00"), // positon
|
||||||
|
std::string("#ccffff"), // ice, very light blue
|
||||||
|
};
|
||||||
|
|
||||||
|
for(int y=0;y<image->getHeight();++y) {
|
||||||
|
for(int x=0;x<image->getWidth();++x) {
|
||||||
|
Color color = *(uint32*)image->getPixel(x,y);
|
||||||
|
uint8 c = Color::to8bit(color * colorFactor);
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if(c == waterc || color.a() == 0) {
|
||||||
|
flags |= MinimapTileNotWalkable;
|
||||||
|
c = 255; // alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags != 0) {
|
||||||
|
for(Color &col : nonWalkableColors) {
|
||||||
|
if(col == color) {
|
||||||
|
flags |= MinimapTileNotWalkable;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags != 0) {
|
||||||
|
for(Color &col : nonPathableColors) {
|
||||||
|
if(col == color) {
|
||||||
|
flags |= MinimapTileNotPathable;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c == 255)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Position pos(topLeft.x + x, topLeft.y + y, topLeft.z);
|
||||||
|
MinimapBlock& block = getBlock(pos);
|
||||||
|
Point offsetPos = getBlockOffset(Point(pos.x, pos.y));
|
||||||
|
MinimapTile& tile = block.getTile(pos.x - offsetPos.x, pos.y - offsetPos.y);
|
||||||
|
if(!(tile.flags & MinimapTileWasSeen)) {
|
||||||
|
tile.color = c;
|
||||||
|
tile.flags = flags;
|
||||||
|
block.mustUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch(stdext::exception& e) {
|
||||||
|
g_logger.error(stdext::format("failed to load OTMM minimap: %s", e.what()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Minimap::saveImage(const std::string& fileName, const Rect& mapRect)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
bool Minimap::loadOtmm(const std::string& fileName)
|
bool Minimap::loadOtmm(const std::string& fileName)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -263,6 +352,7 @@ bool Minimap::loadOtmm(const std::string& fileName)
|
||||||
assert(ret == Z_OK);
|
assert(ret == Z_OK);
|
||||||
assert(destLen == blockSize);
|
assert(destLen == blockSize);
|
||||||
block.mustUpdate();
|
block.mustUpdate();
|
||||||
|
block.justSaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
fin->close();
|
fin->close();
|
||||||
|
@ -307,6 +397,9 @@ void Minimap::saveOtmm(const std::string& fileName)
|
||||||
for(auto& it : m_tileBlocks[z]) {
|
for(auto& it : m_tileBlocks[z]) {
|
||||||
int index = it.first;
|
int index = it.first;
|
||||||
MinimapBlock& block = it.second;
|
MinimapBlock& block = it.second;
|
||||||
|
if(!block.wasSeen())
|
||||||
|
continue;
|
||||||
|
|
||||||
Position pos = getIndexPosition(index, z);
|
Position pos = getIndexPosition(index, z);
|
||||||
fin->addU16(pos.x);
|
fin->addU16(pos.x);
|
||||||
fin->addU16(pos.y);
|
fin->addU16(pos.y);
|
||||||
|
|
|
@ -42,7 +42,7 @@ enum MinimapTileFlags {
|
||||||
#pragma pack(push,1) // disable memory alignment
|
#pragma pack(push,1) // disable memory alignment
|
||||||
struct MinimapTile
|
struct MinimapTile
|
||||||
{
|
{
|
||||||
MinimapTile() : flags(0), color(0), speed(10) { }
|
MinimapTile() : flags(0), color(255), speed(10) { }
|
||||||
uint8 flags;
|
uint8 flags;
|
||||||
uint8 color;
|
uint8 color;
|
||||||
uint8 speed;
|
uint8 speed;
|
||||||
|
@ -64,10 +64,13 @@ public:
|
||||||
const TexturePtr& getTexture() { return m_texture; }
|
const TexturePtr& getTexture() { return m_texture; }
|
||||||
std::array<MinimapTile, MMBLOCK_SIZE *MMBLOCK_SIZE>& getTiles() { return m_tiles; }
|
std::array<MinimapTile, MMBLOCK_SIZE *MMBLOCK_SIZE>& getTiles() { return m_tiles; }
|
||||||
void mustUpdate() { m_mustUpdate = true; }
|
void mustUpdate() { m_mustUpdate = true; }
|
||||||
|
void justSaw() { m_wasSeen = true; }
|
||||||
|
bool wasSeen() { return m_wasSeen; }
|
||||||
private:
|
private:
|
||||||
TexturePtr m_texture;
|
TexturePtr m_texture;
|
||||||
std::array<MinimapTile, MMBLOCK_SIZE *MMBLOCK_SIZE> m_tiles;
|
std::array<MinimapTile, MMBLOCK_SIZE *MMBLOCK_SIZE> m_tiles;
|
||||||
stdext::boolean<true> m_mustUpdate;
|
stdext::boolean<true> m_mustUpdate;
|
||||||
|
stdext::boolean<false> m_wasSeen;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -81,13 +84,16 @@ public:
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
|
|
||||||
void draw(const Rect& screenRect, const Position& mapCenter, float scale);
|
void draw(const Rect& screenRect, const Position& mapCenter, float scale, const Color& color);
|
||||||
Point getPoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale);
|
Point getTilePoint(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale);
|
||||||
Position getPosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale);
|
Position getTilePosition(const Point& point, const Rect& screenRect, const Position& mapCenter, float scale);
|
||||||
|
Rect getTileRect(const Position& pos, const Rect& screenRect, const Position& mapCenter, float scale);
|
||||||
|
|
||||||
void updateTile(const Position& pos, const TilePtr& tile);
|
void updateTile(const Position& pos, const TilePtr& tile);
|
||||||
const MinimapTile& getTile(const Position& pos);
|
const MinimapTile& getTile(const Position& pos);
|
||||||
|
|
||||||
|
bool loadImage(const std::string& fileName, const Position& topLeft, float colorFactor);
|
||||||
|
void saveImage(const std::string& fileName, const Rect& mapRect);
|
||||||
bool loadOtmm(const std::string& fileName);
|
bool loadOtmm(const std::string& fileName);
|
||||||
void saveOtmm(const std::string& fileName);
|
void saveOtmm(const std::string& fileName);
|
||||||
|
|
||||||
|
|
|
@ -763,6 +763,9 @@ void ProtocolGame::parseMagicEffect(const InputMessagePtr& msg)
|
||||||
else
|
else
|
||||||
effectId = msg->getU8();
|
effectId = msg->getU8();
|
||||||
|
|
||||||
|
if(!g_things.isValidDatId(effectId, ThingCategoryEffect))
|
||||||
|
g_logger.traceError("invalid effect id");
|
||||||
|
|
||||||
EffectPtr effect = EffectPtr(new Effect());
|
EffectPtr effect = EffectPtr(new Effect());
|
||||||
effect->setId(effectId);
|
effect->setId(effectId);
|
||||||
g_map.addThing(effect, pos);
|
g_map.addThing(effect, pos);
|
||||||
|
@ -786,6 +789,9 @@ void ProtocolGame::parseDistanceMissile(const InputMessagePtr& msg)
|
||||||
Position toPos = getPosition(msg);
|
Position toPos = getPosition(msg);
|
||||||
int shotId = msg->getU8();
|
int shotId = msg->getU8();
|
||||||
|
|
||||||
|
if(!g_things.isValidDatId(shotId, ThingCategoryMissile))
|
||||||
|
g_logger.traceError("invalid effect id");
|
||||||
|
|
||||||
MissilePtr missile = MissilePtr(new Missile());
|
MissilePtr missile = MissilePtr(new Missile());
|
||||||
missile->setId(shotId);
|
missile->setId(shotId);
|
||||||
missile->setPath(fromPos, toPos);
|
missile->setPath(fromPos, toPos);
|
||||||
|
@ -1642,6 +1648,9 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
|
||||||
int feet = msg->getU8();
|
int feet = msg->getU8();
|
||||||
int addons = msg->getU8();
|
int addons = msg->getU8();
|
||||||
|
|
||||||
|
if(!g_things.isValidDatId(lookType, ThingCategoryCreature))
|
||||||
|
lookType = 0;
|
||||||
|
|
||||||
outfit.setId(lookType);
|
outfit.setId(lookType);
|
||||||
outfit.setHead(head);
|
outfit.setHead(head);
|
||||||
outfit.setBody(body);
|
outfit.setBody(body);
|
||||||
|
@ -1653,9 +1662,11 @@ Outfit ProtocolGame::getOutfit(const InputMessagePtr& msg)
|
||||||
int lookTypeEx = msg->getU16();
|
int lookTypeEx = msg->getU16();
|
||||||
if(lookTypeEx == 0) {
|
if(lookTypeEx == 0) {
|
||||||
outfit.setCategory(ThingCategoryEffect);
|
outfit.setCategory(ThingCategoryEffect);
|
||||||
outfit.setAuxId(13);
|
outfit.setAuxId(13); // invisible effect id
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if(!g_things.isValidDatId(lookTypeEx, ThingCategoryItem))
|
||||||
|
lookTypeEx = 0;
|
||||||
outfit.setCategory(ThingCategoryItem);
|
outfit.setCategory(ThingCategoryItem);
|
||||||
outfit.setAuxId(lookTypeEx);
|
outfit.setAuxId(lookTypeEx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,9 +164,17 @@ void ThingType::draw(const Point& dest, float scaleFactor, int layer, int xPatte
|
||||||
if(m_null)
|
if(m_null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects.
|
if(animationPhase >= m_animationPhases)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const TexturePtr& texture = getTexture(animationPhase); // texture might not exists, neither its rects.
|
||||||
|
if(!texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
|
||||||
|
if(frameIndex >= m_texturesFramesRects[animationPhase].size())
|
||||||
|
return;
|
||||||
|
|
||||||
int frameIndex = getTextureIndex(layer, xPattern, yPattern, zPattern);
|
|
||||||
Point textureOffset;
|
Point textureOffset;
|
||||||
Rect textureRect;
|
Rect textureRect;
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,7 @@ int Tile::getGroundSpeed()
|
||||||
|
|
||||||
uint8 Tile::getMinimapColorByte()
|
uint8 Tile::getMinimapColorByte()
|
||||||
{
|
{
|
||||||
uint8 color = 0;
|
uint8 color = 255; // alpha
|
||||||
if(m_minimapColor != 0) {
|
if(m_minimapColor != 0) {
|
||||||
return m_minimapColor;
|
return m_minimapColor;
|
||||||
}
|
}
|
||||||
|
@ -542,18 +542,8 @@ bool Tile::isLookPossible()
|
||||||
|
|
||||||
bool Tile::isClickable()
|
bool Tile::isClickable()
|
||||||
{
|
{
|
||||||
bool hasGround = false;
|
|
||||||
bool hasOnBottom = false;
|
|
||||||
bool hasIgnoreLook = false;
|
|
||||||
for(const ThingPtr& thing : m_things) {
|
for(const ThingPtr& thing : m_things) {
|
||||||
if(thing->isGround())
|
if(!thing->isOnTop() && !thing->isIgnoreLook())
|
||||||
hasGround = true;
|
|
||||||
if(thing->isOnBottom())
|
|
||||||
hasOnBottom = true;
|
|
||||||
if(thing->isIgnoreLook())
|
|
||||||
hasIgnoreLook = true;
|
|
||||||
|
|
||||||
if((hasGround || hasOnBottom) && !hasIgnoreLook)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "declarations.h"
|
||||||
|
#include "uimapanchorlayout.h"
|
||||||
|
#include "uiminimap.h"
|
||||||
|
#include <framework/ui/uiwidget.h>
|
||||||
|
|
||||||
|
int UIPositionAnchor::getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget)
|
||||||
|
{
|
||||||
|
UIMinimapPtr minimap = hookedWidget->static_self_cast<UIMinimap>();
|
||||||
|
Rect hookedRect = minimap->getTileRect(m_hookedPosition);
|
||||||
|
int point = 0;
|
||||||
|
if(hookedRect.isValid()) {
|
||||||
|
switch(m_hookedEdge) {
|
||||||
|
case Fw::AnchorLeft:
|
||||||
|
point = hookedRect.left();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorRight:
|
||||||
|
point = hookedRect.right();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorTop:
|
||||||
|
point = hookedRect.top();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorBottom:
|
||||||
|
point = hookedRect.bottom();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorHorizontalCenter:
|
||||||
|
point = hookedRect.horizontalCenter();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorVerticalCenter:
|
||||||
|
point = hookedRect.verticalCenter();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// must never happens
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMapAnchorLayout::addPositionAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge)
|
||||||
|
{
|
||||||
|
if(!anchoredWidget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(anchoredWidget != getParentWidget());
|
||||||
|
|
||||||
|
UIPositionAnchorPtr anchor(new UIPositionAnchor(anchoredEdge, hookedPosition, hookedEdge));
|
||||||
|
UIAnchorGroupPtr& anchorGroup = m_anchorsGroups[anchoredWidget];
|
||||||
|
if(!anchorGroup)
|
||||||
|
anchorGroup = UIAnchorGroupPtr(new UIAnchorGroup);
|
||||||
|
|
||||||
|
anchorGroup->addAnchor(anchor);
|
||||||
|
|
||||||
|
// layout must be updated because a new anchor got in
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMapAnchorLayout::centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||||
|
{
|
||||||
|
addPositionAnchor(anchoredWidget, Fw::AnchorHorizontalCenter, hookedPosition, Fw::AnchorHorizontalCenter);
|
||||||
|
addPositionAnchor(anchoredWidget, Fw::AnchorVerticalCenter, hookedPosition, Fw::AnchorVerticalCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMapAnchorLayout::fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||||
|
{
|
||||||
|
addPositionAnchor(anchoredWidget, Fw::AnchorLeft, hookedPosition, Fw::AnchorLeft);
|
||||||
|
addPositionAnchor(anchoredWidget, Fw::AnchorRight, hookedPosition, Fw::AnchorRight);
|
||||||
|
addPositionAnchor(anchoredWidget, Fw::AnchorTop, hookedPosition, Fw::AnchorTop);
|
||||||
|
addPositionAnchor(anchoredWidget, Fw::AnchorBottom, hookedPosition, Fw::AnchorBottom);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2013 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UIMAPANCHORLAYOUT_H
|
||||||
|
#define UIMAPANCHORLAYOUT_H
|
||||||
|
|
||||||
|
#include "declarations.h"
|
||||||
|
#include <framework/ui/uianchorlayout.h>
|
||||||
|
|
||||||
|
class UIPositionAnchor : public UIAnchor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UIPositionAnchor(Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge) :
|
||||||
|
UIAnchor(anchoredEdge, std::string(), hookedEdge), m_hookedPosition(hookedPosition) { }
|
||||||
|
|
||||||
|
UIWidgetPtr getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget) { return parentWidget; }
|
||||||
|
int getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Position m_hookedPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UIMapAnchorLayout : public UIAnchorLayout
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UIMapAnchorLayout(UIWidgetPtr parentWidget) : UIAnchorLayout(parentWidget) { }
|
||||||
|
|
||||||
|
void addPositionAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge,
|
||||||
|
const Position& hookedPosition, Fw::AnchorEdge hookedEdge);
|
||||||
|
void centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||||
|
void fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -23,16 +23,19 @@
|
||||||
#include "uiminimap.h"
|
#include "uiminimap.h"
|
||||||
#include "minimap.h"
|
#include "minimap.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
#include "uimapanchorlayout.h"
|
||||||
|
#include "luavaluecasts.h"
|
||||||
|
|
||||||
#include <framework/graphics/painter.h>
|
#include <framework/graphics/painter.h>
|
||||||
|
#include "uimapanchorlayout.h"
|
||||||
|
|
||||||
UIMinimap::UIMinimap()
|
UIMinimap::UIMinimap()
|
||||||
{
|
{
|
||||||
m_crossEnabled = true;
|
|
||||||
m_zoom = 0;
|
m_zoom = 0;
|
||||||
m_scale = 1.0f;
|
m_scale = 1.0f;
|
||||||
m_minZoom = -5;
|
m_minZoom = -5;
|
||||||
m_maxZoom = 5;
|
m_maxZoom = 5;
|
||||||
|
m_layout = UIMapAnchorLayoutPtr(new UIMapAnchorLayout(static_self_cast<UIWidget>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIMinimap::drawSelf(Fw::DrawPane drawPane)
|
void UIMinimap::drawSelf(Fw::DrawPane drawPane)
|
||||||
|
@ -42,22 +45,18 @@ void UIMinimap::drawSelf(Fw::DrawPane drawPane)
|
||||||
if((drawPane & Fw::ForegroundPane) == 0)
|
if((drawPane & Fw::ForegroundPane) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_minimap.draw(getPaddingRect(), getCameraPosition(), m_scale);
|
g_minimap.draw(getPaddingRect(), getCameraPosition(), m_scale, m_color);
|
||||||
|
|
||||||
// draw a cross in the center
|
|
||||||
Rect vRect(0, 0, 2, 10);
|
|
||||||
Rect hRect(0, 0, 10, 2);
|
|
||||||
vRect.moveCenter(m_rect.center());
|
|
||||||
hRect.moveCenter(m_rect.center());
|
|
||||||
g_painter->setColor(Color::white);
|
|
||||||
g_painter->drawFilledRect(vRect);
|
|
||||||
g_painter->drawFilledRect(hRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UIMinimap::setZoom(int zoom)
|
bool UIMinimap::setZoom(int zoom)
|
||||||
{
|
{
|
||||||
|
if(zoom == m_zoom)
|
||||||
|
return true;
|
||||||
|
|
||||||
if(zoom < m_minZoom || zoom > m_maxZoom)
|
if(zoom < m_minZoom || zoom > m_maxZoom)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
int oldZoom = m_zoom;
|
||||||
m_zoom = zoom;
|
m_zoom = zoom;
|
||||||
if(m_zoom < 0)
|
if(m_zoom < 0)
|
||||||
m_scale = 1.0f / (1 << std::abs(zoom));
|
m_scale = 1.0f / (1 << std::abs(zoom));
|
||||||
|
@ -65,37 +64,83 @@ bool UIMinimap::setZoom(int zoom)
|
||||||
m_scale = 1.0f * (1 << std::abs(zoom));
|
m_scale = 1.0f * (1 << std::abs(zoom));
|
||||||
else
|
else
|
||||||
m_scale = 1;
|
m_scale = 1;
|
||||||
return true;
|
m_layout->update();
|
||||||
}
|
|
||||||
|
|
||||||
void UIMinimap::followCreature(const CreaturePtr& creature)
|
onZoomChange(zoom, oldZoom);
|
||||||
{
|
return true;
|
||||||
m_followingCreature = creature;
|
|
||||||
m_cameraPosition = Position();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIMinimap::setCameraPosition(const Position& pos)
|
void UIMinimap::setCameraPosition(const Position& pos)
|
||||||
{
|
{
|
||||||
m_followingCreature = nullptr;
|
Position oldPos = m_cameraPosition;
|
||||||
m_cameraPosition = pos;
|
m_cameraPosition = pos;
|
||||||
|
m_layout->update();
|
||||||
|
|
||||||
|
onCameraPositionChange(pos, oldPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
Point UIMinimap::getPoint(const Position& pos)
|
bool UIMinimap::floorUp()
|
||||||
{
|
{
|
||||||
return g_minimap.getPoint(pos, getPaddingRect(), getCameraPosition(), m_scale);
|
Position pos = getCameraPosition();
|
||||||
|
if(!pos.up())
|
||||||
|
return false;
|
||||||
|
setCameraPosition(pos);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position UIMinimap::getPosition(const Point& mousePos)
|
bool UIMinimap::floorDown()
|
||||||
{
|
{
|
||||||
return g_minimap.getPosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale);
|
Position pos = getCameraPosition();
|
||||||
|
if(!pos.down())
|
||||||
|
return false;
|
||||||
|
setCameraPosition(pos);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position UIMinimap::getCameraPosition()
|
Point UIMinimap::getTilePoint(const Position& pos)
|
||||||
{
|
{
|
||||||
if(m_followingCreature)
|
return g_minimap.getTilePoint(pos, getPaddingRect(), getCameraPosition(), m_scale);
|
||||||
return m_followingCreature->getPosition();
|
}
|
||||||
else
|
|
||||||
return m_cameraPosition;
|
Rect UIMinimap::getTileRect(const Position& pos)
|
||||||
|
{
|
||||||
|
return g_minimap.getTileRect(pos, getPaddingRect(), getCameraPosition(), m_scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
Position UIMinimap::getTilePosition(const Point& mousePos)
|
||||||
|
{
|
||||||
|
return g_minimap.getTilePosition(mousePos, getPaddingRect(), getCameraPosition(), m_scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMinimap::anchorPosition(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge)
|
||||||
|
{
|
||||||
|
UIMapAnchorLayoutPtr layout = m_layout->static_self_cast<UIMapAnchorLayout>();
|
||||||
|
assert(layout);
|
||||||
|
layout->addPositionAnchor(anchoredWidget, anchoredEdge, hookedPosition, hookedEdge);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMinimap::fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||||
|
{
|
||||||
|
UIMapAnchorLayoutPtr layout = m_layout->static_self_cast<UIMapAnchorLayout>();
|
||||||
|
assert(layout);
|
||||||
|
layout->fillPosition(anchoredWidget, hookedPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMinimap::centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition)
|
||||||
|
{
|
||||||
|
UIMapAnchorLayoutPtr layout = m_layout->static_self_cast<UIMapAnchorLayout>();
|
||||||
|
assert(layout);
|
||||||
|
layout->centerInPosition(anchoredWidget, hookedPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMinimap::onZoomChange(int zoom, int oldZoom)
|
||||||
|
{
|
||||||
|
callLuaField("onZoomChange", zoom, oldZoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIMinimap::onCameraPositionChange(const Position& position, const Position& oldPosition)
|
||||||
|
{
|
||||||
|
callLuaField("onCameraPositionChange", position, oldPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIMinimap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
void UIMinimap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||||
|
@ -108,7 +153,5 @@ void UIMinimap::onStyleApply(const std::string& styleName, const OTMLNodePtr& st
|
||||||
setMaxZoom(node->value<int>());
|
setMaxZoom(node->value<int>());
|
||||||
else if(node->tag() == "min-zoom")
|
else if(node->tag() == "min-zoom")
|
||||||
setMinZoom(node->value<int>());
|
setMinZoom(node->value<int>());
|
||||||
else if(node->tag() == "cross")
|
|
||||||
setCross(node->value<bool>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,26 +40,32 @@ public:
|
||||||
void setMinZoom(int minZoom) { m_minZoom = minZoom; }
|
void setMinZoom(int minZoom) { m_minZoom = minZoom; }
|
||||||
void setMaxZoom(int maxZoom) { m_maxZoom = maxZoom; }
|
void setMaxZoom(int maxZoom) { m_maxZoom = maxZoom; }
|
||||||
void setCameraPosition(const Position& pos);
|
void setCameraPosition(const Position& pos);
|
||||||
void setCross(bool enable) { m_crossEnabled = enable; }
|
bool floorUp();
|
||||||
void followCreature(const CreaturePtr& creature);
|
bool floorDown();
|
||||||
|
|
||||||
Point getPoint(const Position& pos);
|
Point getTilePoint(const Position& pos);
|
||||||
Position getPosition(const Point& mousePos);
|
Rect getTileRect(const Position& pos);
|
||||||
Position getCameraPosition();
|
Position getTilePosition(const Point& mousePos);
|
||||||
CreaturePtr getFollowingCreature() { return m_followingCreature; }
|
|
||||||
|
Position getCameraPosition() { return m_cameraPosition; }
|
||||||
int getMinZoom() { return m_minZoom; }
|
int getMinZoom() { return m_minZoom; }
|
||||||
int getMaxZoom() { return m_maxZoom; }
|
int getMaxZoom() { return m_maxZoom; }
|
||||||
int getZoom() { return m_zoom; }
|
int getZoom() { return m_zoom; }
|
||||||
bool getCross() { return m_crossEnabled; }
|
|
||||||
float getScale() { return m_scale; }
|
float getScale() { return m_scale; }
|
||||||
|
|
||||||
|
void anchorPosition(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge anchoredEdge, const Position& hookedPosition, Fw::AnchorEdge hookedEdge);
|
||||||
|
void fillPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||||
|
void centerInPosition(const UIWidgetPtr& anchoredWidget, const Position& hookedPosition);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void onZoomChange(int zoom, int oldZoom);
|
||||||
|
virtual void onCameraPositionChange(const Position& position, const Position& oldPosition);
|
||||||
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
virtual void onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void update();
|
||||||
|
|
||||||
Rect m_mapArea;
|
Rect m_mapArea;
|
||||||
bool m_crossEnabled;
|
|
||||||
CreaturePtr m_followingCreature;
|
|
||||||
Position m_cameraPosition;
|
Position m_cameraPosition;
|
||||||
float m_scale;
|
float m_scale;
|
||||||
int m_zoom;
|
int m_zoom;
|
||||||
|
|
|
@ -289,8 +289,12 @@ bool luavalue_cast(int index, OTMLNodePtr& node)
|
||||||
g_lua.pushNil();
|
g_lua.pushNil();
|
||||||
while(g_lua.next(index < 0 ? index-1 : index)) {
|
while(g_lua.next(index < 0 ? index-1 : index)) {
|
||||||
std::string cnodeName;
|
std::string cnodeName;
|
||||||
if(!g_lua.isNumber(-2))
|
if(g_lua.isString(-2)) {
|
||||||
cnodeName = g_lua.toString(-2);
|
g_lua.pushValue(-2);
|
||||||
|
cnodeName = g_lua.toString();
|
||||||
|
g_lua.pop();
|
||||||
|
} else
|
||||||
|
assert(g_lua.isNumber());
|
||||||
if(g_lua.isTable()) {
|
if(g_lua.isTable()) {
|
||||||
OTMLNodePtr cnode;
|
OTMLNodePtr cnode;
|
||||||
if(luavalue_cast(-1, cnode)) {
|
if(luavalue_cast(-1, cnode)) {
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
// common C headers
|
// common C headers
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -42,5 +43,8 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <tuple>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -618,9 +618,12 @@ LRESULT WIN32Window::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
case WM_SYSKEYDOWN: {
|
case WM_SYSKEYDOWN: {
|
||||||
// F10 is the shortcut key to enter a windows menu, this is a workaround to get F10 working
|
// F10 is the shortcut key to enter a windows menu, this is a workaround to get F10 working
|
||||||
if(wParam != VK_F10)
|
if(wParam != VK_F10) {
|
||||||
|
if(wParam != VK_MENU && wParam != VK_LMENU && wParam != VK_RMENU)
|
||||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
else {
|
else
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
if(uMsg == WM_SYSKEYUP)
|
if(uMsg == WM_SYSKEYUP)
|
||||||
processKeyUp(retranslateVirtualKey(wParam, lParam));
|
processKeyUp(retranslateVirtualKey(wParam, lParam));
|
||||||
else
|
else
|
||||||
|
|
|
@ -33,6 +33,8 @@ class UIBoxLayout;
|
||||||
class UIHorizontalLayout;
|
class UIHorizontalLayout;
|
||||||
class UIVerticalLayout;
|
class UIVerticalLayout;
|
||||||
class UIGridLayout;
|
class UIGridLayout;
|
||||||
|
class UIAnchor;
|
||||||
|
class UIAnchorGroup;
|
||||||
class UIAnchorLayout;
|
class UIAnchorLayout;
|
||||||
class UIParticles;
|
class UIParticles;
|
||||||
|
|
||||||
|
@ -44,8 +46,11 @@ typedef stdext::shared_object_ptr<UIBoxLayout> UIBoxLayoutPtr;
|
||||||
typedef stdext::shared_object_ptr<UIHorizontalLayout> UIHorizontalLayoutPtr;
|
typedef stdext::shared_object_ptr<UIHorizontalLayout> UIHorizontalLayoutPtr;
|
||||||
typedef stdext::shared_object_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
|
typedef stdext::shared_object_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
|
||||||
typedef stdext::shared_object_ptr<UIGridLayout> UIGridLayoutPtr;
|
typedef stdext::shared_object_ptr<UIGridLayout> UIGridLayoutPtr;
|
||||||
|
typedef stdext::shared_object_ptr<UIAnchor> UIAnchorPtr;
|
||||||
|
typedef stdext::shared_object_ptr<UIAnchorGroup> UIAnchorGroupPtr;
|
||||||
typedef stdext::shared_object_ptr<UIAnchorLayout> UIAnchorLayoutPtr;
|
typedef stdext::shared_object_ptr<UIAnchorLayout> UIAnchorLayoutPtr;
|
||||||
|
|
||||||
typedef std::deque<UIWidgetPtr> UIWidgetList;
|
typedef std::deque<UIWidgetPtr> UIWidgetList;
|
||||||
|
typedef std::vector<UIAnchorPtr> UIAnchorList;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,11 +23,81 @@
|
||||||
#include "uianchorlayout.h"
|
#include "uianchorlayout.h"
|
||||||
#include "uiwidget.h"
|
#include "uiwidget.h"
|
||||||
|
|
||||||
void UIAnchorGroup::addAnchor(const UIAnchor& anchor)
|
UIWidgetPtr UIAnchor::getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget)
|
||||||
|
{
|
||||||
|
// determine hooked widget
|
||||||
|
UIWidgetPtr hookedWidget;
|
||||||
|
if(parentWidget) {
|
||||||
|
if(m_hookedWidgetId == "parent")
|
||||||
|
hookedWidget = parentWidget;
|
||||||
|
else if(m_hookedWidgetId == "next")
|
||||||
|
hookedWidget = parentWidget->getChildAfter(widget);
|
||||||
|
else if(m_hookedWidgetId == "prev")
|
||||||
|
hookedWidget = parentWidget->getChildBefore(widget);
|
||||||
|
else
|
||||||
|
hookedWidget = parentWidget->getChildById(m_hookedWidgetId);
|
||||||
|
}
|
||||||
|
return hookedWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UIAnchor::getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget)
|
||||||
|
{
|
||||||
|
// determine hooked widget edge point
|
||||||
|
Rect hookedWidgetRect = hookedWidget->getRect();
|
||||||
|
if(hookedWidget == parentWidget)
|
||||||
|
hookedWidgetRect = parentWidget->getPaddingRect();
|
||||||
|
|
||||||
|
int point = 0;
|
||||||
|
switch(m_hookedEdge) {
|
||||||
|
case Fw::AnchorLeft:
|
||||||
|
point = hookedWidgetRect.left();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorRight:
|
||||||
|
point = hookedWidgetRect.right();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorTop:
|
||||||
|
point = hookedWidgetRect.top();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorBottom:
|
||||||
|
point = hookedWidgetRect.bottom();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorHorizontalCenter:
|
||||||
|
point = hookedWidgetRect.horizontalCenter();
|
||||||
|
break;
|
||||||
|
case Fw::AnchorVerticalCenter:
|
||||||
|
point = hookedWidgetRect.verticalCenter();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// must never happens
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hookedWidget == parentWidget) {
|
||||||
|
switch(m_hookedEdge) {
|
||||||
|
case Fw::AnchorLeft:
|
||||||
|
case Fw::AnchorRight:
|
||||||
|
case Fw::AnchorHorizontalCenter:
|
||||||
|
point -= parentWidget->getVirtualOffset().x;
|
||||||
|
break;
|
||||||
|
case Fw::AnchorBottom:
|
||||||
|
case Fw::AnchorTop:
|
||||||
|
case Fw::AnchorVerticalCenter:
|
||||||
|
point -= parentWidget->getVirtualOffset().y;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UIAnchorGroup::addAnchor(const UIAnchorPtr& anchor)
|
||||||
{
|
{
|
||||||
// duplicated anchors must be replaced
|
// duplicated anchors must be replaced
|
||||||
for(UIAnchor& other : m_anchors) {
|
for(UIAnchorPtr& other : m_anchors) {
|
||||||
if(other.getAnchoredEdge() == anchor.getAnchoredEdge()) {
|
if(other->getAnchoredEdge() == anchor->getAnchoredEdge()) {
|
||||||
other = anchor;
|
other = anchor;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -43,9 +113,12 @@ void UIAnchorLayout::addAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge
|
||||||
|
|
||||||
assert(anchoredWidget != getParentWidget());
|
assert(anchoredWidget != getParentWidget());
|
||||||
|
|
||||||
UIAnchor anchor(anchoredEdge, hookedWidgetId, hookedEdge);
|
UIAnchorPtr anchor(new UIAnchor(anchoredEdge, hookedWidgetId, hookedEdge));
|
||||||
UIAnchorGroup& anchorGroup = m_anchorsGroups[anchoredWidget];
|
UIAnchorGroupPtr& anchorGroup = m_anchorsGroups[anchoredWidget];
|
||||||
anchorGroup.addAnchor(anchor);
|
if(!anchorGroup)
|
||||||
|
anchorGroup = UIAnchorGroupPtr(new UIAnchorGroup);
|
||||||
|
|
||||||
|
anchorGroup->addAnchor(anchor);
|
||||||
|
|
||||||
// layout must be updated because a new anchor got in
|
// layout must be updated because a new anchor got in
|
||||||
update();
|
update();
|
||||||
|
@ -86,7 +159,7 @@ void UIAnchorLayout::removeWidget(const UIWidgetPtr& widget)
|
||||||
removeAnchors(widget);
|
removeAnchors(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup, UIWidgetPtr first)
|
bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first)
|
||||||
{
|
{
|
||||||
UIWidgetPtr parentWidget = getParentWidget();
|
UIWidgetPtr parentWidget = getParentWidget();
|
||||||
if(!parentWidget)
|
if(!parentWidget)
|
||||||
|
@ -105,23 +178,13 @@ bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
|
||||||
bool horizontalMoved = false;
|
bool horizontalMoved = false;
|
||||||
|
|
||||||
// calculates new rect based on anchors
|
// calculates new rect based on anchors
|
||||||
for(const UIAnchor& anchor : anchorGroup.getAnchors()) {
|
for(const UIAnchorPtr& anchor : anchorGroup->getAnchors()) {
|
||||||
// skip invalid anchors
|
// skip invalid anchors
|
||||||
if(anchor.getHookedEdge() == Fw::AnchorNone)
|
if(anchor->getHookedEdge() == Fw::AnchorNone)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// determine hooked widget
|
// determine hooked widget
|
||||||
UIWidgetPtr hookedWidget;
|
UIWidgetPtr hookedWidget = anchor->getHookedWidget(widget, parentWidget);
|
||||||
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
|
// skip invalid anchors
|
||||||
if(!hookedWidget)
|
if(!hookedWidget)
|
||||||
|
@ -131,61 +194,15 @@ bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
|
||||||
// update this hooked widget anchors
|
// update this hooked widget anchors
|
||||||
auto it = m_anchorsGroups.find(hookedWidget);
|
auto it = m_anchorsGroups.find(hookedWidget);
|
||||||
if(it != m_anchorsGroups.end()) {
|
if(it != m_anchorsGroups.end()) {
|
||||||
UIAnchorGroup& hookedAnchorGroup = it->second;
|
const UIAnchorGroupPtr& hookedAnchorGroup = it->second;
|
||||||
if(!hookedAnchorGroup.isUpdated())
|
if(!hookedAnchorGroup->isUpdated())
|
||||||
updateWidget(hookedWidget, hookedAnchorGroup, first);
|
updateWidget(hookedWidget, hookedAnchorGroup, first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine hooked widget edge point
|
int point = anchor->getHookedPoint(hookedWidget, parentWidget);
|
||||||
Rect hookedWidgetRect = hookedWidget->getRect();
|
|
||||||
if(hookedWidget == parentWidget)
|
|
||||||
hookedWidgetRect = parentWidget->getPaddingRect();
|
|
||||||
|
|
||||||
int point = 0;
|
switch(anchor->getAnchoredEdge()) {
|
||||||
switch(anchor.getHookedEdge()) {
|
|
||||||
case Fw::AnchorLeft:
|
|
||||||
point = hookedWidgetRect.left();
|
|
||||||
break;
|
|
||||||
case Fw::AnchorRight:
|
|
||||||
point = hookedWidgetRect.right();
|
|
||||||
break;
|
|
||||||
case Fw::AnchorTop:
|
|
||||||
point = hookedWidgetRect.top();
|
|
||||||
break;
|
|
||||||
case Fw::AnchorBottom:
|
|
||||||
point = hookedWidgetRect.bottom();
|
|
||||||
break;
|
|
||||||
case Fw::AnchorHorizontalCenter:
|
|
||||||
point = hookedWidgetRect.horizontalCenter();
|
|
||||||
break;
|
|
||||||
case Fw::AnchorVerticalCenter:
|
|
||||||
point = hookedWidgetRect.verticalCenter();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// must never happens
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hookedWidget == parentWidget) {
|
|
||||||
switch(anchor.getHookedEdge()) {
|
|
||||||
case Fw::AnchorLeft:
|
|
||||||
case Fw::AnchorRight:
|
|
||||||
case Fw::AnchorHorizontalCenter:
|
|
||||||
point -= parentWidget->getVirtualOffset().x;
|
|
||||||
break;
|
|
||||||
case Fw::AnchorBottom:
|
|
||||||
case Fw::AnchorTop:
|
|
||||||
case Fw::AnchorVerticalCenter:
|
|
||||||
point -= parentWidget->getVirtualOffset().y;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(anchor.getAnchoredEdge()) {
|
|
||||||
case Fw::AnchorHorizontalCenter:
|
case Fw::AnchorHorizontalCenter:
|
||||||
newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight());
|
newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight());
|
||||||
horizontalMoved = true;
|
horizontalMoved = true;
|
||||||
|
@ -230,7 +247,7 @@ bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
if(widget->setRect(newRect))
|
if(widget->setRect(newRect))
|
||||||
changed = true;
|
changed = true;
|
||||||
anchorGroup.setUpdated(true);
|
anchorGroup->setUpdated(true);
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,15 +257,15 @@ bool UIAnchorLayout::internalUpdate()
|
||||||
|
|
||||||
// reset all anchors groups update state
|
// reset all anchors groups update state
|
||||||
for(auto& it : m_anchorsGroups) {
|
for(auto& it : m_anchorsGroups) {
|
||||||
UIAnchorGroup& anchorGroup = it.second;
|
const UIAnchorGroupPtr& anchorGroup = it.second;
|
||||||
anchorGroup.setUpdated(false);
|
anchorGroup->setUpdated(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update all anchors
|
// update all anchors
|
||||||
for(auto& it : m_anchorsGroups) {
|
for(auto& it : m_anchorsGroups) {
|
||||||
const UIWidgetPtr& widget = it.first;
|
const UIWidgetPtr& widget = it.first;
|
||||||
UIAnchorGroup& anchorGroup = it.second;
|
const UIAnchorGroupPtr& anchorGroup = it.second;
|
||||||
if(!anchorGroup.isUpdated()) {
|
if(!anchorGroup->isUpdated()) {
|
||||||
if(updateWidget(widget, anchorGroup))
|
if(updateWidget(widget, anchorGroup))
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,30 +25,30 @@
|
||||||
|
|
||||||
#include "uilayout.h"
|
#include "uilayout.h"
|
||||||
|
|
||||||
class UIAnchor
|
class UIAnchor : public stdext::shared_object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UIAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge) :
|
UIAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge) :
|
||||||
m_anchoredEdge(anchoredEdge), m_hookedEdge(hookedEdge), m_hookedWidgetId(hookedWidgetId) { }
|
m_anchoredEdge(anchoredEdge), m_hookedEdge(hookedEdge), m_hookedWidgetId(hookedWidgetId) { }
|
||||||
|
|
||||||
Fw::AnchorEdge getAnchoredEdge() const { return m_anchoredEdge; }
|
Fw::AnchorEdge getAnchoredEdge() const { return m_anchoredEdge; }
|
||||||
std::string getHookedWidgetId() const { return m_hookedWidgetId; }
|
|
||||||
Fw::AnchorEdge getHookedEdge() const { return m_hookedEdge; }
|
Fw::AnchorEdge getHookedEdge() const { return m_hookedEdge; }
|
||||||
|
|
||||||
private:
|
virtual UIWidgetPtr getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget);
|
||||||
|
virtual int getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget);
|
||||||
|
|
||||||
|
protected:
|
||||||
Fw::AnchorEdge m_anchoredEdge;
|
Fw::AnchorEdge m_anchoredEdge;
|
||||||
Fw::AnchorEdge m_hookedEdge;
|
Fw::AnchorEdge m_hookedEdge;
|
||||||
std::string m_hookedWidgetId;
|
std::string m_hookedWidgetId;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<UIAnchor> UIAnchorList;
|
class UIAnchorGroup : public stdext::shared_object
|
||||||
|
|
||||||
class UIAnchorGroup
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UIAnchorGroup() : m_updated(true) { }
|
UIAnchorGroup() : m_updated(true) { }
|
||||||
|
|
||||||
void addAnchor(const UIAnchor& anchor);
|
void addAnchor(const UIAnchorPtr& anchor);
|
||||||
const UIAnchorList& getAnchors() { return m_anchors; }
|
const UIAnchorList& getAnchors() { return m_anchors; }
|
||||||
bool isUpdated() { return m_updated; }
|
bool isUpdated() { return m_updated; }
|
||||||
void setUpdated(bool updated) { m_updated = updated; }
|
void setUpdated(bool updated) { m_updated = updated; }
|
||||||
|
@ -77,11 +77,9 @@ public:
|
||||||
bool isUIAnchorLayout() { return true; }
|
bool isUIAnchorLayout() { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool internalUpdate();
|
virtual bool internalUpdate();
|
||||||
|
virtual bool updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first = nullptr);
|
||||||
private:
|
std::unordered_map<UIWidgetPtr, UIAnchorGroupPtr> m_anchorsGroups;
|
||||||
bool updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup, UIWidgetPtr first = nullptr);
|
|
||||||
std::unordered_map<UIWidgetPtr, UIAnchorGroup> m_anchorsGroups;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <framework/platform/platformwindow.h>
|
#include <framework/platform/platformwindow.h>
|
||||||
#include <framework/graphics/texturemanager.h>
|
#include <framework/graphics/texturemanager.h>
|
||||||
#include <framework/core/application.h>
|
#include <framework/core/application.h>
|
||||||
|
#include <framework/luaengine/luainterface.h>
|
||||||
|
|
||||||
UIWidget::UIWidget()
|
UIWidget::UIWidget()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue