Reimplement text edit scrolling in C++
* And update some corelib APIs
This commit is contained in:
parent
a3fcf2e8e7
commit
2e75380218
|
@ -10,7 +10,6 @@ FlatLabel < UILabel
|
||||||
color: #aaaaaa
|
color: #aaaaaa
|
||||||
size: 86 20
|
size: 86 20
|
||||||
text-offset: 3 3
|
text-offset: 3 3
|
||||||
text-margin: 3
|
|
||||||
image-source: /images/panel_flat.png
|
image-source: /images/panel_flat.png
|
||||||
image-border: 1
|
image-border: 1
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ TextEdit < UITextEdit
|
||||||
color: #aaaaaa
|
color: #aaaaaa
|
||||||
size: 86 20
|
size: 86 20
|
||||||
text-offset: 0 3
|
text-offset: 0 3
|
||||||
text-margin: 3
|
padding: 3
|
||||||
image-source: /images/textedit.png
|
image-source: /images/textedit.png
|
||||||
image-border: 1
|
image-border: 1
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,11 @@ KeyCodeDescs = {
|
||||||
|
|
||||||
NetworkMessageTypes = {
|
NetworkMessageTypes = {
|
||||||
Boolean = 1,
|
Boolean = 1,
|
||||||
Number = 2,
|
U8 = 2,
|
||||||
String = 3,
|
U16 = 3,
|
||||||
Table = 4
|
U32 = 4,
|
||||||
|
U64 = 5,
|
||||||
|
NumberString = 6,
|
||||||
|
String = 7,
|
||||||
|
Table = 8
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,16 @@ function InputMessage:getData()
|
||||||
local dataType = self:getU8()
|
local dataType = self:getU8()
|
||||||
if dataType == NetworkMessageTypes.Boolean then
|
if dataType == NetworkMessageTypes.Boolean then
|
||||||
return numbertoboolean(self:getU8())
|
return numbertoboolean(self:getU8())
|
||||||
elseif dataType == NetworkMessageTypes.Number then
|
elseif dataType == NetworkMessageTypes.U8 then
|
||||||
|
return self:getU8()
|
||||||
|
elseif dataType == NetworkMessageTypes.U16 then
|
||||||
|
return self:getU16()
|
||||||
|
elseif dataType == NetworkMessageTypes.U32 then
|
||||||
|
return self:getU32()
|
||||||
|
elseif dataType == NetworkMessageTypes.U64 then
|
||||||
return self:getU64()
|
return self:getU64()
|
||||||
|
elseif dataType == NetworkMessageTypes.NumberString then
|
||||||
|
return tonumber(self:getString())
|
||||||
elseif dataType == NetworkMessageTypes.String then
|
elseif dataType == NetworkMessageTypes.String then
|
||||||
return self:getString()
|
return self:getString()
|
||||||
elseif dataType == NetworkMessageTypes.Table then
|
elseif dataType == NetworkMessageTypes.Table then
|
||||||
|
@ -16,7 +24,7 @@ end
|
||||||
|
|
||||||
function InputMessage:getTable()
|
function InputMessage:getTable()
|
||||||
local ret = {}
|
local ret = {}
|
||||||
local size = self:getU32()
|
local size = self:getU16()
|
||||||
for i=1,size do
|
for i=1,size do
|
||||||
local index = self:getData()
|
local index = self:getData()
|
||||||
local value = self:getData()
|
local value = self:getData()
|
||||||
|
@ -24,3 +32,12 @@ function InputMessage:getTable()
|
||||||
end
|
end
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function InputMessage:getColor()
|
||||||
|
local color = {}
|
||||||
|
color.r = msg:getU8()
|
||||||
|
color.g = msg:getU8()
|
||||||
|
color.b = msg:getU8()
|
||||||
|
color.a = msg:getU8()
|
||||||
|
return color
|
||||||
|
end
|
||||||
|
|
|
@ -24,3 +24,10 @@ function g_mouse.bindPressMove(widget, callback)
|
||||||
return true
|
return true
|
||||||
end })
|
end })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function g_mouse.bindPress(widget, callback)
|
||||||
|
connect(widget, { onMousePress = function(widget, mousePos, mouseButton)
|
||||||
|
callback(mousePos, mouseButton)
|
||||||
|
return true
|
||||||
|
end })
|
||||||
|
end
|
||||||
|
|
|
@ -3,8 +3,22 @@ function OutputMessage:addData(data)
|
||||||
self:addU8(NetworkMessageTypes.Boolean)
|
self:addU8(NetworkMessageTypes.Boolean)
|
||||||
self:addU8(booleantonumber(data))
|
self:addU8(booleantonumber(data))
|
||||||
elseif type(data) == 'number' then
|
elseif type(data) == 'number' then
|
||||||
self:addU8(NetworkMessageTypes.Number)
|
if math.isu8(data) then
|
||||||
|
self:addU8(NetworkMessageTypes.U8)
|
||||||
|
self:addU8(data)
|
||||||
|
elseif math.isu16(data) then
|
||||||
|
self:addU8(NetworkMessageTypes.U16)
|
||||||
|
self:addU16(data)
|
||||||
|
elseif math.isu32(data) then
|
||||||
|
self:addU8(NetworkMessageTypes.U32)
|
||||||
|
self:addU32(data)
|
||||||
|
elseif math.isu64(data) then
|
||||||
|
self:addU8(NetworkMessageTypes.U64)
|
||||||
self:addU64(data)
|
self:addU64(data)
|
||||||
|
else -- negative or non integer numbers
|
||||||
|
self:addU8(NetworkMessageTypes.NumberString)
|
||||||
|
self:addString(tostring(data))
|
||||||
|
end
|
||||||
elseif type(data) == 'string' then
|
elseif type(data) == 'string' then
|
||||||
self:addU8(NetworkMessageTypes.String)
|
self:addU8(NetworkMessageTypes.String)
|
||||||
self:addString(data)
|
self:addString(data)
|
||||||
|
@ -19,9 +33,9 @@ end
|
||||||
function OutputMessage:addTable(data)
|
function OutputMessage:addTable(data)
|
||||||
local size = 0
|
local size = 0
|
||||||
|
|
||||||
-- reserve for size
|
-- reserve for size (should be addData, find a way to use it further)
|
||||||
local sizePos = self:getWritePos()
|
local sizePos = self:getWritePos()
|
||||||
self:addU32(size)
|
self:addU16(size)
|
||||||
local sizeSize = self:getWritePos() - sizePos
|
local sizeSize = self:getWritePos() - sizePos
|
||||||
|
|
||||||
-- add values
|
-- add values
|
||||||
|
@ -34,9 +48,16 @@ function OutputMessage:addTable(data)
|
||||||
-- write size
|
-- write size
|
||||||
local currentPos = self:getWritePos()
|
local currentPos = self:getWritePos()
|
||||||
self:setWritePos(sizePos)
|
self:setWritePos(sizePos)
|
||||||
self:addU32(size)
|
self:addU16(size)
|
||||||
|
|
||||||
-- fix msg size and go back to end
|
-- fix msg size and go back to end
|
||||||
self:setMessageSize(self:getMessageSize() - sizeSize)
|
self:setMessageSize(self:getMessageSize() - sizeSize)
|
||||||
self:setWritePos(currentPos)
|
self:setWritePos(currentPos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function OutputMessage:addColor(color)
|
||||||
|
self:addU8(color.r)
|
||||||
|
self:addU8(color.g)
|
||||||
|
self:addU8(color.b)
|
||||||
|
self:addU8(color.a)
|
||||||
|
end
|
||||||
|
|
|
@ -93,6 +93,24 @@ function table.empty(t)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function table.permute(t, n, count)
|
||||||
|
n = n or #t
|
||||||
|
for i=1,count or n do
|
||||||
|
local j = math.random(i, n)
|
||||||
|
t[i], t[j] = t[j], t[i]
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.findbyfield(t, fieldname, fieldvalue)
|
||||||
|
for _i,subt in pairs(t) do
|
||||||
|
if subt[fieldname] == fieldvalue then
|
||||||
|
return subt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
function table.toString(t)
|
function table.toString(t)
|
||||||
local maxn = #t
|
local maxn = #t
|
||||||
local str = ""
|
local str = ""
|
||||||
|
|
|
@ -12,7 +12,7 @@ local function moveToolTip(first)
|
||||||
local pos = g_window.getMousePosition()
|
local pos = g_window.getMousePosition()
|
||||||
pos.y = pos.y + 1
|
pos.y = pos.y + 1
|
||||||
local xdif = g_window.getSize().width - (pos.x + toolTipLabel:getWidth())
|
local xdif = g_window.getSize().width - (pos.x + toolTipLabel:getWidth())
|
||||||
if xdif < 2 then
|
if xdif < 10 then
|
||||||
pos.x = pos.x - toolTipLabel:getWidth() - 3
|
pos.x = pos.x - toolTipLabel:getWidth() - 3
|
||||||
else
|
else
|
||||||
pos.x = pos.x + 10
|
pos.x = pos.x + 10
|
||||||
|
|
|
@ -3,6 +3,7 @@ UIComboBox = extends(UIWidget)
|
||||||
|
|
||||||
function UIComboBox.create()
|
function UIComboBox.create()
|
||||||
local combobox = UIComboBox.internalCreate()
|
local combobox = UIComboBox.internalCreate()
|
||||||
|
combobox:setFocusable(false)
|
||||||
combobox.options = {}
|
combobox.options = {}
|
||||||
combobox.currentIndex = -1
|
combobox.currentIndex = -1
|
||||||
combobox.mouseScroll = true
|
combobox.mouseScroll = true
|
||||||
|
@ -15,6 +16,15 @@ function UIComboBox:clearOptions()
|
||||||
self:clearText()
|
self:clearText()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function UIComboBox:getOption(text)
|
||||||
|
if not self.options then return nil end
|
||||||
|
for i,v in ipairs(self.options) do
|
||||||
|
if v.text == text then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function UIComboBox:setCurrentOption(text)
|
function UIComboBox:setCurrentOption(text)
|
||||||
if not self.options then return end
|
if not self.options then return end
|
||||||
for i,v in ipairs(self.options) do
|
for i,v in ipairs(self.options) do
|
||||||
|
@ -27,6 +37,18 @@ function UIComboBox:setCurrentOption(text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function UIComboBox:setCurrentOptionByData(data)
|
||||||
|
if not self.options then return end
|
||||||
|
for i,v in ipairs(self.options) do
|
||||||
|
if v.data == data and self.currentIndex ~= i then
|
||||||
|
self.currentIndex = i
|
||||||
|
self:setText(v.text)
|
||||||
|
self:onOptionChange(v.text, v.data)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function UIComboBox:setCurrentIndex(index)
|
function UIComboBox:setCurrentIndex(index)
|
||||||
if index >= 1 and index <= #self.options then
|
if index >= 1 and index <= #self.options then
|
||||||
local v = self.options[index]
|
local v = self.options[index]
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
if not UIWindow then dofile 'uiwindow' end
|
||||||
|
|
||||||
|
-- @docclass
|
||||||
|
UIInputBox = extends(UIWindow)
|
||||||
|
|
||||||
|
function UIInputBox.create(title, okCallback, cancelCallback)
|
||||||
|
local inputBox = UIInputBox.internalCreate()
|
||||||
|
|
||||||
|
inputBox:setText(title)
|
||||||
|
inputBox.inputs = {}
|
||||||
|
inputBox.onEnter = function()
|
||||||
|
local results = {}
|
||||||
|
for _,func in pairs(inputBox.inputs) do
|
||||||
|
table.insert(results, func())
|
||||||
|
end
|
||||||
|
okCallback(unpack(results))
|
||||||
|
inputBox:destroy()
|
||||||
|
end
|
||||||
|
inputBox.onEscape = function()
|
||||||
|
if cancelCallback then
|
||||||
|
cancelCallback()
|
||||||
|
end
|
||||||
|
inputBox:destroy()
|
||||||
|
end
|
||||||
|
|
||||||
|
return inputBox
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIInputBox:addLabel(text)
|
||||||
|
local label = g_ui.createWidget('InputBoxLabel', self)
|
||||||
|
label:setText(text)
|
||||||
|
return label
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIInputBox:addLineEdit(labelText, defaultText, maxLength)
|
||||||
|
if labelText then self:addLabel(labelText) end
|
||||||
|
local lineEdit = g_ui.createWidget('InputBoxLineEdit', self)
|
||||||
|
if defaultText then lineEdit:setText(defaultText) end
|
||||||
|
if maxLength then lineEdit:setMaxLength(maxLength) end
|
||||||
|
table.insert(self.inputs, function() return lineEdit:getText() end)
|
||||||
|
return lineEdit
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIInputBox:addTextEdit(labelText, defaultText, maxLength, visibleLines)
|
||||||
|
if labelText then self:addLabel(labelText) end
|
||||||
|
local textEdit = g_ui.createWidget('InputBoxTextEdit', self)
|
||||||
|
if defaultText then textEdit:setText(defaultText) end
|
||||||
|
if maxLength then textEdit:setMaxLength(maxLength) end
|
||||||
|
visibleLines = visibleLines or 1
|
||||||
|
textEdit:setHeight(textEdit:getHeight() * visibleLines)
|
||||||
|
table.insert(self.inputs, function() return textEdit:getText() end)
|
||||||
|
return textEdit
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIInputBox:addCheckBox(text, checked)
|
||||||
|
local checkBox = g_ui.createWidget('InputBoxCheckBox', self)
|
||||||
|
checkBox:setText(text)
|
||||||
|
checkBox:setChecked(checked)
|
||||||
|
table.insert(self.inputs, function() return checkBox:isChecked() end)
|
||||||
|
return checkBox
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIInputBox:addComboBox(labelText, ...)
|
||||||
|
if labelText then self:addLabel(labelText) end
|
||||||
|
local comboBox = g_ui.createWidget('InputBoxComboBox', self)
|
||||||
|
local options = {...}
|
||||||
|
for i=1,#options do
|
||||||
|
comboBox:addOption(options[i])
|
||||||
|
end
|
||||||
|
table.insert(self.inputs, function() return comboBox:getCurrentOption() end)
|
||||||
|
return comboBox
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIInputBox:addSpinBox(labelText, minimum, maximum, value, step)
|
||||||
|
if labelText then self:addLabel(labelText) end
|
||||||
|
local spinBox = g_ui.createWidget('InputBoxSpinBox', self)
|
||||||
|
spinBox:setMinimum(minimum)
|
||||||
|
spinBox:setMaximum(maximum)
|
||||||
|
spinBox:setValue(value)
|
||||||
|
spinBox:setStep(step)
|
||||||
|
table.insert(self.inputs, function() return spinBox:getValue() end)
|
||||||
|
return spinBox
|
||||||
|
end
|
||||||
|
|
||||||
|
function UIInputBox:display(okButtonText, cancelButtonText)
|
||||||
|
okButtonText = okButtonText or tr('Ok')
|
||||||
|
cancelButtonText = cancelButtonText or tr('Cancel')
|
||||||
|
|
||||||
|
local buttonsWidget = g_ui.createWidget('InputBoxButtonsPanel', self)
|
||||||
|
local okButton = g_ui.createWidget('InputBoxButton', buttonsWidget)
|
||||||
|
okButton:setText(okButtonText)
|
||||||
|
okButton.onClick = self.onEnter
|
||||||
|
|
||||||
|
local cancelButton = g_ui.createWidget('InputBoxButton', buttonsWidget)
|
||||||
|
cancelButton:setText(cancelButtonText)
|
||||||
|
cancelButton.onClick = self.onEscape
|
||||||
|
|
||||||
|
buttonsWidget:setHeight(okButton:getHeight())
|
||||||
|
|
||||||
|
rootWidget:addChild(self)
|
||||||
|
self:setStyle('InputBoxWindow')
|
||||||
|
end
|
||||||
|
|
||||||
|
function displayTextInputBox(title, label, okCallback, cancelCallback)
|
||||||
|
local inputBox = UIInputBox.create(title, okCallback, cancelCallback)
|
||||||
|
inputBox:addLineEdit(label)
|
||||||
|
inputBox:display()
|
||||||
|
end
|
||||||
|
|
||||||
|
function displayNumberInputBox(title, label, okCallback, cancelCallback, min, max, value, step)
|
||||||
|
local inputBox = UIInputBox.create(title, okCallback, cancelCallback)
|
||||||
|
inputBox:addSpinBox(label, min, max, value, step)
|
||||||
|
inputBox:display()
|
||||||
|
end
|
|
@ -22,10 +22,14 @@ function UIPopupMenu:display(pos)
|
||||||
currentMenu:destroy()
|
currentMenu:destroy()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if pos == nil then
|
||||||
|
pos = g_window.getMousePosition()
|
||||||
|
end
|
||||||
|
|
||||||
rootWidget:addChild(self)
|
rootWidget:addChild(self)
|
||||||
self:setPosition(pos)
|
self:setPosition(pos)
|
||||||
self:grabMouse()
|
self:grabMouse()
|
||||||
self:grabKeyboard()
|
--self:grabKeyboard()
|
||||||
currentMenu = self
|
currentMenu = self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,10 @@ function UIProgressBar.create()
|
||||||
progressbar:setFocusable(false)
|
progressbar:setFocusable(false)
|
||||||
progressbar:setPhantom(true)
|
progressbar:setPhantom(true)
|
||||||
progressbar.percent = 0
|
progressbar.percent = 0
|
||||||
|
progressbar.bgBorderLeft = 0
|
||||||
|
progressbar.bgBorderRight = 0
|
||||||
|
progressbar.bgBorderTop = 0
|
||||||
|
progressbar.bgBorderBottom = 0
|
||||||
progressbar:updateBackground()
|
progressbar:updateBackground()
|
||||||
return progressbar
|
return progressbar
|
||||||
end
|
end
|
||||||
|
@ -25,11 +29,30 @@ function UIProgressBar:getPercentPixels()
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIProgressBar:updateBackground()
|
function UIProgressBar:updateBackground()
|
||||||
local width = math.round(math.max((self.percent * self:getWidth())/100, 1))
|
local width = math.round(math.max((self.percent * (self:getWidth() - self.bgBorderLeft - self.bgBorderRight))/100, 1))
|
||||||
local height = self:getHeight()
|
local height = self:getHeight() - self.bgBorderTop - self.bgBorderBottom
|
||||||
self:setBackgroundSize({width=width, height=height})
|
local rect = { x = self.bgBorderLeft, y = self.bgBorderTop, width = width, height = height }
|
||||||
|
self:setBackgroundRect(rect)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function UIProgressBar:onStyleApply(name, node)
|
||||||
|
for name,value in pairs(node) do
|
||||||
|
if name == 'background-border-left' then
|
||||||
|
self.bgBorderLeft = tonumber(value)
|
||||||
|
elseif name == 'background-border-right' then
|
||||||
|
self.bgBorderRight = tonumber(value)
|
||||||
|
elseif name == 'background-border-top' then
|
||||||
|
self.bgBorderTop = tonumber(value)
|
||||||
|
elseif name == 'background-border-bottom' then
|
||||||
|
self.bgBorderBottom = tonumber(value)
|
||||||
|
elseif name == 'background-border' then
|
||||||
|
self.bgBorderLeft = tonumber(value)
|
||||||
|
self.bgBorderRight = tonumber(value)
|
||||||
|
self.bgBorderTop = tonumber(value)
|
||||||
|
self.bgBorderBottom = tonumber(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function UIProgressBar:onGeometryChange(oldRect, newRect)
|
function UIProgressBar:onGeometryChange(oldRect, newRect)
|
||||||
self:updateBackground()
|
self:updateBackground()
|
||||||
|
|
|
@ -3,11 +3,14 @@ UISpinBox = extends(UITextEdit)
|
||||||
|
|
||||||
function UISpinBox.create()
|
function UISpinBox.create()
|
||||||
local spinbox = UISpinBox.internalCreate()
|
local spinbox = UISpinBox.internalCreate()
|
||||||
|
spinbox:setFocusable(false)
|
||||||
spinbox:setValidCharacters('0123456789')
|
spinbox:setValidCharacters('0123456789')
|
||||||
spinbox.displayButtons = true
|
spinbox.displayButtons = true
|
||||||
spinbox.minimum = 0
|
spinbox.minimum = 0
|
||||||
spinbox.maximum = 0
|
spinbox.maximum = 0
|
||||||
spinbox.value = 0
|
spinbox.value = 0
|
||||||
|
spinbox.step = 1
|
||||||
|
spinbox.firstchange = true
|
||||||
spinbox:setText("0")
|
spinbox:setText("0")
|
||||||
return spinbox
|
return spinbox
|
||||||
end
|
end
|
||||||
|
@ -21,6 +24,14 @@ function UISpinBox:onMouseWheel(mousePos, direction)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function UISpinBox:onKeyPress()
|
||||||
|
if self.firstchange then
|
||||||
|
self.firstchange = false
|
||||||
|
self:setText('')
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
function UISpinBox:onTextChange(text, oldText)
|
function UISpinBox:onTextChange(text, oldText)
|
||||||
if text:len() == 0 then
|
if text:len() == 0 then
|
||||||
self:setValue(self.minimum)
|
self:setValue(self.minimum)
|
||||||
|
@ -79,14 +90,15 @@ function UISpinBox:hideButtons()
|
||||||
end
|
end
|
||||||
|
|
||||||
function UISpinBox:up()
|
function UISpinBox:up()
|
||||||
self:setValue(self.value + 1)
|
self:setValue(self.value + self.step)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UISpinBox:down()
|
function UISpinBox:down()
|
||||||
self:setValue(self.value - 1)
|
self:setValue(self.value - self.step)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UISpinBox:setValue(value)
|
function UISpinBox:setValue(value)
|
||||||
|
value = value or 0
|
||||||
value = math.max(math.min(self.maximum, value), self.minimum)
|
value = math.max(math.min(self.maximum, value), self.minimum)
|
||||||
if value == self.value then return end
|
if value == self.value then return end
|
||||||
if self:getText():len() > 0 then
|
if self:getText():len() > 0 then
|
||||||
|
@ -107,6 +119,7 @@ function UISpinBox:setValue(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UISpinBox:setMinimum(minimum)
|
function UISpinBox:setMinimum(minimum)
|
||||||
|
minimum = minimum or -9223372036854775808
|
||||||
self.minimum = minimum
|
self.minimum = minimum
|
||||||
if self.minimum > self.maximum then
|
if self.minimum > self.maximum then
|
||||||
self.maximum = self.minimum
|
self.maximum = self.minimum
|
||||||
|
@ -117,12 +130,17 @@ function UISpinBox:setMinimum(minimum)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UISpinBox:setMaximum(maximum)
|
function UISpinBox:setMaximum(maximum)
|
||||||
|
maximum = maximum or 9223372036854775807
|
||||||
self.maximum = maximum
|
self.maximum = maximum
|
||||||
if self.value > maximum then
|
if self.value > maximum then
|
||||||
self:setValue(maximum)
|
self:setValue(maximum)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function UISpinBox:setStep(step)
|
||||||
|
self.step = step or 1
|
||||||
|
end
|
||||||
|
|
||||||
function UISpinBox:getValue()
|
function UISpinBox:getValue()
|
||||||
return self.value
|
return self.value
|
||||||
end
|
end
|
||||||
|
|
|
@ -193,6 +193,9 @@ function UITabBar:selectTab(tab)
|
||||||
tab:setChecked(true)
|
tab:setChecked(true)
|
||||||
tab:setOn(false)
|
tab:setOn(false)
|
||||||
tab.blinking = false
|
tab.blinking = false
|
||||||
|
|
||||||
|
local parent = tab:getParent()
|
||||||
|
parent:focusChild(tab, MouseFocusReason)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UITabBar:selectNextTab()
|
function UITabBar:selectNextTab()
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
function UITextEdit:onStyleApply(styleName, styleNode)
|
||||||
|
for name,value in pairs(styleNode) do
|
||||||
|
if name == 'vertical-scrollbar' then
|
||||||
|
addEvent(function()
|
||||||
|
self:setVerticalScrollBar(self:getParent():getChildById(value))
|
||||||
|
end)
|
||||||
|
elseif name == 'horizontal-scrollbar' then
|
||||||
|
addEvent(function()
|
||||||
|
self:setHorizontalScrollBar(self:getParent():getChildById(value))
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UITextEdit:onMouseWheel(mousePos, mouseWheel)
|
||||||
|
if self.verticalScrollBar and self:isMultiline() then
|
||||||
|
if mouseWheel == MouseWheelUp then
|
||||||
|
self.verticalScrollBar:decrement()
|
||||||
|
else
|
||||||
|
self.verticalScrollBar:increment()
|
||||||
|
end
|
||||||
|
elseif self.horizontalScrollBar then
|
||||||
|
if mouseWheel == MouseWheelUp then
|
||||||
|
self.horizontalScrollBar:increment()
|
||||||
|
else
|
||||||
|
self.horizontalScrollBar:decrement()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function UITextEdit:onTextAreaUpdate(virtualOffset, virtualSize, totalSize)
|
||||||
|
self:updateScrollBars()
|
||||||
|
end
|
||||||
|
|
||||||
|
function UITextEdit:setVerticalScrollBar(scrollbar)
|
||||||
|
self.verticalScrollBar = scrollbar
|
||||||
|
self.verticalScrollBar.onValueChange = function(scrollbar, value)
|
||||||
|
local virtualOffset = self:getTextVirtualOffset()
|
||||||
|
virtualOffset.y = value
|
||||||
|
self:setTextVirtualOffset(virtualOffset)
|
||||||
|
end
|
||||||
|
self:updateScrollBars()
|
||||||
|
end
|
||||||
|
|
||||||
|
function UITextEdit:setHorizontalScrollBar(scrollbar)
|
||||||
|
self.horizontalScrollBar = scrollbar
|
||||||
|
self.horizontalScrollBar.onValueChange = function(scrollbar, value)
|
||||||
|
local virtualOffset = self:getTextVirtualOffset()
|
||||||
|
virtualOffset.x = value
|
||||||
|
self:setTextVirtualOffset(virtualOffset)
|
||||||
|
end
|
||||||
|
self:updateScrollBars()
|
||||||
|
end
|
||||||
|
|
||||||
|
function UITextEdit:updateScrollBars()
|
||||||
|
local scrollSize = self:getTextTotalSize()
|
||||||
|
local scrollWidth = math.max(scrollSize.width - self:getTextVirtualSize().width, 0)
|
||||||
|
local scrollHeight = math.max(scrollSize.height - self:getTextVirtualSize().height, 0)
|
||||||
|
|
||||||
|
local scrollbar = self.verticalScrollBar
|
||||||
|
if scrollbar then
|
||||||
|
scrollbar:setMinimum(0)
|
||||||
|
scrollbar:setMaximum(scrollHeight)
|
||||||
|
scrollbar:setValue(self:getTextVirtualOffset().y)
|
||||||
|
end
|
||||||
|
|
||||||
|
local scrollbar = self.horizontalScrollBar
|
||||||
|
if scrollbar then
|
||||||
|
scrollbar:setMinimum(0)
|
||||||
|
scrollbar:setMaximum(scrollWidth)
|
||||||
|
scrollbar:setValue(self:getTextVirtualOffset().x)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- todo: ontext change, focus to cursor
|
|
@ -228,11 +228,17 @@ function resolvepath(filePath, depth)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function toboolean(str)
|
function toboolean(v)
|
||||||
str = str:trim():lower()
|
if type(v) == 'string' then
|
||||||
if str == '1' or str == 'true' then
|
v = v:trim():lower()
|
||||||
|
if v == '1' or v == 'true' then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
elseif type(v) == 'number' then
|
||||||
|
if v == 1 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,46 +23,6 @@ function destroy()
|
||||||
end
|
end
|
||||||
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)
|
function onGameEditText(id, itemId, maxLength, text, writter, time)
|
||||||
if textWindow then return end
|
if textWindow then return end
|
||||||
textWindow = g_ui.createWidget('TextWindow', rootWidget)
|
textWindow = g_ui.createWidget('TextWindow', rootWidget)
|
||||||
|
@ -119,81 +79,13 @@ function onGameEditText(id, itemId, maxLength, text, writter, time)
|
||||||
destroy()
|
destroy()
|
||||||
end
|
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
|
okButton.onClick = doneFunc
|
||||||
cancelButton.onClick = destroy
|
cancelButton.onClick = destroy
|
||||||
--textWindow.onEnter = doneFunc -- this should be '\n'
|
|
||||||
|
if not writeable then
|
||||||
|
textWindow.onEnter = doneFunc
|
||||||
|
end
|
||||||
|
|
||||||
textWindow.onEscape = destroy
|
textWindow.onEscape = destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -222,28 +114,3 @@ function onGameEditList(id, doorId, text)
|
||||||
textWindow.onEscape = destroy
|
textWindow.onEscape = destroy
|
||||||
end
|
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
|
TextWindow < MainWindow
|
||||||
id: textWindow
|
id: textWindow
|
||||||
size: 280 280
|
size: 300 280
|
||||||
@onEscape: self:destroy()
|
|
||||||
|
|
||||||
UIItem
|
Item
|
||||||
id: textItem
|
id: textItem
|
||||||
virtual: true
|
virtual: true
|
||||||
size: 32 32
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
||||||
|
@ -15,43 +13,40 @@ TextWindow < MainWindow
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: textItem.right
|
anchors.left: textItem.right
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: text.top
|
|
||||||
text-align: left
|
|
||||||
margin-left: 8
|
margin-left: 8
|
||||||
margin-bottom: 10
|
text-auto-resize: true
|
||||||
|
text-align: left
|
||||||
|
text-wrap: true
|
||||||
|
|
||||||
MultilineTextEdit
|
MultilineTextEdit
|
||||||
id: text
|
id: text
|
||||||
anchors.fill: parent
|
anchors.top: textScroll.top
|
||||||
anchors.top: textItem.bottom
|
anchors.left: parent.left
|
||||||
margin-right: 10
|
anchors.right: textScroll.left
|
||||||
margin-top: 30
|
anchors.bottom: textScroll.bottom
|
||||||
margin-bottom: 30
|
vertical-scrollbar: textScroll
|
||||||
|
|
||||||
VerticalScrollBar
|
VerticalScrollBar
|
||||||
id: textScroll
|
id: textScroll
|
||||||
anchors.left: prev.right
|
anchors.top: description.bottom
|
||||||
anchors.top: prev.top
|
anchors.bottom: okButton.top
|
||||||
anchors.bottom: prev.bottom
|
anchors.right: parent.right
|
||||||
minimum: 0
|
margin-top: 10
|
||||||
maximum: 0
|
margin-bottom: 10
|
||||||
step: 1
|
step: 16
|
||||||
value: 0
|
|
||||||
pixels-scroll: true
|
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
|
Button
|
||||||
id: okButton
|
id: okButton
|
||||||
!text: tr('Ok')
|
!text: tr('Ok')
|
||||||
anchors.top: text.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.right: text.right
|
anchors.right: next.left
|
||||||
margin-top: 10
|
margin-right: 10
|
||||||
|
width: 60
|
||||||
|
|
||||||
|
Button
|
||||||
|
id: cancelButton
|
||||||
|
!text: tr('Cancel')
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
width: 60
|
width: 60
|
||||||
|
|
|
@ -637,23 +637,28 @@ void Application::registerLuaFunctions()
|
||||||
// UITextEdit
|
// UITextEdit
|
||||||
g_lua.registerClass<UITextEdit, UIWidget>();
|
g_lua.registerClass<UITextEdit, UIWidget>();
|
||||||
g_lua.bindClassStaticFunction<UITextEdit>("create", []{ return UITextEditPtr(new UITextEdit); } );
|
g_lua.bindClassStaticFunction<UITextEdit>("create", []{ return UITextEditPtr(new UITextEdit); } );
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setTextHorizontalMargin", &UITextEdit::setTextHorizontalMargin);
|
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setCursorPos", &UITextEdit::setCursorPos);
|
g_lua.bindClassMemberFunction<UITextEdit>("setCursorPos", &UITextEdit::setCursorPos);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setCursorEnabled", &UITextEdit::setCursorEnabled);
|
g_lua.bindClassMemberFunction<UITextEdit>("setCursorVisible", &UITextEdit::setCursorVisible);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setTextHidden", &UITextEdit::setTextHidden);
|
g_lua.bindClassMemberFunction<UITextEdit>("setTextHidden", &UITextEdit::setTextHidden);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setValidCharacters", &UITextEdit::setValidCharacters);
|
g_lua.bindClassMemberFunction<UITextEdit>("setValidCharacters", &UITextEdit::setValidCharacters);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setShiftNavigation", &UITextEdit::setShiftNavigation);
|
g_lua.bindClassMemberFunction<UITextEdit>("setShiftNavigation", &UITextEdit::setShiftNavigation);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setMultiline", &UITextEdit::setMultiline);
|
g_lua.bindClassMemberFunction<UITextEdit>("setMultiline", &UITextEdit::setMultiline);
|
||||||
|
g_lua.bindClassMemberFunction<UITextEdit>("setEditable", &UITextEdit::setEditable);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("setMaxLength", &UITextEdit::setMaxLength);
|
g_lua.bindClassMemberFunction<UITextEdit>("setMaxLength", &UITextEdit::setMaxLength);
|
||||||
|
g_lua.bindClassMemberFunction<UITextEdit>("setTextVirtualOffset", &UITextEdit::setTextVirtualOffset);
|
||||||
|
g_lua.bindClassMemberFunction<UITextEdit>("getTextVirtualOffset", &UITextEdit::getTextVirtualOffset);
|
||||||
|
g_lua.bindClassMemberFunction<UITextEdit>("getTextVirtualSize", &UITextEdit::getTextVirtualSize);
|
||||||
|
g_lua.bindClassMemberFunction<UITextEdit>("getTextTotalSize", &UITextEdit::getTextTotalSize);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("moveCursor", &UITextEdit::moveCursor);
|
g_lua.bindClassMemberFunction<UITextEdit>("moveCursor", &UITextEdit::moveCursor);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("appendText", &UITextEdit::appendText);
|
g_lua.bindClassMemberFunction<UITextEdit>("appendText", &UITextEdit::appendText);
|
||||||
|
g_lua.bindClassMemberFunction<UITextEdit>("wrapText", &UITextEdit::wrapText);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("removeCharacter", &UITextEdit::removeCharacter);
|
g_lua.bindClassMemberFunction<UITextEdit>("removeCharacter", &UITextEdit::removeCharacter);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("getDisplayedText", &UITextEdit::getDisplayedText);
|
g_lua.bindClassMemberFunction<UITextEdit>("getDisplayedText", &UITextEdit::getDisplayedText);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("getTextPos", &UITextEdit::getTextPos);
|
g_lua.bindClassMemberFunction<UITextEdit>("getTextPos", &UITextEdit::getTextPos);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("getTextHorizontalMargin", &UITextEdit::getTextHorizontalMargin);
|
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("getCursorPos", &UITextEdit::getCursorPos);
|
g_lua.bindClassMemberFunction<UITextEdit>("getCursorPos", &UITextEdit::getCursorPos);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("getMaxLength", &UITextEdit::getMaxLength);
|
g_lua.bindClassMemberFunction<UITextEdit>("getMaxLength", &UITextEdit::getMaxLength);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("isCursorEnabled", &UITextEdit::isCursorEnabled);
|
g_lua.bindClassMemberFunction<UITextEdit>("isEditable", &UITextEdit::isEditable);
|
||||||
|
g_lua.bindClassMemberFunction<UITextEdit>("isCursorVisible", &UITextEdit::isCursorVisible);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("isTextHidden", &UITextEdit::isTextHidden);
|
g_lua.bindClassMemberFunction<UITextEdit>("isTextHidden", &UITextEdit::isTextHidden);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("isShiftNavigation", &UITextEdit::isShiftNavigation);
|
g_lua.bindClassMemberFunction<UITextEdit>("isShiftNavigation", &UITextEdit::isShiftNavigation);
|
||||||
g_lua.bindClassMemberFunction<UITextEdit>("isMultiline", &UITextEdit::isMultiline);
|
g_lua.bindClassMemberFunction<UITextEdit>("isMultiline", &UITextEdit::isMultiline);
|
||||||
|
|
|
@ -33,12 +33,13 @@ UITextEdit::UITextEdit()
|
||||||
{
|
{
|
||||||
m_cursorPos = 0;
|
m_cursorPos = 0;
|
||||||
m_textAlign = Fw::AlignTopLeft;
|
m_textAlign = Fw::AlignTopLeft;
|
||||||
m_startRenderPos = 0;
|
|
||||||
m_textHorizontalMargin = 0;
|
|
||||||
m_textHidden = false;
|
m_textHidden = false;
|
||||||
m_shiftNavigation = false;
|
m_shiftNavigation = false;
|
||||||
m_multiline = false;
|
m_multiline = false;
|
||||||
|
m_cursorVisible = true;
|
||||||
|
m_cursorInRange = true;
|
||||||
m_maxLength = 0;
|
m_maxLength = 0;
|
||||||
|
m_editable = true;
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,16 +63,16 @@ void UITextEdit::drawSelf(Fw::DrawPane drawPane)
|
||||||
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||||
|
|
||||||
// render cursor
|
// render cursor
|
||||||
if(isExplicitlyEnabled() && isActive() && m_cursorPos >= 0) {
|
if(isExplicitlyEnabled() && m_cursorVisible && m_cursorInRange && isActive() && m_cursorPos >= 0) {
|
||||||
assert(m_cursorPos <= textLength);
|
assert(m_cursorPos <= textLength);
|
||||||
// draw every 333ms
|
// draw every 333ms
|
||||||
const int delay = 333;
|
const int delay = 333;
|
||||||
int elapsed = g_clock.millis() - m_cursorTicks;
|
int elapsed = g_clock.millis() - m_cursorTicks;
|
||||||
if(elapsed <= delay) {
|
if(elapsed <= delay) {
|
||||||
Rect cursorRect;
|
Rect cursorRect;
|
||||||
// when cursor is at 0 or is the first visible element
|
// when cursor is at 0
|
||||||
if(m_cursorPos == 0 || m_cursorPos == m_startRenderPos)
|
if(m_cursorPos == 0)
|
||||||
cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight());
|
cursorRect = Rect(m_rect.left()+m_padding.left, m_rect.top()+m_padding.top, 1, m_font->getGlyphHeight());
|
||||||
else
|
else
|
||||||
cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight());
|
cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight());
|
||||||
g_painter->drawFilledRect(cursorRect);
|
g_painter->drawFilledRect(cursorRect);
|
||||||
|
@ -81,7 +82,7 @@ void UITextEdit::drawSelf(Fw::DrawPane drawPane)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UITextEdit::update()
|
void UITextEdit::update(bool focusCursor)
|
||||||
{
|
{
|
||||||
std::string text = getDisplayedText();
|
std::string text = getDisplayedText();
|
||||||
int textLength = text.length();
|
int textLength = text.length();
|
||||||
|
@ -103,18 +104,14 @@ void UITextEdit::update()
|
||||||
m_glyphsTexCoords.resize(textLength);
|
m_glyphsTexCoords.resize(textLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point oldTextAreaOffset = m_textVirtualOffset;
|
||||||
|
|
||||||
// readjust start view area based on cursor position
|
// readjust start view area based on cursor position
|
||||||
|
m_cursorInRange = false;
|
||||||
|
if(focusCursor) {
|
||||||
if(m_cursorPos >= 0 && textLength > 0) {
|
if(m_cursorPos >= 0 && textLength > 0) {
|
||||||
assert(m_cursorPos <= textLength);
|
assert(m_cursorPos <= textLength);
|
||||||
if(m_cursorPos < m_startRenderPos) // cursor is before the previous first rendered glyph, so we need to update
|
Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(m_padding.left+m_padding.right, 0)); // previous rendered virtual rect
|
||||||
{
|
|
||||||
m_startInternalPos.x = glyphsPositions[m_cursorPos].x;
|
|
||||||
m_startInternalPos.y = glyphsPositions[m_cursorPos].y - m_font->getYOffset();
|
|
||||||
m_startRenderPos = m_cursorPos;
|
|
||||||
} else if(m_cursorPos > m_startRenderPos || // cursor is after the previous first rendered glyph
|
|
||||||
(m_cursorPos == m_startRenderPos && textLength == m_cursorPos)) // cursor is at the previous rendered element, and is the last text element
|
|
||||||
{
|
|
||||||
Rect virtualRect(m_startInternalPos, m_rect.size() - Size(2*m_textHorizontalMargin, 0) ); // previous rendered virtual rect
|
|
||||||
int pos = m_cursorPos - 1; // element before cursor
|
int pos = m_cursorPos - 1; // element before cursor
|
||||||
glyph = (uchar)text[pos]; // glyph of the element before cursor
|
glyph = (uchar)text[pos]; // glyph of the element before cursor
|
||||||
Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]);
|
Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]);
|
||||||
|
@ -135,25 +132,55 @@ void UITextEdit::update()
|
||||||
|
|
||||||
// first glyph entirely visible found
|
// first glyph entirely visible found
|
||||||
if(glyphRect.topLeft() >= startGlyphPos) {
|
if(glyphRect.topLeft() >= startGlyphPos) {
|
||||||
m_startInternalPos.x = glyphsPositions[pos].x;
|
m_textVirtualOffset.x = glyphsPositions[pos].x;
|
||||||
m_startInternalPos.y = glyphsPositions[pos].y - m_font->getYOffset();
|
m_textVirtualOffset.y = glyphsPositions[pos].y - m_font->getYOffset();
|
||||||
m_startRenderPos = pos;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
m_startInternalPos = Point(0,0);
|
m_textVirtualOffset = Point(0,0);
|
||||||
|
}
|
||||||
|
m_cursorInRange = true;
|
||||||
|
} else {
|
||||||
|
if(m_cursorPos >= 0 && textLength > 0) {
|
||||||
|
Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(2*m_padding.left+m_padding.right, 0) ); // previous rendered virtual rect
|
||||||
|
int pos = m_cursorPos - 1; // element before cursor
|
||||||
|
glyph = (uchar)text[pos]; // glyph of the element before cursor
|
||||||
|
Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]);
|
||||||
|
if(virtualRect.contains(glyphRect.topLeft()) && virtualRect.contains(glyphRect.bottomRight()))
|
||||||
|
m_cursorInRange = true;
|
||||||
|
} else {
|
||||||
|
m_cursorInRange = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fireAreaUpdate = false;
|
||||||
|
if(oldTextAreaOffset != m_textVirtualOffset)
|
||||||
|
fireAreaUpdate = true;
|
||||||
|
|
||||||
Rect textScreenCoords = m_rect;
|
Rect textScreenCoords = m_rect;
|
||||||
textScreenCoords.expandLeft(-m_textHorizontalMargin);
|
textScreenCoords.expandLeft(-m_padding.left);
|
||||||
textScreenCoords.expandRight(-m_textHorizontalMargin);
|
textScreenCoords.expandRight(-m_padding.right);
|
||||||
textScreenCoords.expandLeft(-m_textOffset.x);
|
textScreenCoords.expandBottom(-m_padding.bottom);
|
||||||
textScreenCoords.translate(0, m_textOffset.y);
|
textScreenCoords.expandTop(-m_padding.top);
|
||||||
m_drawArea = textScreenCoords;
|
m_drawArea = textScreenCoords;
|
||||||
|
|
||||||
|
if(textScreenCoords.size() != m_textVirtualSize) {
|
||||||
|
m_textVirtualSize = textScreenCoords.size();
|
||||||
|
fireAreaUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size totalSize = textBoxSize;
|
||||||
|
if(totalSize.width() < m_textVirtualSize.width())
|
||||||
|
totalSize.setWidth(m_textVirtualSize.height());
|
||||||
|
if(totalSize.height() < m_textVirtualSize.height())
|
||||||
|
totalSize.setHeight(m_textVirtualSize.height());
|
||||||
|
if(m_textTotalSize != totalSize) {
|
||||||
|
m_textTotalSize = totalSize;
|
||||||
|
fireAreaUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_textAlign & Fw::AlignBottom) {
|
if(m_textAlign & Fw::AlignBottom) {
|
||||||
m_drawArea.translate(0, textScreenCoords.height() - textBoxSize.height());
|
m_drawArea.translate(0, textScreenCoords.height() - textBoxSize.height());
|
||||||
} else if(m_textAlign & Fw::AlignVerticalCenter) {
|
} else if(m_textAlign & Fw::AlignVerticalCenter) {
|
||||||
|
@ -199,21 +226,21 @@ void UITextEdit::update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// only render glyphs that are after startRenderPosition
|
// only render glyphs that are after startRenderPosition
|
||||||
if(glyphScreenCoords.bottom() < m_startInternalPos.y || glyphScreenCoords.right() < m_startInternalPos.x)
|
if(glyphScreenCoords.bottom() < m_textVirtualOffset.y || glyphScreenCoords.right() < m_textVirtualOffset.x)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// bound glyph topLeft to startRenderPosition
|
// bound glyph topLeft to startRenderPosition
|
||||||
if(glyphScreenCoords.top() < m_startInternalPos.y) {
|
if(glyphScreenCoords.top() < m_textVirtualOffset.y) {
|
||||||
glyphTextureCoords.setTop(glyphTextureCoords.top() + (m_startInternalPos.y - glyphScreenCoords.top()));
|
glyphTextureCoords.setTop(glyphTextureCoords.top() + (m_textVirtualOffset.y - glyphScreenCoords.top()));
|
||||||
glyphScreenCoords.setTop(m_startInternalPos.y);
|
glyphScreenCoords.setTop(m_textVirtualOffset.y);
|
||||||
}
|
}
|
||||||
if(glyphScreenCoords.left() < m_startInternalPos.x) {
|
if(glyphScreenCoords.left() < m_textVirtualOffset.x) {
|
||||||
glyphTextureCoords.setLeft(glyphTextureCoords.left() + (m_startInternalPos.x - glyphScreenCoords.left()));
|
glyphTextureCoords.setLeft(glyphTextureCoords.left() + (m_textVirtualOffset.x - glyphScreenCoords.left()));
|
||||||
glyphScreenCoords.setLeft(m_startInternalPos.x);
|
glyphScreenCoords.setLeft(m_textVirtualOffset.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// subtract startInternalPos
|
// subtract startInternalPos
|
||||||
glyphScreenCoords.translate(-m_startInternalPos);
|
glyphScreenCoords.translate(-m_textVirtualOffset);
|
||||||
|
|
||||||
// translate rect to screen coords
|
// translate rect to screen coords
|
||||||
glyphScreenCoords.translate(textScreenCoords.topLeft());
|
glyphScreenCoords.translate(textScreenCoords.topLeft());
|
||||||
|
@ -236,12 +263,9 @@ void UITextEdit::update()
|
||||||
m_glyphsCoords[i] = glyphScreenCoords;
|
m_glyphsCoords[i] = glyphScreenCoords;
|
||||||
m_glyphsTexCoords[i] = glyphTextureCoords;
|
m_glyphsTexCoords[i] = glyphTextureCoords;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void UITextEdit::setTextHorizontalMargin(int margin)
|
if(fireAreaUpdate)
|
||||||
{
|
onTextAreaUpdate(m_textVirtualOffset, m_textVirtualSize, m_textTotalSize);
|
||||||
m_textHorizontalMargin = margin;
|
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UITextEdit::setCursorPos(int pos)
|
void UITextEdit::setCursorPos(int pos)
|
||||||
|
@ -253,24 +277,20 @@ void UITextEdit::setCursorPos(int pos)
|
||||||
m_cursorPos = m_text.length();
|
m_cursorPos = m_text.length();
|
||||||
else
|
else
|
||||||
m_cursorPos = pos;
|
m_cursorPos = pos;
|
||||||
update();
|
update(true);
|
||||||
g_app.repaint();
|
g_app.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UITextEdit::setCursorEnabled(bool enable)
|
|
||||||
{
|
|
||||||
if(enable) {
|
|
||||||
m_cursorPos = 0;
|
|
||||||
blinkCursor();
|
|
||||||
} else
|
|
||||||
m_cursorPos = -1;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UITextEdit::setTextHidden(bool hidden)
|
void UITextEdit::setTextHidden(bool hidden)
|
||||||
{
|
{
|
||||||
m_textHidden = true;
|
m_textHidden = true;
|
||||||
|
update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITextEdit::setTextVirtualOffset(const Point& offset)
|
||||||
|
{
|
||||||
|
m_textVirtualOffset = offset;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +319,7 @@ void UITextEdit::appendText(std::string text)
|
||||||
m_text.insert(m_cursorPos, text);
|
m_text.insert(m_cursorPos, text);
|
||||||
m_cursorPos += text.length();
|
m_cursorPos += text.length();
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
update();
|
update(true);
|
||||||
UIWidget::onTextChange(m_text, oldText);
|
UIWidget::onTextChange(m_text, oldText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +343,7 @@ void UITextEdit::appendCharacter(char c)
|
||||||
m_text.insert(m_cursorPos, tmp);
|
m_text.insert(m_cursorPos, tmp);
|
||||||
m_cursorPos++;
|
m_cursorPos++;
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
update();
|
update(true);
|
||||||
UIWidget::onTextChange(m_text, oldText);
|
UIWidget::onTextChange(m_text, oldText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -341,11 +361,16 @@ void UITextEdit::removeCharacter(bool right)
|
||||||
m_text.erase(m_text.begin() + --m_cursorPos);
|
m_text.erase(m_text.begin() + --m_cursorPos);
|
||||||
}
|
}
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
update();
|
update(true);
|
||||||
UIWidget::onTextChange(m_text, oldText);
|
UIWidget::onTextChange(m_text, oldText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UITextEdit::wrapText()
|
||||||
|
{
|
||||||
|
m_text = m_font->wrapText(m_text, getPaddingRect().width());
|
||||||
|
}
|
||||||
|
|
||||||
void UITextEdit::moveCursor(bool right)
|
void UITextEdit::moveCursor(bool right)
|
||||||
{
|
{
|
||||||
if(right) {
|
if(right) {
|
||||||
|
@ -359,7 +384,7 @@ void UITextEdit::moveCursor(bool right)
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update();
|
update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int UITextEdit::getTextPos(Point pos)
|
int UITextEdit::getTextPos(Point pos)
|
||||||
|
@ -404,7 +429,7 @@ void UITextEdit::onTextChange(const std::string& text, const std::string& oldTex
|
||||||
{
|
{
|
||||||
m_cursorPos = text.length();
|
m_cursorPos = text.length();
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
update();
|
update(true);
|
||||||
UIWidget::onTextChange(text, oldText);
|
UIWidget::onTextChange(text, oldText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,14 +449,16 @@ void UITextEdit::onStyleApply(const std::string& styleName, const OTMLNodePtr& s
|
||||||
setCursorPos(m_text.length());
|
setCursorPos(m_text.length());
|
||||||
} else if(node->tag() == "text-hidden")
|
} else if(node->tag() == "text-hidden")
|
||||||
setTextHidden(node->value<bool>());
|
setTextHidden(node->value<bool>());
|
||||||
else if(node->tag() == "text-margin")
|
|
||||||
setTextHorizontalMargin(node->value<int>());
|
|
||||||
else if(node->tag() == "shift-navigation")
|
else if(node->tag() == "shift-navigation")
|
||||||
setShiftNavigation(node->value<bool>());
|
setShiftNavigation(node->value<bool>());
|
||||||
else if(node->tag() == "multiline")
|
else if(node->tag() == "multiline")
|
||||||
setMultiline(node->value<bool>());
|
setMultiline(node->value<bool>());
|
||||||
else if(node->tag() == "max-length")
|
else if(node->tag() == "max-length")
|
||||||
setMaxLength(node->value<int>());
|
setMaxLength(node->value<int>());
|
||||||
|
else if(node->tag() == "editable")
|
||||||
|
setEditable(node->value<bool>());
|
||||||
|
else if(node->tag() == "cursor-visible")
|
||||||
|
setCursorVisible(node->value<bool>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +475,7 @@ void UITextEdit::onFocusChange(bool focused, Fw::FocusReason reason)
|
||||||
setCursorPos(m_text.length());
|
setCursorPos(m_text.length());
|
||||||
else
|
else
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
|
update(true);
|
||||||
}
|
}
|
||||||
UIWidget::onFocusChange(focused, reason);
|
UIWidget::onFocusChange(focused, reason);
|
||||||
}
|
}
|
||||||
|
@ -458,10 +486,10 @@ bool UITextEdit::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeat
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(keyboardModifiers == Fw::KeyboardNoModifier) {
|
if(keyboardModifiers == Fw::KeyboardNoModifier) {
|
||||||
if(keyCode == Fw::KeyDelete) { // erase right character
|
if(keyCode == Fw::KeyDelete && m_editable) { // erase right character
|
||||||
removeCharacter(true);
|
removeCharacter(true);
|
||||||
return true;
|
return true;
|
||||||
} else if(keyCode == Fw::KeyBackspace) { // erase left character {
|
} else if(keyCode == Fw::KeyBackspace && m_editable) { // erase left character {
|
||||||
removeCharacter(false);
|
removeCharacter(false);
|
||||||
return true;
|
return true;
|
||||||
} else if(keyCode == Fw::KeyRight && !m_shiftNavigation) { // move cursor right
|
} else if(keyCode == Fw::KeyRight && !m_shiftNavigation) { // move cursor right
|
||||||
|
@ -480,16 +508,16 @@ bool UITextEdit::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeat
|
||||||
if(UIWidgetPtr parent = getParent())
|
if(UIWidgetPtr parent = getParent())
|
||||||
parent->focusNextChild(Fw::KeyboardFocusReason);
|
parent->focusNextChild(Fw::KeyboardFocusReason);
|
||||||
return true;
|
return true;
|
||||||
} else if(keyCode == Fw::KeyEnter && m_multiline) {
|
} else if(keyCode == Fw::KeyEnter && m_multiline && m_editable) {
|
||||||
appendCharacter('\n');
|
appendCharacter('\n');
|
||||||
return true;
|
return true;
|
||||||
} else if(keyCode == Fw::KeyUp && !m_shiftNavigation && m_multiline) {
|
} else if(keyCode == Fw::KeyUp && !m_shiftNavigation && m_multiline) {
|
||||||
|
return true;
|
||||||
} else if(keyCode == Fw::KeyDown && !m_shiftNavigation && m_multiline) {
|
} else if(keyCode == Fw::KeyDown && !m_shiftNavigation && m_multiline) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} else if(keyboardModifiers == Fw::KeyboardCtrlModifier) {
|
} else if(keyboardModifiers == Fw::KeyboardCtrlModifier) {
|
||||||
if(keyCode == Fw::KeyV) {
|
if(keyCode == Fw::KeyV && m_editable) {
|
||||||
appendText(g_window.getClipboardText());
|
appendText(g_window.getClipboardText());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -512,9 +540,12 @@ bool UITextEdit::onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeat
|
||||||
|
|
||||||
bool UITextEdit::onKeyText(const std::string& keyText)
|
bool UITextEdit::onKeyText(const std::string& keyText)
|
||||||
{
|
{
|
||||||
|
if(m_editable) {
|
||||||
appendText(keyText);
|
appendText(keyText);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool UITextEdit::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
bool UITextEdit::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
||||||
{
|
{
|
||||||
|
@ -526,6 +557,11 @@ bool UITextEdit::onMousePress(const Point& mousePos, Fw::MouseButton button)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UITextEdit::onTextAreaUpdate(const Point& offset, const Size& visibleSize, const Size& totalSize)
|
||||||
|
{
|
||||||
|
callLuaField("onTextAreaUpdate", offset, visibleSize, totalSize);
|
||||||
|
}
|
||||||
|
|
||||||
void UITextEdit::blinkCursor()
|
void UITextEdit::blinkCursor()
|
||||||
{
|
{
|
||||||
m_cursorTicks = g_clock.millis();
|
m_cursorTicks = g_clock.millis();
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UILINEEDIT_H
|
#ifndef UITEXTEDIT_H
|
||||||
#define UILINEEDIT_H
|
#define UITEXTEDIT_H
|
||||||
|
|
||||||
#include "uiwidget.h"
|
#include "uiwidget.h"
|
||||||
|
|
||||||
|
@ -34,32 +34,37 @@ public:
|
||||||
void drawSelf(Fw::DrawPane drawPane);
|
void drawSelf(Fw::DrawPane drawPane);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update();
|
void update(bool focusCursor = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setTextHorizontalMargin(int margin);
|
|
||||||
void setCursorPos(int pos);
|
void setCursorPos(int pos);
|
||||||
void setCursorEnabled(bool enable);
|
void setCursorVisible(bool enable) { m_cursorVisible = false; }
|
||||||
void setTextHidden(bool hidden);
|
void setTextHidden(bool hidden);
|
||||||
void setValidCharacters(const std::string validCharacters) { m_validCharacters = validCharacters; }
|
void setValidCharacters(const std::string validCharacters) { m_validCharacters = validCharacters; }
|
||||||
void setShiftNavigation(bool enable) { m_shiftNavigation = enable; }
|
void setShiftNavigation(bool enable) { m_shiftNavigation = enable; }
|
||||||
void setMultiline(bool enable) { m_multiline = enable; }
|
void setMultiline(bool enable) { m_multiline = enable; }
|
||||||
void setMaxLength(uint maxLength) { m_maxLength = maxLength; }
|
void setMaxLength(uint maxLength) { m_maxLength = maxLength; }
|
||||||
|
void setTextVirtualOffset(const Point& offset);
|
||||||
|
void setEditable(bool editable) { m_editable = editable; }
|
||||||
|
|
||||||
void moveCursor(bool right);
|
void moveCursor(bool right);
|
||||||
void appendText(std::string text);
|
void appendText(std::string text);
|
||||||
void appendCharacter(char c);
|
void appendCharacter(char c);
|
||||||
void removeCharacter(bool right);
|
void removeCharacter(bool right);
|
||||||
|
|
||||||
|
void wrapText();
|
||||||
std::string getDisplayedText();
|
std::string getDisplayedText();
|
||||||
int getTextPos(Point pos);
|
int getTextPos(Point pos);
|
||||||
int getTextHorizontalMargin() { return m_textHorizontalMargin; }
|
|
||||||
int getCursorPos() { return m_cursorPos; }
|
int getCursorPos() { return m_cursorPos; }
|
||||||
|
Point getTextVirtualOffset() { return m_textVirtualOffset; }
|
||||||
|
Size getTextVirtualSize() { return m_textVirtualSize; }
|
||||||
|
Size getTextTotalSize() { return m_textTotalSize; }
|
||||||
uint getMaxLength() { return m_maxLength; }
|
uint getMaxLength() { return m_maxLength; }
|
||||||
bool isCursorEnabled() { return m_cursorPos != -1; }
|
bool isCursorVisible() { return m_cursorVisible; }
|
||||||
bool isTextHidden() { return m_textHidden; }
|
bool isTextHidden() { return m_textHidden; }
|
||||||
bool isShiftNavigation() { return m_shiftNavigation; }
|
bool isShiftNavigation() { return m_shiftNavigation; }
|
||||||
bool isMultiline() { return m_multiline; }
|
bool isMultiline() { return m_multiline; }
|
||||||
|
bool isEditable() { return m_editable; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onHoverChange(bool hovered);
|
virtual void onHoverChange(bool hovered);
|
||||||
|
@ -71,19 +76,23 @@ protected:
|
||||||
virtual bool onKeyText(const std::string& keyText);
|
virtual bool onKeyText(const std::string& keyText);
|
||||||
virtual bool onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks);
|
virtual bool onKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks);
|
||||||
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
|
virtual bool onMousePress(const Point& mousePos, Fw::MouseButton button);
|
||||||
|
virtual void onTextAreaUpdate(const Point& vitualOffset, const Size& virtualSize, const Size& totalSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void blinkCursor();
|
void blinkCursor();
|
||||||
|
|
||||||
Rect m_drawArea;
|
Rect m_drawArea;
|
||||||
int m_cursorPos;
|
int m_cursorPos;
|
||||||
Point m_startInternalPos;
|
Point m_textVirtualOffset;
|
||||||
int m_startRenderPos;
|
Size m_textVirtualSize;
|
||||||
|
Size m_textTotalSize;
|
||||||
ticks_t m_cursorTicks;
|
ticks_t m_cursorTicks;
|
||||||
int m_textHorizontalMargin;
|
|
||||||
bool m_textHidden;
|
bool m_textHidden;
|
||||||
bool m_shiftNavigation;
|
bool m_shiftNavigation;
|
||||||
bool m_multiline;
|
bool m_multiline;
|
||||||
|
bool m_cursorInRange;
|
||||||
|
bool m_cursorVisible;
|
||||||
|
bool m_editable;
|
||||||
std::string m_validCharacters;
|
std::string m_validCharacters;
|
||||||
uint m_maxLength;
|
uint m_maxLength;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue