Fixes and new tuned terminal

This commit is contained in:
Eduardo Bart 2013-02-28 18:39:27 -03:00
parent 69e762385e
commit b804dd6959
18 changed files with 238 additions and 206 deletions

View File

@ -0,0 +1,8 @@
Font
name: terminus-10px
texture: terminus-10px
height: 12
y-offset: 0
glyph-size: 16 16
fixed-glyph-width: 6
space-width: 6

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -14,8 +14,8 @@ Module
- client_locales - client_locales
- client_topmenu - client_topmenu
- client_background - client_background
- client_entergame
- client_options - client_options
- client_entergame
- client_terminal - client_terminal
- client_modulemanager - client_modulemanager
- client_serverlist - client_serverlist

View File

@ -121,7 +121,7 @@ function installLocale(locale)
end end
if updatesNeeded > 0 then if updatesNeeded > 0 then
pwarning('Locale \'' .. locale.name .. '\' is missing ' .. updatesNeeded .. ' translations.') pdebug('Locale \'' .. locale.name .. '\' is missing ' .. updatesNeeded .. ' translations.')
end end
end end
@ -182,7 +182,7 @@ function _G.tr(text, ...)
if not translation then if not translation then
if translation == nil then if translation == nil then
if currentLocale.name ~= defaultLocaleName then if currentLocale.name ~= defaultLocaleName then
pwarning('Unable to translate: \"' .. text .. '\"') pdebug('Unable to translate: \"' .. text .. '\"')
end end
end end
translation = text translation = text

View File

@ -5,6 +5,5 @@ Module
website: www.otclient.info website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ locales ] scripts: [ locales ]
dependencies: [ client_topmenu ]
@onLoad: init() @onLoad: init()
@onUnload: terminate() @onUnload: terminate()

View File

