Improve multiline text selection, closes #507

This commit is contained in:
Eduardo Bart 2015-06-03 10:51:26 -03:00
parent 6893a5e98a
commit 0c1540e531
3 changed files with 76 additions and 70 deletions

View File

@ -113,13 +113,7 @@ function init()
local tab = consoleTabBar:getCurrentTab() local tab = consoleTabBar:getCurrentTab()
if not tab then return false end if not tab then return false end
local consoleBuffer = tab.tabPanel:getChildById('consoleBuffer') g_window.setClipboardText(selectioText)
if not consoleBuffer then return false end
local consoleLabel = consoleBuffer:getFocusedChild()
if not consoleLabel then return false end
g_window.setClipboardText(getSelection(consoleLabel))
return true return true
end end
@ -147,31 +141,12 @@ function init()
end end
end end
function getSelection(widget) function clearSelection(consoleBuffer)
if not widget.selection then for _,label in pairs(consoleBuffer:getChildren()) do
return widget:getSelection() label:clearSelection()
end
local text = {}
for selectionChild = widget.selection.first, widget.selection.last do
local label = widget:getParent():getChildByIndex(selectionChild)
table.insert(text, label:getSelection())
end
return table.concat(text, '\r\n')
end
function invalidateSelection(widget)
local parent = widget:getParent()
if widget.selection then
for selectionChild = widget.selection.first, widget.selection.last do
local label = parent:getChildByIndex(selectionChild)
if label ~= widget then
label:clearSelection()
end
end
widget.selection = nil
end end
consoleBuffer.selectionText = nil
consoleBuffer.selection = nil
end end
function toggleChat() function toggleChat()
@ -604,49 +579,76 @@ function addTabText(text, speaktype, tab, creatureName)
end end
label.name = creatureName label.name = creatureName
consoleBuffer.onMouseRelease = function(self, mousePos, mouseButton)
processMessageMenu(mousePos, mouseButton, nil, nil, nil, tab)
end
label.onMouseRelease = function(self, mousePos, mouseButton) label.onMouseRelease = function(self, mousePos, mouseButton)
-- TODO: regain lost selection
processMessageMenu(mousePos, mouseButton, creatureName, text, self, tab) processMessageMenu(mousePos, mouseButton, creatureName, text, self, tab)
end end
label.onFocusChange = function(self, focused, reason)
-- TODO: we are losing focus on context menu and therefore the selection
if not focused then invalidateSelection(self) end
end
label.onMousePress = function(self, mousePos, button) label.onMousePress = function(self, mousePos, button)
if button == MouseLeftButton then invalidateSelection(self) end if button == MouseLeftButton then clearSelection(consoleBuffer) end
end end
label.onMouseMove = function(self, mousePos, mouseMoved) label.onDragEnter = function(self, mousePos)
if self:isPressed() then clearSelection(consoleBuffer)
local parent = self:getParent() return true
local selfIndex = parent:getChildIndex(self) end
local child = parent:getChildByPos(mousePos) label.onDragLeave = function(self, droppedWidget, mousePos)
local childIndex = parent:getChildIndex(child) local text = {}
for selectionChild = consoleBuffer.selection.first, consoleBuffer.selection.last do
local label = self:getParent():getChildByIndex(selectionChild)
table.insert(text, label:getSelection())
end
consoleBuffer.selectionText = table.concat(text, '\r\n')
return true
end
label.onDragMove = function(self, mousePos, mouseMoved)
local parent = self:getParent()
local selfIndex = parent:getChildIndex(self)
local child = parent:getChildByPos(mousePos)
-- remove old selection -- find out bounds children
invalidateSelection(self) if not child then
if mousePos.y >= parent:getLastChild():getY() then
-- choose new selection child = parent:getLastChild()
if child and child ~= self then elseif mousePos.y <= parent:getFirstChild():getY() then
self.selection = {first = math.min(selfIndex, childIndex), last = math.max(selfIndex, childIndex)} child = parent:getFirstChild()
for selectionChild = self.selection.first + 1, self.selection.last - 1 do
parent:getChildByIndex(selectionChild):selectAll()
end
local textPos = child:getTextPos(mousePos)
if childIndex > selfIndex then
child:setSelection(0, textPos)
else
child:setSelection(string.len(child:getText()), textPos)
end
elseif not child then
-- TODO: out of bonding rect selection
end end
end end
if not child then return false end
local childIndex = parent:getChildIndex(child)
-- remove old selection
clearSelection(consoleBuffer)
-- update self selection
local textBegin = self:getTextPos(self:getLastClickPosition())
local textPos = self:getTextPos(mousePos)
self:setSelection(textBegin, textPos)
consoleBuffer.selection = { first = math.min(selfIndex, childIndex), last = math.max(selfIndex, childIndex) }
-- update siblings selection
if child ~= self then
for selectionChild = consoleBuffer.selection.first + 1, consoleBuffer.selection.last - 1 do
parent:getChildByIndex(selectionChild):selectAll()
end
local textPos = child:getTextPos(mousePos)
if childIndex > selfIndex then
child:setSelection(0, textPos)
else
child:setSelection(string.len(child:getText()), textPos)
end
end
return true
end end
if consoleBuffer:getChildCount() > MAX_LINES then if consoleBuffer:getChildCount() > MAX_LINES then
local child = consoleBuffer:getFirstChild() local child = consoleBuffer:getFirstChild()
if child.selection then invalidateSelection(child) end clearSelection(consoleBuffer)
child:destroy() child:destroy()
end end
end end
@ -709,13 +711,15 @@ function processMessageMenu(mousePos, mouseButton, creatureName, text, label, ta
menu:addOption(tr('Copy name'), function () g_window.setClipboardText(creatureName) end) menu:addOption(tr('Copy name'), function () g_window.setClipboardText(creatureName) end)
end end
local selectedText = getSelection(label) local selection = tab.tabPanel:getChildById('consoleBuffer').selectionText
if #selectedText > 0 then if selection and #selection > 0 then
menu:addOption(tr('Copy'), function() g_window.setClipboardText(selectedText) end, '(Ctrl+C)') menu:addOption(tr('Copy'), function() g_window.setClipboardText(selection) end, '(Ctrl+C)')
end end
menu:addOption(tr('Copy message'), function() g_window.setClipboardText(text) end) if text then
menu:addOption(tr('Select all'), function() label:selectAll() end) menu:addOption(tr('Copy message'), function() g_window.setClipboardText(text) end)
if tab.violations then end
--menu:addOption(tr('Select all'), function() label:selectAll() end)
if tab.violations and creatureName then
menu:addSeparator() menu:addSeparator()
menu:addOption(tr('Process') .. ' ' .. creatureName, function() processViolation(creatureName, text) end) menu:addOption(tr('Process') .. ' ' .. creatureName, function() processViolation(creatureName, text) end)
menu:addOption(tr('Remove') .. ' ' .. creatureName, function() g_game.closeRuleViolation(creatureName) end) menu:addOption(tr('Remove') .. ' ' .. creatureName, function() g_game.closeRuleViolation(creatureName) end)

View File

@ -10,6 +10,8 @@ ConsoleLabel < UITextEdit
change-cursor-image: false change-cursor-image: false
cursor-visible: false cursor-visible: false
editable: false editable: false
draggable: true
selectable: false
ConsolePhantomLabel < UILabel ConsolePhantomLabel < UILabel
font: verdana-11px-antialised font: verdana-11px-antialised

View File

@ -659,7 +659,7 @@ void UITextEdit::onFocusChange(bool focused, Fw::FocusReason reason)
else else
blinkCursor(); blinkCursor();
update(true); update(true);
} else } else if(m_selectable)
clearSelection(); clearSelection();
UIWidget::onFocusChange(focused, reason); UIWidget::onFocusChange(focused, reason);
} }