Merge branch 'master' into master

This commit is contained in:
Yx 2017-09-23 09:46:18 +08:00 committed by GitHub
commit 02c4c05a0d
10 changed files with 162 additions and 16 deletions

View file

@ -36,6 +36,10 @@ function suit.getOptionsAndSize(opt, ...)
end
-- gui state
function suit:setHovered(id)
return self.hovered ~= id
end
function suit:anyHovered()
return self.hovered ~= nil
end
@ -48,6 +52,10 @@ function suit:wasHovered(id)
return id == self.hovered_last
end
function suit:setActive(id)
return self.active ~= nil
end
function suit:anyActive()
return self.active ~= nil
end
@ -56,6 +64,15 @@ function suit:isActive(id)
return id == self.active
end
function suit:setHit(id)
self.hit = id
-- simulate mouse release on button -- see suit:mouseReleasedOn()
self.mouse_button_down = false
self.active = id
self.hovered = id
end
function suit:anyHit()
return self.hit ~= nil
end
@ -182,7 +199,7 @@ end
function suit:draw()
self:exitFrame()
love.graphics.push('all')
for i = 1,self.draw_queue.n do
for i = self.draw_queue.n,1,-1 do
self.draw_queue[i]()
end
love.graphics.pop()

BIN
docs/_static/different-ids.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

BIN
docs/_static/same-ids.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

View file

@ -231,6 +231,71 @@ available space (but you have to tell how much space there is beforehand).
Refer to the :doc:`Layout <layout>` documentation for more information.
Widget ids
----------
Each widget is identified by an ``id`` [4]_. Internally, this ``id`` is used t
figure out which widget should handle user input like mouse clicks and keyboard
presses.
Unless specified otherwise, the ``id`` is the same as the first argument, i.e.,
the ``id`` of ``Button("Hello, World!", ...)`` will be the string
``"Hello, World!"``.
In almost all of the cases, this will work fine and you don't have to worry about
this ``id`` business.
Well, almost. Problems arise when two widgets share the same id, like here::
local suit = require 'suit'
function love.update()
suit.layout:reset(100, 100)
suit.layout:padding(10)
if suit.Button("Button", suit.layout:row(200, 30)).hit then
love.graphics.setBackgroundColor(255,255,255)
end
if suit.Button("Button", suit.layout:row()).hit then
love.graphics.setBackgroundColor(0,0,0)
end
end
function love.draw()
suit:draw()
end
.. image:: _static/same-ids.gif
If the first button is hovered, both buttons will be highlighted, and if it pressed,
both actions will be carried out.
Hovering the second button will not affect the first, and clicking it will highlight
both buttons, but only execute the action of the second button [5]_.
Luckily, there is a fix: you can specify the ``id`` of any widget using the ``id``
option, like so::
local suit = require 'suit'
function love.update()
suit.layout:reset(100, 100)
suit.layout:padding(10)
if suit.Button("Button", {id=1}, suit.layout:row(200, 30)).hit then
love.graphics.setBackgroundColor(255,255,255)
end
if suit.Button("Button", {id=2}, suit.layout:row()).hit then
love.graphics.setBackgroundColor(0,0,0)
end
end
function love.draw()
suit:draw()
end
.. image:: _static/different-ids.gif
Now, events from one button will not propagate to the other. Here, the both ``id`` s
are numbers, but you can use any Lua value except ``nil`` and ``false``.
Themeing
--------
@ -325,3 +390,6 @@ table or use some metatable magic::
.. [1] But it thinks you can handle that.
.. [2] Proportion determined by rigorous scientific experiments [3]_.
.. [3] And theoretic reasoning. Mostly that, actually.
.. [4] Welcome to the tautology club!
.. [5] Immediate mode is to blame: When the second button is processed, the first
one is already fully evaluated. Time can not be reversed, not even by love.

View file