@ -82,45 +82,20 @@ local function setupGraphicsEngines()
end end
function init() function init()
for k,v in pairs(defaultOptions) do
g_settings.setDefault(k, v)
options[k] = v
end
optionsWindow = g_ui.displayUI('options') optionsWindow = g_ui.displayUI('options')
optionsWindow:hide() optionsWindow:hide()
optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle)
optionsTabBar = optionsWindow:getChildById('optionsTabBar') optionsTabBar = optionsWindow:getChildById('optionsTabBar')
optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent')) optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent'))
addEvent(function() setup() end)
g_keyboard.bindKeyDown('Ctrl+Shift+F', function() toggleOption('fullscreen') end) g_keyboard.bindKeyDown('Ctrl+Shift+F', function() toggleOption('fullscreen') end)
g_keyboard.bindKeyDown('Ctrl+N', toggleDisplays) g_keyboard.bindKeyDown('Ctrl+N', toggleDisplays)
audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end)
end
function terminate()
g_keyboard.unbindKeyDown('Ctrl+Shift+F')
g_keyboard.unbindKeyDown('Ctrl+N')
optionsWindow:destroy()
optionsButton:destroy()
audioButton:destroy()
optionsTabBar = nil
generalPanel = nil
consolePanel = nil
graphicsPanel = nil
audioPanel = nil
end
function setup()
-- load options
for k,v in pairs(defaultOptions) do
g_settings.setDefault(k, v)
if type(v) == 'boolean' then
setOption(k, g_settings.getBoolean(k))
elseif type(v) == 'number' then
setOption(k, g_settings.getNumber(k))
end
end
generalPanel = g_ui.loadUI('game') generalPanel = g_ui.loadUI('game')
optionsTabBar:addTab(tr('Game'), generalPanel, '/images/optionstab/game') optionsTabBar:addTab(tr('Game'), generalPanel, '/images/optionstab/game')
@ -133,7 +108,31 @@ function setup()
audioPanel = g_ui.loadUI('audio') audioPanel = g_ui.loadUI('audio')
optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio') optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio')
optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle)
audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end)
addEvent(function() setup() end)
end
function terminate()
g_keyboard.unbindKeyDown('Ctrl+Shift+F')
g_keyboard.unbindKeyDown('Ctrl+N')
optionsWindow:destroy()
optionsButton:destroy()
audioButton:destroy()
end
function setup()
setupGraphicsEngines() setupGraphicsEngines()
-- load options
for k,v in pairs(defaultOptions) do
if type(v) == 'boolean' then
setOption(k, g_settings.getBoolean(k), true)
elseif type(v) == 'number' then
setOption(k, g_settings.getNumber(k), true)
end
end
end end
function toggle() function toggle()
@ -172,8 +171,8 @@ function toggleOption(key)
setOption(key, not getOption(key)) setOption(key, not getOption(key))
end end
function setOption(key, value) function setOption(key, value, force)
if options[key] == value then return end if not force and options[key] == value then return end
local gameMapPanel = modules.game_interface.getMapPanel() local gameMapPanel = modules.game_interface.getMapPanel()
local panel = nil local panel = nil
@ -188,66 +187,37 @@ function setOption(key, value)
panel = graphicsPanel panel = graphicsPanel
elseif key == 'enableAudio' then elseif key == 'enableAudio' then
g_sounds.setAudioEnabled(value) g_sounds.setAudioEnabled(value)
addEvent(function() if value then
if value then audioButton:setIcon('/images/topbuttons/audio')
audioButton:setIcon('/images/topbuttons/audio') else
else audioButton:setIcon('/images/topbuttons/audio_mute')
audioButton:setIcon('/images/topbuttons/audio_mute') end
end
end)
panel = audioPanel panel = audioPanel
elseif key == 'enableMusicSound' then elseif key == 'enableMusicSound' then
g_sounds.getChannel(SoundChannels.Music):setEnabled(value) g_sounds.getChannel(SoundChannels.Music):setEnabled(value)
elseif key == 'musicSoundVolume' then elseif key == 'musicSoundVolume' then
g_sounds.getChannel(SoundChannels.Music):setGain(value/100) g_sounds.getChannel(SoundChannels.Music):setGain(value/100)
if audioPanel then audioPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value))
audioPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value))
end
elseif key == 'showLeftPanel' then elseif key == 'showLeftPanel' then
addEvent(function() modules.game_interface.getLeftPanel():setOn(value)
modules.game_interface.getLeftPanel():setOn(value)
end)
elseif key == 'backgroundFrameRate' then elseif key == 'backgroundFrameRate' then
local text = value local text = value
if value <= 0 or value >= 201 then if value <= 0 or value >= 201 then text = 'max' value = 0 end
text = 'max' graphicsPanel:getChildById('backgroundFrameRateLabel'):setText(tr('Game framerate limit: %s', text))
value = 0
end
if graphicsPanel then
graphicsPanel:getChildById('backgroundFrameRateLabel'):setText(tr('Game framerate limit: %s', text))
end
g_app.setBackgroundPaneMaxFps(value) g_app.setBackgroundPaneMaxFps(value)
elseif key == 'foregroundFrameRate' then elseif key == 'foregroundFrameRate' then
local text = value local text = value
if value <= 0 or value >= 61 then if value <= 0 or value >= 61 then text = 'max' value = 0 end
text = 'max' graphicsPanel:getChildById('foregroundFrameRateLabel'):setText(tr('Interface framerate limit: %s', text))
value = 0
end
if graphicsPanel then
graphicsPanel:getChildById('foregroundFrameRateLabel'):setText(tr('Interface framerate limit: %s', text))
end
g_app.setForegroundPaneMaxFps(value) g_app.setForegroundPaneMaxFps(value)
elseif key == 'enableLights' then elseif key == 'enableLights' then
addEvent(function() gameMapPanel:setDrawLights(value and options['ambientLight'] < 100)
local map = modules.game_interface.getMapPanel() graphicsPanel:getChildById('ambientLight'):setEnabled(value)
map:setDrawLights(value and options['ambientLight'] < 100) graphicsPanel:getChildById('ambientLightLabel'):setEnabled(value)
if graphicsPanel then
graphicsPanel:getChildById('ambientLight'):setEnabled(value)
graphicsPanel:getChildById('ambientLightLabel'):setEnabled(value)
end
end)
elseif key == 'ambientLight' then elseif key == 'ambientLight' then
addEvent(function() graphicsPanel:getChildById('ambientLightLabel'):setText(tr('Ambient light: %s%%', value))
local map = modules.game_interface.getMapPanel() gameMapPanel:setMinimumAmbientLight(value/100)
if graphicsPanel then gameMapPanel:setDrawLights(options['enableLights'] and value < 100)
graphicsPanel:getChildById('ambientLightLabel'):setText(tr('Ambient light: %s%%', value))
end
map:setMinimumAmbientLight(value/100)
map:setDrawLights(options['enableLights'] and value < 100)
end)
elseif key == 'painterEngine' then elseif key == 'painterEngine' then
g_graphics.selectPainterEngine(value) g_graphics.selectPainterEngine(value)
elseif key == 'displayNames' then elseif key == 'displayNames' then

