mirror of
https://github.com/airstruck/luigi.git
synced 2026-01-10 16:28:23 +00:00
formalize attributes
This commit is contained in:
385
luigi/attribute.lua
Normal file
385
luigi/attribute.lua
Normal file
@@ -0,0 +1,385 @@
|
||||
--[[--
|
||||
Widget attributes.
|
||||
|
||||
This module defines "attributes" (special fields) that are
|
||||
recognized by all widgets. Their interpretation may vary
|
||||
depending on the `type` of widget. Some widget types may also
|
||||
recognize additional attributes.
|
||||
|
||||
Setting attributes can have side effects. For example, setting
|
||||
`height` or `width` causes the parent widget and its descendants
|
||||
to recalculate their size and position.
|
||||
--]]--
|
||||
|
||||
local Attribute = {}
|
||||
|
||||
--[[--
|
||||
widget identifier.
|
||||
|
||||
Should contain a unique string identifying the widget, if present.
|
||||
|
||||
A reference to the widget will be stored in the associated layout
|
||||
in a property having the same name as the widget's id.
|
||||
|
||||
Setting this attribute re-registers the widget with its layout.
|
||||
|
||||
@attrib id
|
||||
--]]--
|
||||
function Attribute.id (widget, value)
|
||||
local layout = widget.layout.master or widget.layout
|
||||
local oldValue = widget.attributes.id
|
||||
|
||||
if oldValue then
|
||||
layout[oldValue] = nil
|
||||
end
|
||||
|
||||
if value then
|
||||
layout[value] = widget
|
||||
end
|
||||
|
||||
widget.attributes.id = value
|
||||
end
|
||||
|
||||
-- TODO: formalize this bitfield somewhere
|
||||
local function parseKeyCombo (value)
|
||||
local mainKey = (value):match '[^%-]+$'
|
||||
local alt = (value):match 'alt%-' and 1 or 0
|
||||
local ctrl = (value):match 'ctrl%-' and 2 or 0
|
||||
local shift = (value):match 'shift%-' and 4 or 0
|
||||
local modifierFlags = alt + ctrl + shift
|
||||
|
||||
return mainKey, modifierFlags
|
||||
end
|
||||
|
||||
--[[--
|
||||
Keyboard accelerator.
|
||||
|
||||
Should contain a string representing a key and optional modifiers,
|
||||
separated by dashes; for example `'ctrl-c'` or `'alt-shift-escape'`.
|
||||
|
||||
Pressing this key combination bubbles a `Press` event on the widget,
|
||||
as if it had been pressed with a mouse or touch interface.
|
||||
|
||||
Setting this attribute re-registers the widget with its layout.
|
||||
|
||||
@attrib key
|
||||
--]]--
|
||||
function Attribute.key (widget, value)
|
||||
local layout = widget.layout.master or widget.layout
|
||||
local oldValue = widget.attributes.key
|
||||
|
||||
if oldValue then
|
||||
local mainKey, modifierFlags = parseKeyCombo(oldValue)
|
||||
layout.accelerators[modifierFlags][mainKey] = nil
|
||||
end
|
||||
|
||||
if value then
|
||||
local mainKey, modifierFlags = parseKeyCombo(value)
|
||||
layout.accelerators[modifierFlags][mainKey] = widget
|
||||
end
|
||||
|
||||
widget.attributes.key = value
|
||||
end
|
||||
|
||||
--[[--
|
||||
widget value.
|
||||
|
||||
Some widget types expect the value to be of a specific type and
|
||||
within a specific range. For example, `slider` and `progress`
|
||||
widgets expect a normalized number, and `text` widgets expect
|
||||
a string.
|
||||
|
||||
Setting this attribute bubbles the `Change` event.
|
||||
|
||||
@attrib value
|
||||
--]]--
|
||||
function Attribute.value (widget, value)
|
||||
local oldValue = widget.value
|
||||
widget.attributes.value = value
|
||||
widget:bubbleEvent('Change', { value = value, oldValue = oldValue })
|
||||
end
|
||||
|
||||
--[[--
|
||||
widget style.
|
||||
|
||||
Should contain a string or array of strings identifying
|
||||
style rules to be applied to the widget. When resolving
|
||||
any attribute with a `nil` value, these style rules are
|
||||
searched for a corresponding attribute.
|
||||
|
||||
Setting this attribute resets the `Font` and `Text` object
|
||||
associated with this widget.
|
||||
|
||||
Setting this attribute recalculates the size and position
|
||||
of the parent widget and its descendants.
|
||||
|
||||
@attrib style
|
||||
--]]--
|
||||
function Attribute.style (widget, value)
|
||||
widget.attributes.style = value
|
||||
widget.fontData = nil
|
||||
widget.textData = nil
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Size Attributes.
|
||||
|
||||
Setting these attributes recalculates the size and position
|
||||
of the parent widget and its descendants.
|
||||
|
||||
@section size
|
||||
--]]--
|
||||
|
||||
--[[--
|
||||
Flow axis.
|
||||
|
||||
Should equal either `'x'` or `'y'`. Defaults to `'y'`.
|
||||
|
||||
This attribute determines the placement and default dimensions
|
||||
of any child widgets.
|
||||
|
||||
When flow is `'x'`, the `height` of child widgets defaults
|
||||
to this widget's height, and each child is placed to the
|
||||
right of the previous child. When flow is `'y'`, the `width`
|
||||
of child widgets defaults to this widget's width, and each
|
||||
child is placed below the previous child.
|
||||
|
||||
Setting this attribute resets the `Text` object associated
|
||||
with this widget.
|
||||
|
||||
@attrib flow
|
||||
--]]--
|
||||
function Attribute.flow (widget, value)
|
||||
widget.attributes.flow = value
|
||||
widget.textData = nil
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Width.
|
||||
|
||||
This attribute may not always hold a numeric value.
|
||||
To get the calculated width, use `Widget:getWidth`.
|
||||
|
||||
Setting this attribute when the `wrap` attribute is
|
||||
also present resets the `Text` object associated
|
||||
with this widget.
|
||||
|
||||
@attrib width
|
||||
--]]--
|
||||
function Attribute.width (widget, value)
|
||||
value = value and math.max(value, widget.minwidth or 0)
|
||||
widget.attributes.width = value
|
||||
if widget.wrap then
|
||||
widget.textData = nil
|
||||
end
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Height.
|
||||
|
||||
This attribute may not always hold a numeric value.
|
||||
To get the calculated height, use `Widget:getHeight`.
|
||||
|
||||
@attrib height
|
||||
--]]--
|
||||
function Attribute.height (widget, value)
|
||||
value = value and math.max(value, widget.minheight or 0)
|
||||
widget.attributes.height = value
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Minimum width.
|
||||
|
||||
@attrib minwidth
|
||||
--]]--
|
||||
function Attribute.minwidth (widget, value)
|
||||
widget.attributes.minwidth = value
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Minimum height.
|
||||
|
||||
@attrib minheight
|
||||
--]]--
|
||||
function Attribute.minheight (widget, value)
|
||||
widget.attributes.minheight = value
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Font Attributes.
|
||||
|
||||
Setting these attributes resets the Font and Text
|
||||
objects associated with the widget.
|
||||
|
||||
@section font
|
||||
--]]--
|
||||
|
||||
--[[--
|
||||
Font path.
|
||||
|
||||
Should contain a path to a TrueType font to use for displaying
|
||||
this widget's `text`.
|
||||
|
||||
@attrib font
|
||||
--]]--
|
||||
function Attribute.font (widget, value)
|
||||
widget.attributes.font = value
|
||||
widget.fontData = nil
|
||||
widget.textData = nil
|
||||
end
|
||||
|
||||
--[[--
|
||||
Font size.
|
||||
|
||||
Should contain a number representing the size of the font, in points.
|
||||
Defaults to 12.
|
||||
|
||||
@attrib size
|
||||
--]]--
|
||||
function Attribute.size (widget, value)
|
||||
widget.attributes.size = value
|
||||
widget.fontData = nil
|
||||
widget.textData = nil
|
||||
end
|
||||
|
||||
--[[--
|
||||
Text Attributes.
|
||||
|
||||
Setting these attributes resets the Text object
|
||||
associated with the widget.
|
||||
|
||||
@section text
|
||||
--]]--
|
||||
|
||||
--[[--
|
||||
Text to display.
|
||||
|
||||
@attrib text
|
||||
--]]--
|
||||
function Attribute.text (widget, value)
|
||||
widget.attributes.text = value
|
||||
widget.textData = nil
|
||||
end
|
||||
|
||||
--[[--
|
||||
Text color.
|
||||
|
||||
Should contain an array with 3 or 4 values (RGB or RGBA) from 0 to 255.
|
||||
|
||||
@attrib color
|
||||
--]]--
|
||||
function Attribute.color (widget, value)
|
||||
widget.attributes.color = value
|
||||
widget.textData = nil
|
||||
end
|
||||
--[[--
|
||||
Text and icon alignment.
|
||||
|
||||
@attrib align
|
||||
--]]--
|
||||
function Attribute.align (widget, value)
|
||||
widget.attributes.align = value
|
||||
widget.textData = nil
|
||||
end
|
||||
|
||||
--[[--
|
||||
Wrap text onto multiple lines.
|
||||
|
||||
Should contain `true` for multiline text, or `false` or `nil`
|
||||
for a single line. Even text containing line breaks will display
|
||||
as a single line when this attribute is not set to `true`.
|
||||
|
||||
@attrib wrap
|
||||
--]]--
|
||||
function Attribute.wrap (widget, value)
|
||||
widget.attributes.wrap = value
|
||||
widget.textData = nil
|
||||
end
|
||||
|
||||
--[[--
|
||||
Visual Attributes.
|
||||
|
||||
@section visual
|
||||
--]]--
|
||||
|
||||
--[[--
|
||||
Background color.
|
||||
|
||||
Should contain an array with 3 or 4 values (RGB or RGBA) from 0 to 255.
|
||||
|
||||
@attrib background
|
||||
--]]--
|
||||
function Attribute.background (widget, value)
|
||||
widget.attributes.background = value
|
||||
end
|
||||
|
||||
--[[--
|
||||
Outline color.
|
||||
|
||||
Should contain an array with 3 or 4 values (RGB or RGBA) from 0 to 255.
|
||||
|
||||
@attrib outline
|
||||
--]]--
|
||||
function Attribute.outline (widget, value)
|
||||
widget.attributes.outline = value
|
||||
end
|
||||
|
||||
--[[--
|
||||
Slice image.
|
||||
|
||||
Should contain a path to an image with "slices" to display for this widget.
|
||||
|
||||
@attrib slices
|
||||
--]]--
|
||||
function Attribute.slices (widget, value)
|
||||
widget.attributes.slices = value
|
||||
end
|
||||
|
||||
--[[--
|
||||
Margin size.
|
||||
|
||||
The margin area occupies space outside of the `outline` and `slices`.
|
||||
|
||||
@attrib margin
|
||||
--]]--
|
||||
function Attribute.margin (widget, value)
|
||||
widget.attributes.margin = value
|
||||
widget.textData = nil
|
||||
widget:reshape()
|
||||
end
|
||||
|
||||
--[[--
|
||||
Padding size.
|
||||
|
||||
The padding area occupies space inside the `outline` and `slices`,
|
||||
and outside the space where the `icon` and `text` and any
|
||||
child widgets appear.
|
||||
|
||||
@attrib padding
|
||||
--]]--
|
||||
function Attribute.padding (widget, value)
|
||||
widget.attributes.padding = value
|
||||
widget.textData = nil
|
||||
widget:reshape()
|
||||
end
|
||||
|
||||
--[[--
|
||||
Icon path.
|
||||
|
||||
Should contain a path to an image file.
|
||||
|
||||
@attrib icon
|
||||
--]]--
|
||||
function Attribute.icon (widget, value)
|
||||
widget.attributes.icon = value
|
||||
widget.textData = nil
|
||||
end
|
||||
|
||||
|
||||
return Attribute
|
||||
@@ -149,7 +149,7 @@ function Renderer:positionText (widget, x1, y1, x2, y2)
|
||||
end
|
||||
|
||||
if not widget.fontData then
|
||||
widget.fontData = Font(widget.font, widget.fontSize)
|
||||
widget.fontData = Font(widget.font, widget.size)
|
||||
end
|
||||
|
||||
local font = widget.fontData
|
||||
@@ -168,7 +168,7 @@ function Renderer:positionText (widget, x1, y1, x2, y2)
|
||||
if not widget.textData then
|
||||
local limit = widget.wrap and x2 - x1 or nil
|
||||
widget.textData = Text(
|
||||
font, widget.text, widget.textColor, horizontal, limit)
|
||||
font, widget.text, widget.color, horizontal, limit)
|
||||
end
|
||||
|
||||
local textHeight = widget.textData:getHeight()
|
||||
|
||||
@@ -17,6 +17,7 @@ function Style:getProperty (object, property, original)
|
||||
|
||||
for _, lookupName in ipairs(self.lookupNames) do
|
||||
local lookup = rawget(object, lookupName)
|
||||
or object.attributes and rawget(object.attributes, lookupName)
|
||||
if lookup then
|
||||
if type(lookup) ~= 'table' then
|
||||
lookup = { lookup }
|
||||
|
||||
@@ -41,7 +41,7 @@ return function (config)
|
||||
['menu.item'] = {
|
||||
padding = 4,
|
||||
align = 'left middle',
|
||||
textColor = { 0, 0, 0 }
|
||||
color = { 0, 0, 0 }
|
||||
},
|
||||
['menu.item_active'] = {
|
||||
background = highlight,
|
||||
|
||||
114
luigi/widget.lua
114
luigi/widget.lua
@@ -8,6 +8,7 @@ local ROOT = (...):gsub('[^.]*$', '')
|
||||
|
||||
local Backend = require(ROOT .. 'backend')
|
||||
local Event = require(ROOT .. 'event')
|
||||
local Attribute = require(ROOT .. 'attribute')
|
||||
local Font = Backend.Font
|
||||
|
||||
local Widget = {}
|
||||
@@ -16,18 +17,15 @@ Event.injectBinders(Widget)
|
||||
|
||||
Widget.isWidget = true
|
||||
|
||||
--[[--
|
||||
Widget type registry.
|
||||
--]]--
|
||||
Widget.typeDecorators = {
|
||||
button = require(ROOT .. 'widget.button'), -- A simple button
|
||||
menu = require(ROOT .. 'widget.menu'), -- A menu bar
|
||||
['menu.item'] = require(ROOT .. 'widget.menu.item'), -- A menu item
|
||||
progress = require(ROOT .. 'widget.progress'), -- A progress bar
|
||||
sash = require(ROOT .. 'widget.sash'), -- Resizes nearby widgets
|
||||
slider = require(ROOT .. 'widget.slider'), -- Slides to adjust a normalized value
|
||||
stepper = require(ROOT .. 'widget.stepper'), -- Steps through a series of choices
|
||||
text = require(ROOT .. 'widget.text'), -- A text entry widget
|
||||
button = require(ROOT .. 'widget.button'),
|
||||
menu = require(ROOT .. 'widget.menu'),
|
||||
['menu.item'] = require(ROOT .. 'widget.menu.item'),
|
||||
progress = require(ROOT .. 'widget.progress'),
|
||||
sash = require(ROOT .. 'widget.sash'),
|
||||
slider = require(ROOT .. 'widget.slider'),
|
||||
stepper = require(ROOT .. 'widget.stepper'),
|
||||
text = require(ROOT .. 'widget.text'),
|
||||
}
|
||||
|
||||
--[[--
|
||||
@@ -45,9 +43,9 @@ function Widget.register (name, decorator)
|
||||
Widget.typeDecorators[name] = decorator
|
||||
end
|
||||
|
||||
-- look for properties in shadow props, Widget, style, and theme
|
||||
-- look for properties in attributes, Widget, style, and theme
|
||||
local function metaIndex (self, property)
|
||||
local value = self.shadowProperties[property]
|
||||
local value = self.attributes[property]
|
||||
if value ~= nil then return value end
|
||||
|
||||
local value = Widget[property]
|
||||
@@ -62,92 +60,28 @@ local function metaIndex (self, property)
|
||||
return theme and theme:getProperty(self, property)
|
||||
end
|
||||
|
||||
-- setting shadow properties causes special behavior
|
||||
-- setting attributes triggers special behavior
|
||||
local function metaNewIndex (self, property, value)
|
||||
if property == 'font' or property == 'fontSize' then
|
||||
self.shadowProperties[property] = value
|
||||
self.fontData = nil
|
||||
self.textData = nil
|
||||
end
|
||||
|
||||
if property == 'text' or property == 'textColor'
|
||||
or property == 'align' or property == 'wrap' then
|
||||
self.shadowProperties[property] = value
|
||||
self.textData = nil
|
||||
return
|
||||
end
|
||||
|
||||
if property == 'width' then
|
||||
value = value and math.max(value, self.minwidth or 0)
|
||||
self.shadowProperties[property] = value
|
||||
if self.wrap then
|
||||
self.textData = nil
|
||||
end
|
||||
Widget.reshape(self.parent or self)
|
||||
return
|
||||
end
|
||||
|
||||
if property == 'height' then
|
||||
value = value and math.max(value, self.minheight or 0)
|
||||
self.shadowProperties[property] = value
|
||||
Widget.reshape(self.parent or self)
|
||||
return
|
||||
end
|
||||
|
||||
if property == 'value' then
|
||||
local oldValue = self.value
|
||||
self.shadowProperties[property] = value
|
||||
self:bubbleEvent('Change', {
|
||||
value = value,
|
||||
oldValue = oldValue,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
if property == 'key' then
|
||||
self.shadowProperties[property] = value
|
||||
|
||||
if not value then return end
|
||||
|
||||
local mainKey = (value):match '[^%-]+$'
|
||||
local alt = (value):match 'alt%-' and 1 or 0
|
||||
local ctrl = (value):match 'ctrl%-' and 2 or 0
|
||||
local shift = (value):match 'shift%-' and 4 or 0
|
||||
local modifierFlags = alt + ctrl + shift
|
||||
|
||||
local layout = self.layout.master or self.layout
|
||||
|
||||
layout.accelerators[modifierFlags][mainKey] = self
|
||||
return
|
||||
end
|
||||
|
||||
if property == 'id' then
|
||||
self.shadowProperties[property] = value
|
||||
|
||||
if not value then return end
|
||||
|
||||
local layout = self.layout.master or self.layout
|
||||
|
||||
layout[value] = self
|
||||
return
|
||||
if Attribute[property] then
|
||||
return Attribute[property](self, value)
|
||||
end
|
||||
|
||||
rawset(self, property, value)
|
||||
end
|
||||
|
||||
local shadowKeys = {
|
||||
'id', 'key', 'value',
|
||||
'width', 'height',
|
||||
'font', 'fontSize',
|
||||
'text', 'textColor',
|
||||
'align', 'wrap',
|
||||
}
|
||||
local attributeNames = {}
|
||||
|
||||
for name in pairs(Attribute) do
|
||||
attributeNames[#attributeNames + 1] = name
|
||||
end
|
||||
|
||||
--[[--
|
||||
Widget pseudo-constructor.
|
||||
|
||||
@function Luigi.Widget
|
||||
|
||||
@within Constructor
|
||||
|
||||
@tparam Layout layout
|
||||
The layout this widget belongs to.
|
||||
|
||||
@@ -163,18 +97,18 @@ local function metaCall (Widget, layout, self)
|
||||
self.layout = layout
|
||||
self.position = { x = nil, y = nil }
|
||||
self.dimensions = { width = nil, height = nil }
|
||||
self.shadowProperties = {}
|
||||
self.attributes = {}
|
||||
|
||||
setmetatable(self, { __index = metaIndex, __newindex = metaNewIndex })
|
||||
|
||||
for _, property in ipairs(shadowKeys) do
|
||||
for _, property in ipairs(attributeNames) do
|
||||
local value = rawget(self, property)
|
||||
rawset(self, property, nil)
|
||||
self[property] = value
|
||||
end
|
||||
|
||||
self.type = self.type or 'generic'
|
||||
self.fontData = Font(self.font, self.fontSize, self.textColor)
|
||||
self.fontData = Font(self.font, self.size, self.color)
|
||||
|
||||
-- layout:addWidget(self)
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
--[[--
|
||||
A simple button.
|
||||
|
||||
@widget button
|
||||
--]]--
|
||||
|
||||
return function (self)
|
||||
|
||||
end
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
--[[--
|
||||
A menu bar.
|
||||
|
||||
@widget menu
|
||||
--]]--
|
||||
|
||||
return function (self)
|
||||
|
||||
for index, child in ipairs(self) do
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
--[[--
|
||||
A menu item.
|
||||
|
||||
When a `menu` is created, any sub-items not having a specified type
|
||||
are automatically given a type of `'menu.item'`. These widgets should
|
||||
not be explicitly created.
|
||||
|
||||
@widget menu.item
|
||||
--]]--
|
||||
local ROOT = (...):gsub('[^.]*.[^.]*.[^.]*$', '')
|
||||
|
||||
local Layout, Event
|
||||
@@ -125,7 +134,7 @@ local function initialize (self)
|
||||
local textWidth = self.fontData:getAdvance(text) + pad * 2
|
||||
|
||||
if isSubmenu then
|
||||
local tc = self.textColor or { 0, 0, 0, 255 }
|
||||
local tc = self.color or { 0, 0, 0, 255 }
|
||||
local keyColor = { tc[1], tc[2], tc[3], 0x90 }
|
||||
local edgeType
|
||||
if #self.items > 0 then
|
||||
@@ -139,7 +148,7 @@ local function initialize (self)
|
||||
self:addChild { icon = icon, width = self.height }
|
||||
self:addChild { text = text, width = textWidth }
|
||||
self:addChild { text = key, align = 'middle right',
|
||||
minwidth = self.height, textColor = keyColor, type = edgeType }
|
||||
minwidth = self.height, color = keyColor, type = edgeType }
|
||||
|
||||
self.icon = nil
|
||||
self.text = nil
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
--[[--
|
||||
A progress bar.
|
||||
|
||||
Set the widget's `value` property to a decimal value
|
||||
between 0 and 1 (inclusive) to change the width of the bar.
|
||||
|
||||
@widget progress
|
||||
--]]--
|
||||
|
||||
return function (self)
|
||||
self.value = 0
|
||||
self.flow = 'x' -- TODO: support vertical progress?
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
--[[--
|
||||
A sash.
|
||||
|
||||
Dragging this widget resizes the widgets adjacent to it.
|
||||
A sash must be adjacent to a widget with a specified size
|
||||
in the same direction as the parent element's `flow`.
|
||||
|
||||
For example, if the parent of the sash is `flow = 'x'`
|
||||
then either or both of the siblings next to the sash
|
||||
must have a specified `width` property.
|
||||
|
||||
@widget sash
|
||||
--]]--
|
||||
|
||||
local function setDimension (widget, name, size)
|
||||
if not widget.parent then
|
||||
widget[name] = size
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
--[[--
|
||||
A slider.
|
||||
|
||||
Dragging this widget changes its `value` property to a
|
||||
number between 0 and 1, inclusive.
|
||||
|
||||
@widget slider
|
||||
--]]--
|
||||
|
||||
return function (self)
|
||||
|
||||
local function clamp (value)
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
--[[--
|
||||
A stepper.
|
||||
|
||||
This widget is composed of two buttons and a content area.
|
||||
Upon creation, this widget's children are moved into an
|
||||
`items` property. The items are displayed one at a time in
|
||||
the content area. Pressing the buttons cycles through the
|
||||
item displayed in the content area.
|
||||
|
||||
@widget stepper
|
||||
--]]--
|
||||
|
||||
return function (self)
|
||||
self.items = {}
|
||||
self.index = 1
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
--[[--
|
||||
A text entry area.
|
||||
|
||||
@widget text
|
||||
--]]--
|
||||
local ROOT = (...):gsub('[^.]*.[^.]*$', '')
|
||||
|
||||
local utf8 = require(ROOT .. 'utf8')
|
||||
@@ -231,7 +236,7 @@ return function (self)
|
||||
local x, y, w, h = self:getRectangle(true, true)
|
||||
local width, height = endX - startX, h
|
||||
local font = self.fontData
|
||||
local textColor = self.textColor or { 0, 0, 0, 255 }
|
||||
local color = self.color or { 0, 0, 0, 255 }
|
||||
local textTop = math.floor(y + (h - font:getLineHeight()) / 2)
|
||||
|
||||
Backend.push()
|
||||
@@ -242,12 +247,12 @@ return function (self)
|
||||
Backend.setColor(self.highlight)
|
||||
Backend.drawRectangle('fill', startX, y, width, height)
|
||||
if Backend.getTime() % 2 < 1.75 then
|
||||
Backend.setColor(textColor)
|
||||
Backend.setColor(color)
|
||||
Backend.drawRectangle('fill', endX, y, 1, height)
|
||||
end
|
||||
|
||||
-- draw text
|
||||
Backend.setColor(textColor)
|
||||
Backend.setColor(color)
|
||||
Backend.print(self.value, x - self.scrollX, textTop)
|
||||
if not self.focused then
|
||||
Backend.pop()
|
||||
|
||||
Reference in New Issue
Block a user