@ -67,6 +67,8 @@ according to the size of the popped layout.
Used for nested row/column layouts.
.. _layout-row:
.. function:: row(w,h)
:param mixed w,h: Cell width and height (optional).
@ -91,14 +93,20 @@ Used to provide the last four arguments to a widget, e.g.::
suit.Button("Options", suit.layout:row())
suit.Button("Quit", suit.layout:row(nil, "median"))
.. function:: down(w,h)
An alias for :ref:`layout:row() <layout-row>`.
.. _layout-col:
.. function:: col(w,h)
:param mixed w,h: Cell width and height (optional).
:returns: Position and size of the cell: ``x,y,w,h``.
Creates a new cell right to the current cell with width ``w`` and height ``h``.
If either ``w`` or ``h`` is omitted, the value is set the last used value. Both
``w`` and ``h`` can be a string, which takes the following meaning:
Creates a new cell to the right of the current cell with width ``w`` and height
``h``. If either ``w`` or ``h`` is omitted, the value is set the last used
value. Both ``w`` and ``h`` can be a string, which takes the following meaning:
``max``
Maximum of all values since the last reset.
@ -114,6 +122,59 @@ Used to provide the last four arguments to a widget, e.g.::
suit.Button("OK", suit.layout:col(100,30))
suit.Button("Cancel", suit.layout:col("max"))
.. function:: right(w,h)
An alias for :ref:`layout:col() <layout-col>`.
.. function:: up(w,h)
:param mixed w,h: Cell width and height (optional).
:returns: Position and size of the cell: ``x,y,w,h``.
Creates a new cell above the current cell with width ``w`` and height ``h``. If
either ``w`` or ``h`` is omitted, the value is set the last used value. Both
``w`` and ``h`` can be a string, which takes the following meaning:
``max``
Maximum of all values since the last reset.
``min``
Mimimum of all values since the last reset.
``median``
Median of all values since the last reset.
Be careful when mixing ``up()`` and :ref:`layout:row() <layout-row>`, as suit
does no checking to make sure cells don't overlap. e.g.::
suit.Button("A", suit.layout:row(100,30))
suit.Button("B", suit.layout:row())
suit.Button("Also A", suit.layout:up())
.. function:: left(w,h)
:param mixed w,h: Cell width and height (optional).
:returns: Position and size of the cell: ``x,y,w,h``.
Creates a new cell to the left of the current cell with width ``w`` and height
``h``. If either ``w`` or ``h`` is omitted, the value is set the last used
value. Both ``w`` and ``h`` can be a string, which takes the following meaning:
``max``
Maximum of all values since the last reset.
``min``
Mimimum of all values since the last reset.
``median``
Median of all values since the last reset.
Be careful when mixing ``left()`` and :ref:`layout:col() <layout-col>`, as suit
does no checking to make sure cells don't overlap. e.g.::
suit.Button("A", suit.layout:col(100,30))
suit.Button("B", suit.layout:col())
suit.Button("Also A", suit.layout:left())
Precomputed Layouts
-------------------

View file

@ -30,7 +30,7 @@ Creates a label at position ``(x,y)`` with width ``w`` and height ``h``.
.. function:: ImageButton(normal, options, x,y)
:param Image notmal: Image of the button in normal state.
:param Image normal: Image of the button in normal state.
:param table options: Widget options.
:param numbers x,y: Upper left corner of the widget.
:returns: Return state (see below).

View file

@ -11,11 +11,14 @@ return setmetatable({
getOptionsAndSize = suit.getOptionsAndSize,
-- core functions
setHovered = function(...) return instance:setHovered(...) end,
anyHovered = function(...) return instance:anyHovered(...) end,
isHovered = function(...) return instance:isHovered(...) end,
wasHovered = function(...) return instance:wasHovered(...) end,
anyActive = function(...) return instance:anyActive(...) end,
setActive = function(...) return instance:setActive(...) end,
isActive = function(...) return instance:isActive(...) end,
setHit = function(...) return instance:setHit(...) end,
anyHit = function(...) return instance:anyHit(...) end,
isHit = function(...) return instance:isHit(...) end,

View file

@ -49,6 +49,11 @@ return function(core, input, ...)
end
-- user interaction
if input.forcefocus ~= nil and input.forcefocus then
core.active = opt.id
input.forcefocus = false
end
opt.state = core:registerHitbox(opt.id, x,y,w,h)
opt.hasKeyboardFocus = core:grabKeyboardFocus(opt.id)

View file

@ -37,20 +37,12 @@ end
Layout.nextDown = Layout.nextRow
function Layout:nextUp()
return self._x, self._y - self._h - self._pady
end
function Layout:nextCol()
return self._x + self._w + self._padx, self._y
end
Layout.nextRight = Layout.nextCol
function Layout:nextLeft()
return self._x - self._w - self._padx, self._y
end
function Layout:push(x,y)
self._stack[#self._stack+1] = {
self._x, self._y,
@ -152,7 +144,7 @@ Layout.down = Layout.row
function Layout:up(w, h)
w,h = calc_width_height(self, w, h)
local x,y = self._x, self._y - (self._h or 0)
local x,y = self._x, self._y - (self._h and h or 0)
if not self._isFirstCell then
y = y - self._pady
@ -184,7 +176,7 @@ Layout.right = Layout.col
function Layout:left(w, h)
w,h = calc_width_height(self, w, h)
local x,y = self._x - (self._w or 0), self._y
local x,y = self._x - (self._w and w or 0), self._y
if not self._isFirstCell then
x = x - self._padx

View file

@ -19,7 +19,7 @@ function theme.getColorForState(opt)
end
function theme.drawBox(x,y,w,h, colors, cornerRadius)
local colors = colors or theme.getColorForState(opt)
colors = colors or theme.getColorForState(opt)
cornerRadius = cornerRadius or theme.cornerRadius
w = math.max(cornerRadius/2, w)
if h < cornerRadius/2 then