View File

@ -4,7 +4,6 @@ Module
author: edubart, BeniS author: edubart, BeniS
website: www.otclient.info website: www.otclient.info
sandboxed: true sandboxed: true
dependencies: [ client_topmenu ]
scripts: [ options ] scripts: [ options ]
@onLoad: init() @onLoad: init()
@onUnload: terminate() @onUnload: terminate()

View File

@ -1,84 +1,17 @@
function dumpWidgets(widget, level) function draw_debug_boxes(enable)
widget = widget or rootWidget
level = level or 0
for i=1,widget:getChildCount() do
local child = widget:getChildByIndex(i)
if child:isVisible() then
local name = child:getId()
if name:match('widget%d+') == nil then
print(string.rep(' ', level) .. name)
end
if child:getId() ~= 'terminalBuffer' then
dumpWidgets(child, level+1)
end
end
end
end
function drawDebugBoxes(enable)
if enable == nil then enable = true end if enable == nil then enable = true end
g_ui.setDebugBoxesDrawing(enable) g_ui.setDebugBoxesDrawing(enable)
end end
function hideMap() function hide_map()
local map = rootWidget:recursiveGetChildById('gameMapPanel') modules.game_interface.getMapPanel():hide()
if map then map:hide() end
end end
function showMap() function show_map()
local map = rootWidget:recursiveGetChildById('gameMapPanel') modules.game_interface.getMapPanel():show()
if map then map:show() end
end end
function debugContainersItems() function auto_reload_module(name)
function UIItem:onHoverChange(hovered)
if hovered then
local item = self:getItem()
if item then
local text = "id: " ..item:getId() ..
"\n stackable: " ..tostring(item:isStackable()) ..
"\n marketable: " ..tostring(item:isMarketable()) ..
"\n vocation: "..(item:getMarketData() and item:getMarketData().restrictVocation or 'none') ..
"\n cloth slot: " ..item:getClothSlot()
g_tooltip.display(text)
end
else
g_tooltip.hide()
end
end
end
function debugPosition(enable)
if enable == nil then enable = true end
local label = rootWidget:getChildById('debugPositionLabel')
if not label then
label = g_ui.createWidget('GameLabel', rootWidget)
label:setColor('pink')
label:setFont('terminus-14px-bold')
label:setId('debugPositionLabel')
label:setPosition({x= 10, y = 40 })
label:setPhantom(true)
label:setTextAutoResize(true)
end
if enable then
label.event = cycleEvent(function()
local player = g_game.getLocalPlayer()
if player then
local pos = g_game.getLocalPlayer():getPosition()
label:show()
label:setText('x: ' .. pos.x .. '\ny: ' .. pos.y .. '\nz: ' .. pos.z)
else
label:hide()
end
end, 100)
else
removeEvent(label.event)
label.event = nil
label:hide()
end
end
function autoReloadModule(name)
local function reloadEvent() local function reloadEvent()
reloadModule(name) reloadModule(name)
scheduleEvent(reloadEvent, 1000) scheduleEvent(reloadEvent, 1000)
@ -86,14 +19,53 @@ function autoReloadModule(name)
reloadEvent() reloadEvent()
end end
function createDebugUIItem(id) local function pingBack(ping) print(g_game.getWorldName() .. ' => ' .. ping .. ' ms') end
local uiitem = g_ui.createWidget('Item', rootWidget) local pinging = false
uiitem:setPosition({x= 200, y = 200 }) function ping()
uiitem:setItemId(id) if pinging then
uiitem:show() pdebug('Ping stopped.')
g_game.setPingDelay(1000)
disconnect(g_game, 'onPingBack', pingBack)
else
if not (g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing)) then
perror('this server does not support ping')
return
elseif not g_game.isOnline() then
perror('ping command is only allowed when online')
return
end
pdebug('Starting ping...')
g_game.setPingDelay(0)
connect(g_game, 'onPingBack', pingBack)
end
pinging = not pinging
end end
function debugPings() function clear()
g_game.setPingDelay(0) modules.client_terminal.clear()
connect(g_game, { onPingBack = function(ping) print(g_game.getWorldName() .. ' => ' .. ping .. ' ms') end }) end
function ls(path)
path = path or '/'
local files = g_resources.listDirectoryFiles(path)
for k,v in pairs(files) do
if g_resources.directoryExists(path .. v) then
modules.client_terminal.addLine(path .. v, 'blue')
else
pinfo(path .. v)
end
end
end
function about_version()
pinfo(g_app.getName() .. ' ' .. g_app.getVersion() .. '\n' ..
'Rev ' .. g_app.getBuildRevision() .. ' ('.. g_app.getBuildCommit() .. ')\n' ..
'Built on ' .. g_app.getBuildDate())
end
function about_graphics()
pinfo('Vendor ' .. g_graphics.getVendor() )
pinfo('Renderer' .. g_graphics.getRenderer())
pinfo('Version' .. g_graphics.getVersion())
end end

