From b804dd6959f58db589664ce37d3fd8a62c49cb6a Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Thu, 28 Feb 2013 18:39:27 -0300 Subject: [PATCH] Fixes and new tuned terminal --- data/fonts/terminus-10px.otfont | 8 ++ data/fonts/terminus-10px.png | Bin 0 -> 3173 bytes modules/client/client.otmod | 2 +- modules/client_locales/locales.lua | 4 +- modules/client_locales/locales.otmod | 1 - modules/client_options/options.lua | 116 +++++++---------- modules/client_options/options.otmod | 1 - modules/client_terminal/commands.lua | 128 ++++++++----------- modules/client_terminal/terminal.lua | 72 ++++++++--- modules/client_terminal/terminal.otmod | 2 +- modules/client_terminal/terminal.otui | 60 +++++++-- modules/client_topmenu/topmenu.lua | 12 +- modules/corelib/ui/uiminiwindowcontainer.lua | 2 +- modules/game_console/violationwindow.otui | 1 + modules/game_minimap/minimap.otui | 2 +- src/client/tile.cpp | 9 +- src/framework/ui/uitextedit.cpp | 5 +- src/framework/ui/uitextedit.h | 3 + 18 files changed, 230 insertions(+), 198 deletions(-) create mode 100644 data/fonts/terminus-10px.otfont create mode 100644 data/fonts/terminus-10px.png diff --git a/data/fonts/terminus-10px.otfont b/data/fonts/terminus-10px.otfont new file mode 100644 index 00000000..957da0de --- /dev/null +++ b/data/fonts/terminus-10px.otfont @@ -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 diff --git a/data/fonts/terminus-10px.png b/data/fonts/terminus-10px.png new file mode 100644 index 0000000000000000000000000000000000000000..4e8f500cfb1150da73845f65a41a3e0dcc2d4cd7 GIT binary patch literal 3173 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 0 then - pwarning('Locale \'' .. locale.name .. '\' is missing ' .. updatesNeeded .. ' translations.') + pdebug('Locale \'' .. locale.name .. '\' is missing ' .. updatesNeeded .. ' translations.') end end @@ -182,7 +182,7 @@ function _G.tr(text, ...) if not translation then if translation == nil then if currentLocale.name ~= defaultLocaleName then - pwarning('Unable to translate: \"' .. text .. '\"') + pdebug('Unable to translate: \"' .. text .. '\"') end end translation = text diff --git a/modules/client_locales/locales.otmod b/modules/client_locales/locales.otmod index 403081b8..623701e7 100644 --- a/modules/client_locales/locales.otmod +++ b/modules/client_locales/locales.otmod @@ -5,6 +5,5 @@ Module website: www.otclient.info sandboxed: true scripts: [ locales ] - dependencies: [ client_topmenu ] @onLoad: init() @onUnload: terminate() diff --git a/modules/client_options/options.lua b/modules/client_options/options.lua index 91459bba..0fc0431f 100644 --- a/modules/client_options/options.lua +++ b/modules/client_options/options.lua @@ -82,19 +82,36 @@ local function setupGraphicsEngines() end function init() + for k,v in pairs(defaultOptions) do + g_settings.setDefault(k, v) + options[k] = v + end + optionsWindow = g_ui.displayUI('options') optionsWindow:hide() - optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle) optionsTabBar = optionsWindow:getChildById('optionsTabBar') optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent')) - addEvent(function() setup() end) - g_keyboard.bindKeyDown('Ctrl+Shift+F', function() toggleOption('fullscreen') end) g_keyboard.bindKeyDown('Ctrl+N', toggleDisplays) + generalPanel = g_ui.loadUI('game') + optionsTabBar:addTab(tr('Game'), generalPanel, '/images/optionstab/game') + + consolePanel = g_ui.loadUI('console') + optionsTabBar:addTab(tr('Console'), consolePanel, '/images/optionstab/console') + + graphicsPanel = g_ui.loadUI('graphics') + optionsTabBar:addTab(tr('Graphics'), graphicsPanel, '/images/optionstab/graphics') + + audioPanel = g_ui.loadUI('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() @@ -103,37 +120,19 @@ function terminate() optionsWindow:destroy() optionsButton:destroy() audioButton:destroy() - optionsTabBar = nil - generalPanel = nil - consolePanel = nil - graphicsPanel = nil - audioPanel = nil end function setup() + setupGraphicsEngines() + -- 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)) + setOption(k, g_settings.getBoolean(k), true) elseif type(v) == 'number' then - setOption(k, g_settings.getNumber(k)) + setOption(k, g_settings.getNumber(k), true) end end - - generalPanel = g_ui.loadUI('game') - optionsTabBar:addTab(tr('Game'), generalPanel, '/images/optionstab/game') - - consolePanel = g_ui.loadUI('console') - optionsTabBar:addTab(tr('Console'), consolePanel, '/images/optionstab/console') - - graphicsPanel = g_ui.loadUI('graphics') - optionsTabBar:addTab(tr('Graphics'), graphicsPanel, '/images/optionstab/graphics') - - audioPanel = g_ui.loadUI('audio') - optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio') - - setupGraphicsEngines() end function toggle() @@ -172,8 +171,8 @@ function toggleOption(key) setOption(key, not getOption(key)) end -function setOption(key, value) - if options[key] == value then return end +function setOption(key, value, force) + if not force and options[key] == value then return end local gameMapPanel = modules.game_interface.getMapPanel() local panel = nil @@ -188,66 +187,37 @@ function setOption(key, value) panel = graphicsPanel elseif key == 'enableAudio' then g_sounds.setAudioEnabled(value) - addEvent(function() - if value then - audioButton:setIcon('/images/topbuttons/audio') - else - audioButton:setIcon('/images/topbuttons/audio_mute') - end - end) + if value then + audioButton:setIcon('/images/topbuttons/audio') + else + audioButton:setIcon('/images/topbuttons/audio_mute') + end panel = audioPanel elseif key == 'enableMusicSound' then g_sounds.getChannel(SoundChannels.Music):setEnabled(value) elseif key == 'musicSoundVolume' then g_sounds.getChannel(SoundChannels.Music):setGain(value/100) - if audioPanel then - audioPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value)) - end + audioPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value)) elseif key == 'showLeftPanel' then - addEvent(function() - modules.game_interface.getLeftPanel():setOn(value) - end) + modules.game_interface.getLeftPanel():setOn(value) elseif key == 'backgroundFrameRate' then local text = value - if value <= 0 or value >= 201 then - text = 'max' - value = 0 - end - - if graphicsPanel then - graphicsPanel:getChildById('backgroundFrameRateLabel'):setText(tr('Game framerate limit: %s', text)) - end + if value <= 0 or value >= 201 then text = 'max' value = 0 end + graphicsPanel:getChildById('backgroundFrameRateLabel'):setText(tr('Game framerate limit: %s', text)) g_app.setBackgroundPaneMaxFps(value) elseif key == 'foregroundFrameRate' then local text = value - if value <= 0 or value >= 61 then - text = 'max' - value = 0 - end - - if graphicsPanel then - graphicsPanel:getChildById('foregroundFrameRateLabel'):setText(tr('Interface framerate limit: %s', text)) - end + if value <= 0 or value >= 61 then text = 'max' value = 0 end + graphicsPanel:getChildById('foregroundFrameRateLabel'):setText(tr('Interface framerate limit: %s', text)) g_app.setForegroundPaneMaxFps(value) elseif key == 'enableLights' then - addEvent(function() - local map = modules.game_interface.getMapPanel() - map:setDrawLights(value and options['ambientLight'] < 100) - - if graphicsPanel then - graphicsPanel:getChildById('ambientLight'):setEnabled(value) - graphicsPanel:getChildById('ambientLightLabel'):setEnabled(value) - end - end) + gameMapPanel:setDrawLights(value and options['ambientLight'] < 100) + graphicsPanel:getChildById('ambientLight'):setEnabled(value) + graphicsPanel:getChildById('ambientLightLabel'):setEnabled(value) elseif key == 'ambientLight' then - addEvent(function() - local map = modules.game_interface.getMapPanel() - if graphicsPanel then - graphicsPanel:getChildById('ambientLightLabel'):setText(tr('Ambient light: %s%%', value)) - end - map:setMinimumAmbientLight(value/100) - map:setDrawLights(options['enableLights'] and value < 100) - end) + graphicsPanel:getChildById('ambientLightLabel'):setText(tr('Ambient light: %s%%', value)) + gameMapPanel:setMinimumAmbientLight(value/100) + gameMapPanel:setDrawLights(options['enableLights'] and value < 100) elseif key == 'painterEngine' then g_graphics.selectPainterEngine(value) elseif key == 'displayNames' then diff --git a/modules/client_options/options.otmod b/modules/client_options/options.otmod index 1b99917a..8216f644 100644 --- a/modules/client_options/options.otmod +++ b/modules/client_options/options.otmod @@ -4,7 +4,6 @@ Module author: edubart, BeniS website: www.otclient.info sandboxed: true - dependencies: [ client_topmenu ] scripts: [ options ] @onLoad: init() @onUnload: terminate() diff --git a/modules/client_terminal/commands.lua b/modules/client_terminal/commands.lua index 5bd5b4cc..71c5cbaa 100644 --- a/modules/client_terminal/commands.lua +++ b/modules/client_terminal/commands.lua @@ -1,99 +1,71 @@ -function dumpWidgets(widget, level) - 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) +function draw_debug_boxes(enable) if enable == nil then enable = true end g_ui.setDebugBoxesDrawing(enable) end -function hideMap() - local map = rootWidget:recursiveGetChildById('gameMapPanel') - if map then map:hide() end +function hide_map() + modules.game_interface.getMapPanel():hide() end -function showMap() - local map = rootWidget:recursiveGetChildById('gameMapPanel') - if map then map:show() end +function show_map() + modules.game_interface.getMapPanel():show() end -function debugContainersItems() - 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 +function auto_reload_module(name) + local function reloadEvent() + reloadModule(name) + scheduleEvent(reloadEvent, 1000) end + reloadEvent() 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) +local function pingBack(ping) print(g_game.getWorldName() .. ' => ' .. ping .. ' ms') end +local pinging = false +function ping() + if pinging then + pdebug('Ping stopped.') + g_game.setPingDelay(1000) + disconnect(g_game, 'onPingBack', pingBack) else - removeEvent(label.event) - label.event = nil - label:hide() + 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 -function autoReloadModule(name) - local function reloadEvent() - reloadModule(name) - scheduleEvent(reloadEvent, 1000) +function clear() + modules.client_terminal.clear() +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 - reloadEvent() end -function createDebugUIItem(id) - local uiitem = g_ui.createWidget('Item', rootWidget) - uiitem:setPosition({x= 200, y = 200 }) - uiitem:setItemId(id) - uiitem:show() +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 debugPings() - g_game.setPingDelay(0) - connect(g_game, { onPingBack = function(ping) print(g_game.getWorldName() .. ' => ' .. ping .. ' ms') end }) +function about_graphics() + pinfo('Vendor ' .. g_graphics.getVendor() ) + pinfo('Renderer' .. g_graphics.getRenderer()) + pinfo('Version' .. g_graphics.getVersion()) end diff --git a/modules/client_terminal/terminal.lua b/modules/client_terminal/terminal.lua index 49601f38..db9b3ed5 100644 --- a/modules/client_terminal/terminal.lua +++ b/modules/client_terminal/terminal.lua @@ -1,17 +1,21 @@ -- configs -local LogColors = { [LogInfo] = 'white', +local LogColors = { [LogDebug] = 'pink', + [LogInfo] = 'white', [LogWarning] = 'yellow', [LogError] = 'red' } -local MaxLogLines = 80 +local MaxLogLines = 512 local LabelHeight = 16 local MaxHistory = 1000 +local oldenv = getfenv(0) +setfenv(0, _G) +commandEnv = runinsandbox('commands') +setfenv(0, oldenv) + -- private variables local terminalWindow local terminalButton local logLocked = false -local commandEnv = {} -setmetatable(commandEnv, { __index = getfenv() } ) local commandTextEdit local terminalBuffer local commandHistory = { } @@ -96,9 +100,6 @@ local function doCommand() end 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) if logLocked then return end @@ -137,11 +138,19 @@ function init() commandTextEdit = terminalWindow:getChildById('commandTextEdit') g_keyboard.bindKeyPress('Up', 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('Enter', doCommand, commandTextEdit) g_keyboard.bindKeyDown('Escape', hide, terminalWindow) - terminalBuffer = terminalWindow:getChildById('terminalBuffer') + terminalBuffer = terminalWindow:recursiveGetChildById('terminalBuffer') + terminalSelectText = terminalWindow:recursiveGetChildById('terminalSelectText') + g_logger.setOnLog(onLog) g_logger.fireOldMessages() end @@ -194,6 +203,8 @@ function addLine(text, color) label:setId('terminalLabel' .. numLines) label:setText(text) label:setColor(color) + + terminalSelectText:setText(terminalSelectText:getText() .. '\n' .. text) end function executeCommand(command) @@ -203,6 +214,18 @@ function executeCommand(command) g_logger.log(LogInfo, '> ' .. command) 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 local realCommand if string.sub(command, 1, 1) == '=' then @@ -226,23 +249,32 @@ function executeCommand(command) --addLine(">> " .. command, "#ffffff") -- load command buffer - local func, err = loadstring(realCommand, "@") - - -- check for syntax errors if not func then - g_logger.log(LogError, 'incorrect lua syntax: ' .. err:sub(5)) - return + func, err = loadstring(realCommand, "@") + + -- check for syntax errors + if not func then + g_logger.log(LogError, 'incorrect lua syntax: ' .. err:sub(5)) + return + end end -- setup func env to commandEnv setfenv(func, commandEnv) -- execute the command - local ok, ret = pcall(func) - if ok then - -- if the command returned a value, print it - if ret then print(ret) end - else - g_logger.log(LogError, 'command failed: ' .. ret) - end + addEvent(function() + local ok, ret = pcall(func) + if ok then + -- if the command returned a value, print it + if ret then print(ret) end + else + g_logger.log(LogError, 'command failed: ' .. ret) + end + end) +end + +function clear() + terminalBuffer:destroyChildren() + terminalSelectText:setText('') end diff --git a/modules/client_terminal/terminal.otmod b/modules/client_terminal/terminal.otmod index 5460b356..e3dc5115 100644 --- a/modules/client_terminal/terminal.otmod +++ b/modules/client_terminal/terminal.otmod @@ -3,7 +3,7 @@ Module description: Terminal for executing lua functions author: edubart website: www.otclient.info - scripts: [ terminal, commands ] + scripts: [ terminal ] sandboxed: true @onLoad: init() @onUnload: terminate() diff --git a/modules/client_terminal/terminal.otui b/modules/client_terminal/terminal.otui index 9e6945e0..ec9c01ae 100644 --- a/modules/client_terminal/terminal.otui +++ b/modules/client_terminal/terminal.otui @@ -1,7 +1,21 @@ TerminalLabel < UILabel - font: terminus-14px-bold + font: terminus-10px text-wrap: 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 id: terminalWindow @@ -10,35 +24,57 @@ UIWindow clipping: true anchors.fill: parent - Panel - id: terminalBuffer - layout: - type: verticalBox - fit-children: true + ScrollablePanel + id: terminalScrollArea focusable: false anchors.left: parent.left - anchors.right: parent.right + anchors.right: terminalScroll.left + anchors.top: parent.top anchors.bottom: commandSymbolLabel.top + vertical-scrollbar: terminalScroll + inverted-scroll: true 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 id: commandSymbolLabel - size: 12 16 + size: 12 12 fixed-size: true anchors.bottom: parent.bottom anchors.left: parent.left margin-left: 2 - font: terminus-14px-bold + font: terminus-10px text: > UITextEdit id: commandTextEdit - height: 16 + height: 12 anchors.bottom: parent.bottom anchors.left: commandSymbolLabel.right anchors.right: parent.right - margin-left: 5 - font: terminus-14px-bold + margin-left: 1 + font: terminus-10px selection-color: black selection-background-color: white diff --git a/modules/client_topmenu/topmenu.lua b/modules/client_topmenu/topmenu.lua index cd53486b..e4a06c4b 100644 --- a/modules/client_topmenu/topmenu.lua +++ b/modules/client_topmenu/topmenu.lua @@ -68,11 +68,13 @@ end function online() showGameButtons() - if g_settings.getBoolean('showPing') and (g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing)) then - pingLabel:show() - else - pingLabel:hide() - end + addEvent(function() + if modules.client_options.getOption('showPing') and (g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing)) then + pingLabel:show() + else + pingLabel:hide() + end + end) end function offline() diff --git a/modules/corelib/ui/uiminiwindowcontainer.lua b/modules/corelib/ui/uiminiwindowcontainer.lua index 7c00d67c..37cdfb7d 100644 --- a/modules/corelib/ui/uiminiwindowcontainer.lua +++ b/modules/corelib/ui/uiminiwindowcontainer.lua @@ -127,7 +127,7 @@ end function UIMiniWindowContainer:scheduleInsert(widget, index) if index - 1 > self:getChildCount() then if self.scheduledWidgets[index] then - pwarning('replacing scheduled widget id ' .. widget:getId()) + pdebug('replacing scheduled widget id ' .. widget:getId()) end self.scheduledWidgets[index] = widget else diff --git a/modules/game_console/violationwindow.otui b/modules/game_console/violationwindow.otui index 0b6c14d8..ad2df92a 100644 --- a/modules/game_console/violationwindow.otui +++ b/modules/game_console/violationwindow.otui @@ -10,6 +10,7 @@ MainWindow anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top + max-length: 255 TextEdit id: text diff --git a/modules/game_minimap/minimap.otui b/modules/game_minimap/minimap.otui index 437bb68e..fa156c7b 100644 --- a/modules/game_minimap/minimap.otui +++ b/modules/game_minimap/minimap.otui @@ -10,7 +10,7 @@ MiniWindow text: ? text-align: center 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.right: minimizeButton.left margin-right: 3 diff --git a/src/client/tile.cpp b/src/client/tile.cpp index f659729b..8daaf189 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -542,8 +542,15 @@ bool Tile::isLookPossible() bool Tile::isClickable() { + bool hasGround = false; + bool hasOnBottom = false; + bool hasIgnoreLook = false; 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 false; diff --git a/src/framework/ui/uitextedit.cpp b/src/framework/ui/uitextedit.cpp index 232da156..91b4f09f 100644 --- a/src/framework/ui/uitextedit.cpp +++ b/src/framework/ui/uitextedit.cpp @@ -41,6 +41,7 @@ UITextEdit::UITextEdit() m_maxLength = 0; m_editable = true; m_selectable = true; + m_autoScroll = false; m_changeCursorImage = true; m_selectionReference = 0; m_selectionStart = 0; @@ -164,7 +165,7 @@ void UITextEdit::update(bool focusCursor) // readjust start view area based on cursor position m_cursorInRange = false; - if(focusCursor) { + if(focusCursor && m_autoScroll) { if(m_cursorPos > 0 && textLength > 0) { assert(m_cursorPos <= textLength); 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()); else if(node->tag() == "change-cursor-image") setChangeCursorImage(node->value()); + else if(node->tag() == "auto-scroll") + setAutoScroll(node->value()); } } diff --git a/src/framework/ui/uitextedit.h b/src/framework/ui/uitextedit.h index de253d78..7a456bf9 100644 --- a/src/framework/ui/uitextedit.h +++ b/src/framework/ui/uitextedit.h @@ -51,6 +51,7 @@ public: void setSelectable(bool selectable) { m_selectable = selectable; } void setSelectionColor(const Color& color) { m_selectionColor = color; } void setSelectionBackgroundColor(const Color& color) { m_selectionBackgroundColor = color; } + void setAutoScroll(bool autoScroll) { m_autoScroll = autoScroll; } void moveCursorHorizontally(bool right); void moveCursorVertically(bool up); @@ -87,6 +88,7 @@ public: bool isMultiline() { return m_multiline; } bool isEditable() { return m_editable; } bool isSelectable() { return m_selectable; } + bool isAutoScrolling() { return m_autoScroll; } protected: void updateText(); @@ -123,6 +125,7 @@ private: std::string m_validCharacters; uint m_maxLength; bool m_updatesEnabled; + bool m_autoScroll; bool m_selectable; int m_selectionReference;