mirror of
https://github.com/edubart/otclient.git
synced 2025-10-15 03:54:54 +02:00
Reimplement text edit scrolling in C++
* And update some corelib APIs
This commit is contained in:
@@ -23,46 +23,6 @@ function destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function getCursorPosByNewLine(str, count)
|
||||
if count <= 1 then return 0 end
|
||||
|
||||
local i = 0
|
||||
for n = 1, count-1 do
|
||||
local tPos = string.find(str, '\n', i)
|
||||
if tPos then
|
||||
i = tPos+1
|
||||
end
|
||||
end
|
||||
|
||||
return i - 1
|
||||
end
|
||||
|
||||
function getLineByCursorPos(str, pos, maxLine)
|
||||
for i = 1, maxLine do
|
||||
if pos <= getCursorPosByNewLine(str, i) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
return maxLine + 1
|
||||
end
|
||||
|
||||
|
||||
function getLineSizeByCursorPos(str, pos, maxLine)
|
||||
for i = 1, maxLine + 1 do
|
||||
if pos < getCursorPosByNewLine(str, i) then
|
||||
return {minPos = getCursorPosByNewLine(str, i-1), maxPos = (getCursorPosByNewLine(str, i) - 1)}
|
||||
end
|
||||
end
|
||||
|
||||
return {minPos = getCursorPosByNewLine(str, maxLine + 1), maxPos = str:len()}
|
||||
end
|
||||
|
||||
function string.count(str, pattern)
|
||||
local _, _count = string.gsub(str, pattern, pattern)
|
||||
return _count
|
||||
end
|
||||
|
||||
function onGameEditText(id, itemId, maxLength, text, writter, time)
|
||||
if textWindow then return end
|
||||
textWindow = g_ui.createWidget('TextWindow', rootWidget)
|
||||
@@ -118,82 +78,14 @@ function onGameEditText(id, itemId, maxLength, text, writter, time)
|
||||
end
|
||||
destroy()
|
||||
end
|
||||
|
||||
local newLineCount = string.count(textEdit:getText(), '\n')
|
||||
if newLineCount >= 9 then
|
||||
textScroll:setMaximum(newLineCount-9)
|
||||
end
|
||||
|
||||
local _prev, _next = 0, 11
|
||||
local scrollOnValueChange = function(widget, value, delta)
|
||||
local line = getLineByCursorPos(textEdit:getText(), textEdit:getCursorPos(), newLineCount)
|
||||
if delta > 0 then
|
||||
textEdit:setCursorPos(getCursorPosByNewLine(textEdit:getText(), _next + delta - 1))
|
||||
if writeable then textEdit:setCursorPos(getCursorPosByNewLine(textEdit:getText(), line + delta)) end
|
||||
else
|
||||
textEdit:setCursorPos(getCursorPosByNewLine(textEdit:getText(), _prev + delta + 1) - 1)
|
||||
if writeable then textEdit:setCursorPos(getCursorPosByNewLine(textEdit:getText(), line + delta)) end
|
||||
end
|
||||
|
||||
_next = _next + delta
|
||||
_prev = _prev + delta
|
||||
end
|
||||
|
||||
textScroll.onValueChange = scrollOnValueChange
|
||||
|
||||
local navigateVertical = function(up) -- Pressing Up / Down when scrollbar is at min / max value
|
||||
local line = getLineByCursorPos(textEdit:getText(), textEdit:getCursorPos(), newLineCount)
|
||||
if up and textScroll:getValue() == textScroll:getMinimum() then
|
||||
textEdit:setCursorPos(getCursorPosByNewLine(textEdit:getText(), line - 1))
|
||||
elseif not up and textScroll:getValue() == textScroll:getMaximum() then
|
||||
textEdit:setCursorPos(getCursorPosByNewLine(textEdit:getText(), line + 1))
|
||||
end
|
||||
end
|
||||
|
||||
local navigateHorizontal = function(right) -- Pressing Left / Right to navigate in a line
|
||||
local currentCursor = textEdit:getCursorPos()
|
||||
local lineSize = getLineSizeByCursorPos(textEdit:getText(), currentCursor, newLineCount)
|
||||
if right and currentCursor < lineSize.maxPos then
|
||||
textEdit:setCursorPos(currentCursor+1)
|
||||
elseif not right and currentCursor > lineSize.minPos then
|
||||
textEdit:setCursorPos(currentCursor-1)
|
||||
end
|
||||
end
|
||||
|
||||
local onKeyPress = function(widget, keyCode, keyModifiers)
|
||||
if keyModifiers ~= 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
if keyCode == 16 or keyCode == 17 then -- Left / Right
|
||||
navigateHorizontal((keyCode == 17))
|
||||
return true
|
||||
elseif keyCode == 14 or keyCode == 15 then -- Up / Down
|
||||
local up = (keyCode == 14)
|
||||
navigateVertical(up)
|
||||
|
||||
if up then
|
||||
textScroll:setValue(textScroll:getValue() - 1)
|
||||
else
|
||||
textScroll:setValue(textScroll:getValue() + 1)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
if not writeable then
|
||||
textEdit:setCursorPos(0)
|
||||
textWindow.onKeyPress = onKeyPress -- textEdit won't receive focus
|
||||
else
|
||||
textScroll:setValue(textScroll:getMaximum())
|
||||
textEdit:setCursorPos(text:len())
|
||||
textEdit.onKeyPress = onKeyPress
|
||||
end
|
||||
|
||||
okButton.onClick = doneFunc
|
||||
cancelButton.onClick = destroy
|
||||
--textWindow.onEnter = doneFunc -- this should be '\n'
|
||||
|
||||
if not writeable then
|
||||
textWindow.onEnter = doneFunc
|
||||
end
|
||||
|
||||
textWindow.onEscape = destroy
|
||||
end
|
||||
|
||||
@@ -222,28 +114,3 @@ function onGameEditList(id, doorId, text)
|
||||
textWindow.onEscape = destroy
|
||||
end
|
||||
|
||||
|
||||
function onGameEditList(id, doorId, text)
|
||||
if textWindow then return end
|
||||
textWindow = g_ui.createWidget('TextWindow', rootWidget)
|
||||
|
||||
local textEdit = textWindow:getChildById('text')
|
||||
local description = textWindow:getChildById('description')
|
||||
local okButton = textWindow:getChildById('okButton')
|
||||
local cancelButton = textWindow:getChildById('cancelButton')
|
||||
|
||||
textEdit:setMaxLength(8192)
|
||||
textEdit:setText(text)
|
||||
textEdit:setEnabled(true)
|
||||
description:setText(tr('Enter one name per line.'))
|
||||
textWindow:setText(tr('Edit List'))
|
||||
|
||||
doneFunc = function()
|
||||
g_game.editList(id, doorId, textEdit:getText())
|
||||
destroy()
|
||||
end
|
||||
|
||||
okButton.onClick = doneFunc
|
||||
textWindow.onEnter = doneFunc
|
||||
textWindow.onEscape = destroy
|
||||
end
|
||||
|
@@ -1,12 +1,10 @@
|
||||
TextWindow < MainWindow
|
||||
id: textWindow
|
||||
size: 280 280
|
||||
@onEscape: self:destroy()
|
||||
size: 300 280
|
||||
|
||||
UIItem
|
||||
Item
|
||||
id: textItem
|
||||
virtual: true
|
||||
size: 32 32
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
|
||||
@@ -15,43 +13,40 @@ TextWindow < MainWindow
|
||||
anchors.top: parent.top
|
||||
anchors.left: textItem.right
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: text.top
|
||||
text-align: left
|
||||
margin-left: 8
|
||||
margin-bottom: 10
|
||||
text-auto-resize: true
|
||||
text-align: left
|
||||
text-wrap: true
|
||||
|
||||
MultilineTextEdit
|
||||
id: text
|
||||
anchors.fill: parent
|
||||
anchors.top: textItem.bottom
|
||||
margin-right: 10
|
||||
margin-top: 30
|
||||
margin-bottom: 30
|
||||
anchors.top: textScroll.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: textScroll.left
|
||||
anchors.bottom: textScroll.bottom
|
||||
vertical-scrollbar: textScroll
|
||||
|
||||
VerticalScrollBar
|
||||
id: textScroll
|
||||
anchors.left: prev.right
|
||||
anchors.top: prev.top
|
||||
anchors.bottom: prev.bottom
|
||||
minimum: 0
|
||||
maximum: 0
|
||||
step: 1
|
||||
value: 0
|
||||
anchors.top: description.bottom
|
||||
anchors.bottom: okButton.top
|
||||
anchors.right: parent.right
|
||||
margin-top: 10
|
||||
margin-bottom: 10
|
||||
step: 16
|
||||
pixels-scroll: true
|
||||
|
||||
Button
|
||||
id: cancelButton
|
||||
!text: tr('Cancel')
|
||||
anchors.top: next.top
|
||||
anchors.right: next.left
|
||||
margin-right: 8
|
||||
width: 60
|
||||
@onClick: self:getParent():destroy()
|
||||
|
||||
Button
|
||||
id: okButton
|
||||
!text: tr('Ok')
|
||||
anchors.top: text.bottom
|
||||
anchors.right: text.right
|
||||
margin-top: 10
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: next.left
|
||||
margin-right: 10
|
||||
width: 60
|
||||
|
||||
Button
|
||||
id: cancelButton
|
||||
!text: tr('Cancel')
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
width: 60
|
||||
|
Reference in New Issue
Block a user