View File

@ -1,17 +1,21 @@
-- configs -- configs
local LogColors = { [LogInfo] = 'white', local LogColors = { [LogDebug] = 'pink',
[LogInfo] = 'white',
[LogWarning] = 'yellow', [LogWarning] = 'yellow',
[LogError] = 'red' } [LogError] = 'red' }
local MaxLogLines = 80 local MaxLogLines = 512
local LabelHeight = 16 local LabelHeight = 16
local MaxHistory = 1000 local MaxHistory = 1000
local oldenv = getfenv(0)
setfenv(0, _G)
commandEnv = runinsandbox('commands')
setfenv(0, oldenv)
-- private variables -- private variables
local terminalWindow local terminalWindow
local terminalButton local terminalButton
local logLocked = false local logLocked = false
local commandEnv = {}
setmetatable(commandEnv, { __index = getfenv() } )
local commandTextEdit local commandTextEdit
local terminalBuffer local terminalBuffer
local commandHistory = { } local commandHistory = { }
@ -96,9 +100,6 @@ local function doCommand()
end end
local function onLog(level, message, time) local function onLog(level, message, time)
-- debug messages are ignored
if level == LogDebug then return end
-- avoid logging while reporting logs (would cause a infinite loop) -- avoid logging while reporting logs (would cause a infinite loop)
if logLocked then return end if logLocked then return end
@ -137,11 +138,19 @@ function init()
commandTextEdit = terminalWindow:getChildById('commandTextEdit') commandTextEdit = terminalWindow:getChildById('commandTextEdit')
g_keyboard.bindKeyPress('Up', function() navigateCommand(1) end, commandTextEdit) g_keyboard.bindKeyPress('Up', function() navigateCommand(1) end, commandTextEdit)
g_keyboard.bindKeyPress('Down', function() navigateCommand(-1) end, commandTextEdit) g_keyboard.bindKeyPress('Down', function() navigateCommand(-1) end, commandTextEdit)
g_keyboard.bindKeyPress('Ctrl+C',
function()
if commandTextEdit:hasSelection() or not terminalSelectText:hasSelection() then return false end
g_window.setClipboardText(terminalSelectText:getSelection())
return true
end, commandTextEdit)
g_keyboard.bindKeyDown('Tab', completeCommand, commandTextEdit) g_keyboard.bindKeyDown('Tab', completeCommand, commandTextEdit)
g_keyboard.bindKeyDown('Enter', doCommand, commandTextEdit) g_keyboard.bindKeyDown('Enter', doCommand, commandTextEdit)
g_keyboard.bindKeyDown('Escape', hide, terminalWindow) g_keyboard.bindKeyDown('Escape', hide, terminalWindow)
terminalBuffer = terminalWindow:getChildById('terminalBuffer') terminalBuffer = terminalWindow:recursiveGetChildById('terminalBuffer')
terminalSelectText = terminalWindow:recursiveGetChildById('terminalSelectText')
g_logger.setOnLog(onLog) g_logger.setOnLog(onLog)
g_logger.fireOldMessages() g_logger.fireOldMessages()
end end
@ -194,6 +203,8 @@ function addLine(text, color)
label:setId('terminalLabel' .. numLines) label:setId('terminalLabel' .. numLines)
label:setText(text) label:setText(text)
label:setColor(color) label:setColor(color)
terminalSelectText:setText(terminalSelectText:getText() .. '\n' .. text)
end end
function executeCommand(command) function executeCommand(command)
@ -203,6 +214,18 @@ function executeCommand(command)
g_logger.log(LogInfo, '> ' .. command) g_logger.log(LogInfo, '> ' .. command)
logLocked = false logLocked = false
local func
local err
-- detect terminal commands
local command_name = command:match('^([%w_]+)[%s]*.*')
if command_name then
local args = string.split(command:match('^[%w]+[%s]*(.*)'), ' ')
if commandEnv[command_name] and type(commandEnv[command_name]) == 'function' then
func = function() modules.client_terminal.commandEnv[command_name](unpack(args)) end
end
end
-- detect and convert commands with simple syntax -- detect and convert commands with simple syntax
local realCommand local realCommand
if string.sub(command, 1, 1) == '=' then if string.sub(command, 1, 1) == '=' then
@ -226,23 +249,32 @@ function executeCommand(command)
--addLine(">> " .. command, "#ffffff") --addLine(">> " .. command, "#ffffff")
-- load command buffer -- load command buffer
local func, err = loadstring(realCommand, "@")
-- check for syntax errors
if not func then if not func then
g_logger.log(LogError, 'incorrect lua syntax: ' .. err:sub(5)) func, err = loadstring(realCommand, "@")
return
-- check for syntax errors
if not func then
g_logger.log(LogError, 'incorrect lua syntax: ' .. err:sub(5))
return
end
end end
-- setup func env to commandEnv -- setup func env to commandEnv
setfenv(func, commandEnv) setfenv(func, commandEnv)
-- execute the command -- execute the command
local ok, ret = pcall(func) addEvent(function()
if ok then local ok, ret = pcall(func)
-- if the command returned a value, print it if ok then
if ret then print(ret) end -- if the command returned a value, print it
else if ret then print(ret) end
g_logger.log(LogError, 'command failed: ' .. ret) else
end g_logger.log(LogError, 'command failed: ' .. ret)
end
end)
end
function clear()
terminalBuffer:destroyChildren()
terminalSelectText:setText('')
end end

View File

@ -3,7 +3,7 @@ Module
description: Terminal for executing lua functions description: Terminal for executing lua functions
author: edubart author: edubart
website: www.otclient.info website: www.otclient.info
scripts: [ terminal, commands ] scripts: [ terminal ]
sandboxed: true sandboxed: true
@onLoad: init() @onLoad: init()
@onUnload: terminate() @onUnload: terminate()

View File

@ -1,7 +1,21 @@
TerminalLabel < UILabel TerminalLabel < UILabel
font: terminus-14px-bold font: terminus-10px
text-wrap: true text-wrap: true
text-auto-resize: true text-auto-resize: true
phantom: true
TerminalSelectText < UITextEdit
font: terminus-10px
text-wrap: true
text-align: bottomLeft
editable: false
change-cursor-image: false
cursor-visible: false
selection-color: black
selection-background-color: white
color: alpha
focusable: false
auto-scroll: false
UIWindow UIWindow
id: terminalWindow id: terminalWindow
@ -10,35 +24,57 @@ UIWindow
clipping: true clipping: true
anchors.fill: parent anchors.fill: parent
Panel ScrollablePanel
id: terminalBuffer id: terminalScrollArea
layout:
type: verticalBox
fit-children: true
focusable: false focusable: false
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: terminalScroll.left
anchors.top: parent.top
anchors.bottom: commandSymbolLabel.top anchors.bottom: commandSymbolLabel.top
vertical-scrollbar: terminalScroll
inverted-scroll: true
margin-left: 2 margin-left: 2
Panel
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
id: terminalBuffer
layout:
type: verticalBox
fit-children: true
focusable: false
TerminalSelectText
id: terminalSelectText
anchors.fill: terminalBuffer
VerticalScrollBar
id: terminalScroll
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
step: 48
pixels-scroll: true
UILabel UILabel
id: commandSymbolLabel id: commandSymbolLabel
size: 12 16 size: 12 12
fixed-size: true fixed-size: true
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
margin-left: 2 margin-left: 2
font: terminus-14px-bold font: terminus-10px
text: > text: >
UITextEdit UITextEdit
id: commandTextEdit id: commandTextEdit
height: 16 height: 12
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: commandSymbolLabel.right anchors.left: commandSymbolLabel.right
anchors.right: parent.right anchors.right: parent.right
margin-left: 5 margin-left: 1
font: terminus-14px-bold font: terminus-10px
selection-color: black selection-color: black
selection-background-color: white selection-background-color: white

View File

@ -68,11 +68,13 @@ end
function online() function online()
showGameButtons() showGameButtons()
if g_settings.getBoolean('showPing') and (g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing)) then addEvent(function()
pingLabel:show() if modules.client_options.getOption('showPing') and (g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing)) then
else pingLabel:show()
pingLabel:hide() else
end pingLabel:hide()
end
end)
end end
function offline() function offline()

View File

@ -127,7 +127,7 @@ end
function UIMiniWindowContainer:scheduleInsert(widget, index) function UIMiniWindowContainer:scheduleInsert(widget, index)
if index - 1 > self:getChildCount() then if index - 1 > self:getChildCount() then
if self.scheduledWidgets[index] then if self.scheduledWidgets[index] then
pwarning('replacing scheduled widget id ' .. widget:getId()) pdebug('replacing scheduled widget id ' .. widget:getId())
end end
self.scheduledWidgets[index] = widget self.scheduledWidgets[index] = widget
else else

View File

@ -10,6 +10,7 @@ MainWindow
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
max-length: 255
TextEdit TextEdit
id: text id: text

View File

@ -10,7 +10,7 @@ MiniWindow
text: ? text: ?
text-align: center text-align: center
phantom: false phantom: false
!tooltip: tr('Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks\nPress Ctrl+Shift+M to view the entire game map')') !tooltip: tr('Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks\nPress Ctrl+Shift+M to view the entire game map')
anchors.top: minimizeButton.top anchors.top: minimizeButton.top
anchors.right: minimizeButton.left anchors.right: minimizeButton.left
margin-right: 3 margin-right: 3

View File

@ -542,8 +542,15 @@ 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->isOnTop() && !thing->isIgnoreLook()) if(thing->isGround())
hasGround = true;
if(thing->isOnBottom())
hasOnBottom = true;
if((hasGround || hasOnBottom) && !hasIgnoreLook)
return true; return true;
} }
return false; return false;

View File

@ -41,6 +41,7 @@ UITextEdit::UITextEdit()
m_maxLength = 0; m_maxLength = 0;
m_editable = true; m_editable = true;
m_selectable = true; m_selectable = true;
m_autoScroll = false;
m_changeCursorImage = true; m_changeCursorImage = true;
m_selectionReference = 0; m_selectionReference = 0;
m_selectionStart = 0; m_selectionStart = 0;
@ -164,7 +165,7 @@ void UITextEdit::update(bool focusCursor)
// readjust start view area based on cursor position // readjust start view area based on cursor position
m_cursorInRange = false; m_cursorInRange = false;
if(focusCursor) { if(focusCursor && m_autoScroll) {
if(m_cursorPos > 0 && textLength > 0) { if(m_cursorPos > 0 && textLength > 0) {
assert(m_cursorPos <= textLength); assert(m_cursorPos <= textLength);
Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(m_padding.left+m_padding.right, 0)); // previous rendered virtual rect Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(m_padding.left+m_padding.right, 0)); // previous rendered virtual rect
@ -628,6 +629,8 @@ void UITextEdit::onStyleApply(const std::string& styleName, const OTMLNodePtr& s
setCursorVisible(node->value<bool>()); setCursorVisible(node->value<bool>());
else if(node->tag() == "change-cursor-image") else if(node->tag() == "change-cursor-image")
setChangeCursorImage(node->value<bool>()); setChangeCursorImage(node->value<bool>());
else if(node->tag() == "auto-scroll")
setAutoScroll(node->value<bool>());
} }
} }

View File

@ -51,6 +51,7 @@ public:
void setSelectable(bool selectable) { m_selectable = selectable; } void setSelectable(bool selectable) { m_selectable = selectable; }
void setSelectionColor(const Color& color) { m_selectionColor = color; } void setSelectionColor(const Color& color) { m_selectionColor = color; }
void setSelectionBackgroundColor(const Color& color) { m_selectionBackgroundColor = color; } void setSelectionBackgroundColor(const Color& color) { m_selectionBackgroundColor = color; }
void setAutoScroll(bool autoScroll) { m_autoScroll = autoScroll; }
void moveCursorHorizontally(bool right); void moveCursorHorizontally(bool right);
void moveCursorVertically(bool up); void moveCursorVertically(bool up);
@ -87,6 +88,7 @@ public:
bool isMultiline() { return m_multiline; } bool isMultiline() { return m_multiline; }
bool isEditable() { return m_editable; } bool isEditable() { return m_editable; }
bool isSelectable() { return m_selectable; } bool isSelectable() { return m_selectable; }
bool isAutoScrolling() { return m_autoScroll; }
protected: protected:
void updateText(); void updateText();
@ -123,6 +125,7 @@ private:
std::string m_validCharacters; std::string m_validCharacters;
uint m_maxLength; uint m_maxLength;
bool m_updatesEnabled; bool m_updatesEnabled;
bool m_autoScroll;
bool m_selectable; bool m_selectable;
int m_selectionReference; int m_selectionReference;