cleaned the suit dep as I put the whole git in it

This commit is contained in:
2021-05-08 11:41:53 +02:00
parent 1560bae757
commit 93efcd6829
20 changed files with 0 additions and 2031 deletions

77
deps/suit/README.md vendored
View File

@@ -1,77 +0,0 @@
# SUIT
Simple User Interface Toolkit for LÖVE.
SUIT is an immediate mode GUI library.
## Documentation?
Over at [readthedocs](http://suit.readthedocs.org/en/latest/).
## Looks?
Here is how SUIT looks like with the default theme:
![Demo of all widgets](docs/_static/demo.gif)
More info and code is over at [readthedocs](http://suit.readthedocs.org/en/latest/).
## Hello, World!
```lua
-- suit up
local suit = require 'suit'
-- storage for text input
local input = {text = ""}
-- make love use font which support CJK text
function love.load()
local font = love.graphics.newFont("NotoSansHans-Regular.otf", 20)
love.graphics.setFont(font)
end
-- all the UI is defined in love.update or functions that are called from here
function love.update(dt)
-- put the layout origin at position (100,100)
-- the layout will grow down and to the right from this point
suit.layout:reset(100,100)
-- put an input widget at the layout origin, with a cell size of 200 by 30 pixels
suit.Input(input, suit.layout:row(200,30))
-- put a label that displays the text below the first cell
-- the cell size is the same as the last one (200x30 px)
-- the label text will be aligned to the left
suit.Label("Hello, "..input.text, {align = "left"}, suit.layout:row())
-- put an empty cell that has the same size as the last cell (200x30 px)
suit.layout:row()
-- put a button of size 200x30 px in the cell below
-- if the button is pressed, quit the game
if suit.Button("Close", suit.layout:row()).hit then
love.event.quit()
end
end
function love.draw()
-- draw the gui
suit.draw()
end
function love.textedited(text, start, length)
-- for IME input
suit.textedited(text, start, length)
end
function love.textinput(t)
-- forward text input to SUIT
suit.textinput(t)
end
function love.keypressed(key)
-- forward keypresses to SUIT
suit.keypressed(key)
end
```

View File

@@ -1,192 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/hump.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/hump.qhc"
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/hump"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/hump"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 KiB

293
deps/suit/docs/conf.py vendored
View File

@@ -1,293 +0,0 @@
# -*- coding: utf-8 -*-
#
# SUIT documentation build configuration file, created by
# sphinx-quickstart on Sat Oct 10 13:10:12 2015.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
import shlex
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.mathjax',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'SUIT'
copyright = u'2016, Matthias Richter'
author = u'Matthias Richter'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
release = '1.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'suitdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'suit.tex', u'SUIT Documentation',
u'Matthias Richter', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'SUIT', u'SUIT Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'SUIT', u'SUIT Documentation',
author, 'SUIT', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
primary_domain = "js"
highlight_language = "lua"
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

View File

@@ -1,241 +0,0 @@
Core Functions
==============
The core functions can be divided into two parts: Functions of interest to the
user and functions of interest to the (widget) developer.
External Interface
------------------
Drawing
^^^^^^^
.. function:: draw()
Draw the GUI - call in ``love.draw``.
.. data:: theme
The current theme. See :doc:`themes`.
Mouse Input
^^^^^^^^^^^
.. function:: updateMouse(x,y, buttonDown)
:param number x,y: Position of the mouse.
:param boolean buttonDown: Whether the mouse button is down.
Update mouse position and button status. You do not need to call this function,
unless you use some screen transformation (e.g., scaling, camera systems, ...).
Keyboard Input
^^^^^^^^^^^^^^
.. function:: keypressed(key)
:param KeyConstant key: The pressed key.
Forwards a ``love.keypressed(key)`` event to SUIT.
.. function:: textinput(char)
:param string char: The pressed character
Forwards a ``love.textinput(key)`` event to SUIT.
GUI State
^^^^^^^^^
.. function:: anyHovered()
:returns: ``true`` if any widget is hovered by the mouse.
Checks if any widget is hovered by the mouse.
.. function:: isHovered(id)
:param mixed id: Identifier of the widget.
:returns: ``true`` if the widget is hovered by the mouse.
Checks if the widget identified by ``id`` is hovered by the mouse.
.. function:: wasHovered(id)
:param mixed id: Identifier of the widget.
:returns: ``true`` if the widget was in the hovered by the mouse in the last frame.
Checks if the widget identified by ``id`` was hovered by the mouse in the last frame.
.. function:: anyActive()
:returns: ``true`` if any widget is in the ``active`` state.
Checks whether the mouse button is pressed and held on any widget.
.. function:: isActive(id)
:param mixed id: Identifier of the widget.
:returns: ``true`` if the widget is in the ``active`` state.
Checks whether the mouse button is pressed and held on the widget identified by ``id``.
.. function:: anyHit()
:returns: ``true`` if the mouse was pressed and released on any widget.
Check whether the mouse was pressed and released on any widget.
.. function:: isHit(id)
:param mixed id: Identifier of the widget.
:returns: ``true`` if the mouse was pressed and released on the widget.
Check whether the mouse was pressed and released on the widget identified by ``id``.
Internal Helpers
----------------
.. function:: getOptionsAndSize(...)
:param mixed ...: Varargs.
:returns: ``options, x,y,w,h``.
Converts varargs to option table and size definition. Used in the widget
functions.
.. function:: registerDraw(f, ...)
:param function f: Function to call in ``draw()``.
:param mixed ...: Arguments to f.
Registers a function to be executed during :func:`draw()`. Used by widgets to
make themselves visible.
.. function:: enterFrame()
Prepares GUI state when entering a frame.
.. function:: exitFrame()
Clears GUI state when exiting a frame.
Mouse Input
^^^^^^^^^^^
.. function:: mouseInRect(x,y,w,h)
:param numbers x,y,w,h: Rectangle definition.
:returns: ``true`` if the mouse cursor is in the rectangle.
Checks whether the mouse cursor is in the rectangle defined by ``x,y,w,h``.
.. function:: registerMouseHit(id, ul_x, ul_y, hit)
:param mixed id: Identifier of the widget.
:param numbers ul_x, ul_y: Upper left corner of the widget.
:param function hit: Function to perform the hit test.
Registers a hit-test defined by the function ``hit`` for the widget identified
by ``id``. Sets the widget to ``hovered`` if th hit-test returns ``true``. Sets the
widget to ``active`` if the hit-test returns ``true`` and the mouse button is
pressed.
The hit test receives coordinates in the coordinate system of the widget, i.e.
``(0,0)`` is the upper left corner of the widget.
.. function:: registerHitbox(id, x,y,w,h)
:param mixed id: Identifier of the widget.
:param numbers x,y,w,h: Rectangle definition.
Registers a hitbox for the widget identified by ``id``. Literally this function::
function registerHitbox(id, x,y,w,h)
return registerMouseHit(id, x,y, function(u,v)
return u >= 0 and u <= w and v >= 0 and v <= h
end)
end
.. function:: mouseReleasedOn(id)
:param mixed id: Identifier of the widget.
:returns: ``true`` if the mouse was released on the widget.
Checks whether the mouse button was released on the widget identified by ``id``.
.. function:: getMousePosition()
:returns: Mouse positon ``mx, my``.
Get the mouse position.
Keyboard Input
^^^^^^^^^^^^^^
.. function:: getPressedKey()
:returns: KeyConstant
Get the currently pressed key (if any).
.. function:: grabKeyboardFocus(id)
:param mixed id: Identifier of the widget.
Try to grab keyboard focus. Successful only if the widget is in the ``active``
state.
.. function:: hasKeyboardFocus(id)
:param mixed id: Identifier of the widget.
:returns: ``true`` if the widget has keyboard focus.
Checks whether the widget identified by ``id`` currently has keyboard focus.
.. function:: keyPressedOn(id, key)
:param mixed id: Identifier of the widget.
:param KeyConstant key: Key to query.
:returns: ``true`` if ``key`` was pressed on the widget.
Checks whether the key ``key`` was pressed while the widget identified by
``id`` has keyboard focus.
Instancing
----------
.. function:: new()
:returns: Separate UI state.
Create a separate UI and layout state. Everything that happens in the new
state will not affect any other state. You can use the new state like the
"global" state ``suit``, but call functions with the colon syntax instead of
the dot syntax, e.g.::
function love.load()
dress = suit.new()
end
function love.update()
dress.layout:reset()
dress:Label("Hello, World!", dress.layout:row(200,30))
dress:Input(input, dress.layout:row())
end
function love.draw()
dress:draw()
end
.. warning::
Unlike UI and layout state, the theme might be shared with other states.
Changes in a shared theme will be shared across all themes.
See the :ref:`Instance Theme <instance-theme>` subsection in the
:doc:`gettingstarted` guide.

View File

@@ -1,398 +0,0 @@
Getting Started
===============
Before actually getting started, it is important to understand the motivation
and mechanics behind SUIT:
- **Immediate mode is better than retained mode**
- **Layout should not care about content**
- **Less is more**
Immediate mode?
---------------
With classical (retained) mode libraries you typically have a stage where you
create the whole UI when the program initializes. This includes what happens
when events like button presses or slider changes occur. After that point, the
GUI is expected to not change very much. This is great for word processors
where the interaction is consistent and straightforward, but bad for games,
where everything changes all the time.
With immediate mode libraries, on the other hand, the GUI is created every
frame from scratch. Because that would be wasteful, there are no widget
objects. Instead, widgets are created by functions that react to UI state and
present some data. Where this data comes from and how it is maintained does
not concern the widget at all. This is, after all, your job. This gives great
control over what is shown where and when. The widget code can be right next
to the code that does what should happen if the widget state changes. The
layout is also very flexible: adding a widget is one more function call, and if
you want to hide a widget, you simply don't call the corresponding function.
This separation of data and behaviour is great when a lot of stuff is going on,
but takes a bit of time getting used to.
What SUIT is
^^^^^^^^^^^^
SUIT is simple: It provides only a few basic widgets that are important for
games:
- :func:`Buttons <Button>` (including :func:`Image Buttons <ImageButton>`)
- :func:`Text Labels <Label>`
- :func:`Checkboxes <Checkbox>`
- :func:`Text Input <Input>`
- :func:`Value Sliders <Slider>`
SUIT is comfortable: It has a straightforward, yet effective row/column-based
layout engine.
SUIT is adaptable: It is possible to change the color scheme, single drawing
functions for all widget or the whole theme.
SUIT is hackable: Custom widgets can leverage the extensive :doc:`core library
<core>`.
**SUIT is good at games!**
What SUIT is not
^^^^^^^^^^^^^^^^
SUIT is not a complete GUI library: It does not provide dropdowns, table views,
menu bars, modal dialogs, etc.
SUIT is not a complete GUI library: It does not have a markup language or tools
to design a user interface.
SUIT is not a complete GUI library: It does not take control of the runtime.
You have to do everything yourself [1]_.
**SUIT is not good at processing words!**
Hello, World!
-------------
SUITing up is is straightforward: Define your GUI in ``love.update()``, and
draw it in ``love.draw()``::
suit = require 'suit'
local show_message = false
function love.update(dt)
-- Put a button on the screen. If hit, show a message.
if suit.Button("Hello, World!", 100,100, 300,30).hit then
show_message = true
end
-- if the button was pressed at least one time, but a label below
if show_message then
suit.Label("How are you today?", 100,150, 300,30)
end
end
function love.draw()
suit.draw()
end
This will produce this UI:
.. image:: _static/hello-world.gif
The two widgets (the button and the label) are each created by a function call
(:func:`suit.Button <Button>` and :func:`suit.Label <Label>`). The first
argument to a widget function always defines the *payload* of the widget.
Different widgets expect different payloads.
Here, both :func:`suit.Button <Button>` and :func:`suit.Label <Label>` expect a
string.
The last four arguments of a widget function define the position and dimension
of the widget.
The function returns a table that indicates the UI state of the widget.
Here, the state ``hit`` is used to figure out if the mouse was clicked and
released on the button. See :doc:`Widgets <widgets>` for more info on widget
states.
Mutable state
-------------
Widgets that mutate some state - input boxes, checkboxes and sliders - expect
a table as their payload, e.g.::
local slider = {value = 1, min = 0, max = 2}
function love.update(dt)
suit.Slider(slider, 100,100, 200,20)
suit.Label(tostring(slider.value), 300,100, 200,20)
end
.. image:: _static/mutable-state.gif
The widget function updates the payload when some user interaction occurs. In
the above example, ``slider.value`` may be changed by the :func:`Slider`
widget. The value is then shown by a :func:`Label` next to the slider.
Options
-------
You can define optional, well, options after the payload. Most options affect
how the widget is drawn. For example, to align the label text to the left::
local slider = {value = 1, max = 2}
function love.update(dt)
suit.Slider(slider, 100,100, 200,30)
suit.Label(tostring(slider.value), {align = "left"}, 300,100, 200,30)
end
.. image:: _static/options.gif
What options are available and what they are doing depends on the widget and
the theme. See :doc:`Widgets <widgets>` for more info on widget options.
Keyboard input
--------------
The :func:`Input` widget requires that you forward the ``keypressed`` and
``textinput`` events to SUIT::
local input = {text = ""}
function love.update(dt)
suit.Input(input, 100,100,200,30)
suit.Label("Hello, "..input.text, {align="left"}, 100,150,200,30)
end
-- forward keyboard events
function love.textinput(t)
suit.textinput(t)
end
function love.keypressed(key)
suit.keypressed(key)
end
.. image:: _static/keyboard.gif
The :func:`Slider` widget can also react to keyboard input. The mouse state is
automatically updated, but you can provide your own version of reality if you
need to. See the :doc:`Core functions <core>` for more details.
Layout
------
It is tedious to calculate the position and size of each widget you want to put
on the screen. Especially when all you want is to put three buttons beneath
each other. SUIT implements a simple, yet effective layout engine. All the
engine does is put cells next to each other (below or right). It does not care
what you put into those cells, but assumes that you probably need them for
widgets. Cells are reported by four numbers (left, top, width and height) that
you can directly pass as the final four arguments to the widget functions.
If you have ever dabbled with `Qt's <http://qt.io>`_ ``QBoxLayout``, you
already know 89% [2]_ of what you need to know.
Hello, World! can be rewritten as follows::
suit = require 'suit'
local show_message = false
function love.update(dt)
-- put the layout origin at position (100,100)
-- cells will grow down and to the right of the origin
-- note the colon syntax
suit.layout:reset(100,100)
-- put 10 extra pixels between cells in each direction
suit.layout:padding(10,10)
-- construct a cell of size 300x30 px and put the button into it
if suit.Button("Hello, World!", suit.layout:row(300,30)).hit then
show_message = true
end
-- add another cell below the first cell
-- the size of the cell is the same as the first cell
if show_message then
suit.Label("How are you today?", suit.layout:row())
end
end
function love.draw()
suit.draw()
end
.. image:: _static/layout.gif
At the beginning of each frame, the layout origin (and some internal layout
state) has to be reset. You can also define optional padding between cells.
Cells are added using ``layout:row(w,h)`` (which puts the new cell below the
old cell) and ``layout:col(w,h)`` (which puts the new cell to the right of the
old cell). If omitted, the width and height of the new cell are copied from
the old cell. There are also special identifiers that calculate the size from
the sizes of all cells that were created since the last ``reset()``: ``max``,
``min`` and ``median``. They do what you expect them to do.
It is also possible to nest cells and to let cells dynamically fill the
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 to
figure out which widget should handle user input like mouse clicks and keyboard
presses.
Unless specified otherwise, the ``id`` is the same as the payload, 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
--------
SUIT lets you customize how any widget (except :func:`ImageButton`) is drawn.
Each widget (except, :func:`you know <ImageButton>`) is drawn by a function in
the table ``suit.theme``. Conveniently, the name of the function
responsible for drawing a widget is named after it, so, a button is drawn by
the function ``suit.theme.Button``. If you want to change how a button is
drawn, simply overwrite the function. If you want to redecorate completely, it
might be easiest to start from scratch and swap the whole table.
However, if you just don't like the colors, the default theme is open to change.
It requires you to change the background (``bg``) and foreground (``fg``) color
of three possible widget states: ``normal``, when nothing out of
the ordinary happened, ``hovered``, when the mouse hovers above a widget, and
``active``, when the mouse hovers above, and the mouse button is pressed (but
not yet released) on the widget. The colors are saved in the table
``suit.theme.color``. The default color scheme is this::
suit.theme.color = {
normal = {bg = { 66, 66, 66}, fg = {188,188,188}},
hovered = {bg = { 50,153,187}, fg = {255,255,255}},
active = {bg = {255,153, 0}, fg = {225,225,225}}
}
You can also do minimally invasive surgery::
function love.load()
suit.theme.color.normal.fg = {255,255,255}
suit.theme.color.hovered = {bg = {200,230,255}, fg = {0,0,0}}
end
GUI Instances
-------------
Sometimes you might feel the need to separate parts of the GUI. Maybe certain
UI elements should always be drawn before or after other UI elements, or maybe
you don't want the UI state to "leak" (e.g., from a stacked pause gamestate to
the main gamestate).
For this reason, SUIT allows you to create GUI instances::
local dress = suit.new()
The IO and layout state of ``dress`` is totally contained in the instance and
does not affect any other instances (including the "global" instance ``suit``).
In particular, ``suit.draw()`` will not draw anything from ``dress``. Luckily,
you can do that yourself::
dress:draw()
Notice that instances require that you use the colon syntax. This is true for
every `core <core>` function as well as the widgets. To create a button, for
example, you have to write::
dress:Button("Click?", dress.layout:row())
.. _instance-theme:
Instance Theme
^^^^^^^^^^^^^^
Unlike UI and layout state, themes **are** shared among instances. The reason
is that the ``suit.theme`` and ``dress.theme`` are **references**, and point to
the same table (unless you make either of them point somewhere else). Usually
this is a feature, but please still consider this
.. warning::
Changes in a shared theme will be shared across GUI instances.
If this is an issue---for example because you only want to change the color
scheme of an instance---you can either `deep-copy
<http://hump.readthedocs.org/en/latest/class.html#class:clone>`_ the theme
table or use some metatable magic::
dress.theme = setmetatable({}, {__index = suit.theme})
-- NOTE: you have to replace the whole color table. E.g., replacing only
-- dress.theme.color.normal will also change suit.theme.color.normal!
dress.theme.color = {
normal = {bg = {188,188,188}, fg = { 66, 66, 66}},
hovered = {bg = {255,255,255}, fg = { 50,153,187}},
active = {bg = {255,255,255}, fg = {225,153, 0}}
}
function dress.theme.Label(text, opt, x,y,w,h)
-- draw the label in a fancier way
end
.. [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

@@ -1,243 +0,0 @@
SUIT
====
Simple User Interface Toolkit for `LÖVE <http://love2d.org>`_.
SUIT up
-------
You can download SUIT and view the code on github: `vrld/SUIT
<http://github.com/vrld/SUIT>`_.
You may also download the sourcecode as a `zip
<http://github.com/vrld/SUIT/zipball/master>`_ or `tar
<http://github.com/vrld/SUIT/tarball/master>`_ file.
Otherwise, use `Git <http://git-scm.com>`_::
git clone git://github.com/vrld/SUIT
Update::
git pull
Hello, Suit::
suit = require 'suit'
local show_message = false
function love.update(dt)
-- Put a button on the screen. If hit, show a message.
if suit.Button("Hello, World!", 100,100, 300,30).hit then
show_message = true
end
-- if the button was pressed at least one time, but a label below
if show_message then
suit.Label("How are you today?", 100,150, 300,30)
end
end
function love.draw()
suit.draw()
end
Read on
-------
.. toctree::
:maxdepth: 2
Getting Started <gettingstarted>
Widgets <widgets>
Layout <layout>
Core Functions <core>
Themeing <themes>
License <license>
Example code
------------
The following code will create this UI:
.. image:: _static/demo.gif
::
local suit = require 'suit'
-- generate some assets (below)
function love.load()
snd = generateClickySound()
normal, hovered, active, mask = generateImageButton()
smallerFont = love.graphics.newFont(10)
end
-- data for a slider, an input box and a checkbox
local slider= {value = 0.5, min = -2, max = 2}
local input = {text = "Hello"}
local chk = {text = "Check?"}
-- all the UI is defined in love.update or functions that are called from here
function love.update(dt)
-- put the layout origin at position (100,100)
-- cells will grown down and to the right from this point
-- also set cell padding to 20 pixels to the right and to the bottom
suit.layout:reset(100,100, 20,20)
-- put a button at the layout origin
-- the cell of the button has a size of 200 by 30 pixels
state = suit.Button("Click?", suit.layout:row(200,30))
-- if the button was entered, play a sound
if state.entered then love.audio.play(snd) end
-- if the button was pressed, take damage
if state.hit then print("Ouch!") end
-- put an input box below the button
-- the cell of the input box has the same size as the cell above
-- if the input cell is submitted, print the text
if suit.Input(input, suit.layout:row()).submitted then
print(input.text)
end
-- put a button below the input box
-- the width of the cell will be the same as above, the height will be 40 px
if suit.Button("Hover?", suit.layout:row(nil,40)).hovered then
-- if the button is hovered, show two other buttons
-- this will shift all other ui elements down
-- put a button below the previous button
-- the cell height will be 30 px
-- the label of the button will be aligned top left
suit.Button("You can see", {align='left', valign='top'}, suit.layout:row(nil,30))
-- put a button below the previous button
-- the cell size will be the same as the one above
-- the label will be aligned bottom right
suit.Button("...but you can't touch!", {align='right', valign='bottom'},
suit.layout:row())
end
-- put a checkbox below the button
-- the size will be the same as above
-- (NOTE: height depends on whether "Hover?" is hovered)
-- the label "Check?" will be aligned right
suit.Checkbox(chk, {align='right'}, suit.layout:row())
-- put a nested layout
-- the size of the cell will be as big as the cell above or as big as the
-- nested content, whichever is bigger
suit.layout:push(suit.layout:row())
-- change cell padding to 3 pixels in either direction
suit.layout:padding(3)
-- put a slider in the cell
-- the inner cell will be 160 px wide and 20 px high
suit.Slider(slider, suit.layout:col(160, 20))
-- put a label that shows the slider value to the right of the slider
-- the width of the label will be 40 px
suit.Label(("%.02f"):format(slider.value), suit.layout:col(40))
-- close the nested layout
suit.layout:pop()
-- put an image button below the nested cell
-- the size of the cell will be 200 by 100 px,
-- but the image may be bigger or smaller
-- the button shows the image `normal' when the button is inactive
-- the button shows the image `hovered` if the mouse is over an opaque pixel
-- of the ImageData `mask`
-- the button shows the image `active` if the mouse is above an opaque pixel
-- of the ImageData `mask` and the mouse button is pressed
-- if `mask` is omitted, the alpha-test will be swapped for a test whether
-- the mouse is in the area occupied by the widget
suit.ImageButton(normal, {mask = mask, hovered = hovered, active = active}, suit.layout:row(200,50))
-- if the checkbox is checked, display a precomputed layout
if chk.checked then
-- the precomputed layout will be 3 rows below each other
-- the origin of the layout will be at (400,100)
-- the minimal height of the layout will be 300 px
rows = suit.layout:rows{pos = {400,100}, min_height = 300,
{200, 30}, -- the first cell will measure 200 by 30 px
{30, 'fill'}, -- the second cell will be 30 px wide and fill the
-- remaining vertical space between the other cells
{200, 30}, -- the third cell will be 200 by 30 px
}
-- the first cell will contain a witty label
-- the label will be aligned left
-- the font of the label will be smaller than the usual font
suit.Label("You uncovered the secret!", {align="left", font = smallerFont},
rows.cell(1))
-- the third cell will contain a label that shows the value of the slider
suit.Label(slider.value, {align='left'}, rows.cell(3))
-- the second cell will show a slider
-- the slider will operate on the same data as the first slider
-- the slider will be vertical instead of horizontal
-- the id of the slider will be 'slider two'. this is necessary, because
-- the two sliders should not both react to UI events
suit.Slider(slider, {vertical = true, id = 'slider two'}, rows.cell(2))
end
end
function love.draw()
-- draw the gui
suit.draw()
end
function love.textinput(t)
-- forward text input to SUIT
suit.textinput(t)
end
function love.keypressed(key)
-- forward keypressed to SUIT
suit.keypressed(key)
end
-- generate assets (see love.load)
function generateClickySound()
local snd = love.sound.newSoundData(512, 44100, 16, 1)
for i = 0,snd:getSampleCount()-1 do
local t = i / 44100
local s = i / snd:getSampleCount()
snd:setSample(i, (.7*(2*love.math.random()-1) + .3*math.sin(t*9000*math.pi)) * (1-s)^1.2 * .3)
end
return love.audio.newSource(snd)
end
function generateImageButton()
local metaballs = function(t, r,g,b)
return function(x,y)
local px, py = 2*(x/200-.5), 2*(y/100-.5)
local d1 = math.exp(-((px-.6)^2 + (py-.1)^2))
local d2 = math.exp(-((px+.7)^2 + (py+.1)^2) * 2)
local d = (d1 + d2)/2
if d > t then
return r,g,b, ((d-t) / (1-t))^.2
end
return 0,0,0,0
end
end
local normal, hovered, active = love.image.newImageData(200,100), love.image.newImageData(200,100), love.image.newImageData(200,100)
normal:mapPixel(metaballs(.48, .74,.74,.74))
hovered:mapPixel(metaballs(.46, .2,.6,.6))
active:mapPixel(metaballs(.43, 1,.6,0))
return love.graphics.newImage(normal), love.graphics.newImage(hovered), love.graphics.newImage(active), normal
end
Indices and tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -1,292 +0,0 @@
Layout
======
.. note::
Still under construction...
Immediate Mode Layouts
----------------------
.. function:: reset([x,y, [pad_x, [pad_y]]])
:param numbers x,y: Origin of the layout (optional).
:param pad_x,pad_y: Cell padding (optional).
Reset the layout, puts the origin at ``(x,y)`` and sets the cell padding to
``pad_x`` and ``pad_y``.
If ``x`` and ``y`` are omitted, they default to ``(0,0)``. If ``pad_x`` is
omitted, it defaults to 0. If ``pad_y`` is omitted, it defaults to ``pad_x``.
.. function:: padding([pad_x, [pad_y]])
:param pad_x: Cell padding in x direction (optional).
:param pad_y: Cell padding in y direction (optional, defaults to ``pad_x``).
:returns: The current (or new) cell padding.
Get and set the current cell padding.
If given, sets the cell padding to ``pad_x`` and ``pad_y``.
If only ``pad_x`` is given, set both padding in ``x`` and ``y`` direction to ``pad_x``.
.. function:: size()
:returns: ``width,height`` - The size of the last cell.
Get the size of the last cell.
.. function:: nextRow()
:returns: ``x,y`` - Upper left corner of the next row cell.
Get the position of the upper left corner of the next cell in a row layout.
Use for mixing precomputed and immediate mode layouts.
.. function:: nextCol()
:returns: ``x,y`` - Upper left corner of the next column cell.
Get the position of the upper left corner of the next cell in a column layout.
Use for mixing precomputed and immediate mode layouts.
.. function:: push([x,y])
:param numbers x,y: Origin of the layout (optional).
Saves the layout state (position, padding, sizes, etc.) on a stack, resets the
layout with position ``(x,y)``.
If ``x`` and ``y`` are omitted, they default to ``(0,0)``.
Used for nested row/column layouts.
.. function:: pop()
Restores the layout parameters from the stack and advances the layout position
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).
:returns: Position and size of the cell: ``x,y,w,h``.
Creates a new cell below 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.
Used to provide the last four arguments to a widget, e.g.::
suit.Button("Start Game", suit.layout:row(100,30))
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 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.
``min``
Mimimum of all values since the last reset.
``median``
Median of all values since the last reset.
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
-------------------
Apart from immediate mode layouts, you can specify layouts in advance.
The specification is a table of tables, where each inner table follows the
convention of :func:`row` and :func:`col`.
The result is a layout definition object that can be used to access the cells.
There are almost only two reasons to do so: (1) You know the area of your
layout in advance (say, the screen size), and want certain cells to dynamically
fill the available space; (2) You want to animate the cells.
.. note::
Unlike immediate mode layouts, precomputed layouts **can not be nested**.
You can mix immediate mode and precomputed layouts to achieve nested
layouts with precomputed cells, however.
Layout Specifications
^^^^^^^^^^^^^^^^^^^^^
Layout specifications are tables of tables, where the each inner table
corresponds to a cell. The inner tables define the width and height of the cell
according to the rules of :func:`row` and :func:`col`, with one additonal
keyword:
``fill``
Fills the available space, determined by ``min_height`` or ``min_width`` and
the number of cells with property ``fill``.
For example, this row specification makes the height of the second cell to
``(300 - 50 - 50) / 1 = 200``::
{min_height = 300,
{100, 50},
{nil, 'fill'},
{nil, 50},
}
This column specification divides the space evenly among two cells::
{min_width = 300,
{'fill', 100}
{'fill'}
}
Apart from ``min_height`` and ``min_width``, layout specifications can also
define the position (upper left corner) of the layout using the ``pos`` keyword::
{min_width = 300, pos = {100,100},
{'fill', 100}
{'fill'}
}
You can also define a padding::
{min_width = 300, pos = {100,100}, padding = {5,5},
{'fill', 100}
{'fill'}
}
Layout Definition Objects
^^^^^^^^^^^^^^^^^^^^^^^^^
Once constructed, the cells can be accessed in two ways:
- Using iterators::
for i, x,y,w,h in definition() do
suit.Button("Button "..i, x,y,w,h)
end
- Using the ``cell(i)`` accessor::
suit.Button("Button 1", definition.cell(1))
suit.Button("Button 3", definition.cell(3))
suit.Button("Button 2", definition.cell(2))
There is actually a third way: Because layout definitions are just tables, you
can access the cells directly::
local cell = definition[1]
suit.Button("Button 1", cell[1], cell[2], cell[3], cell[4])
-- or suit.Button("Button 1", unpack(cell))
This is especially useful if you want to animate the cells, for example with a
`tween <http://hump.readthedocs.org/en/latest/timer.html#Timer.tween>`_::
for i,cell in ipairs(definition)
local destination = {[2] = cell[2]} -- save cell y position
cell[2] = -cell[4] -- move cell just outside of the screen
-- let the cells fall into the screen one after another
timer.after(i / 10, function()
timer.tween(0.7, cell, destination, 'bounce')
end)
end
Constructors
^^^^^^^^^^^^
.. function:: rows(spec)
:param table spec: Layout specification.
:returns: Layout definition object.
Defines a row layout.
.. function:: cols(spec)
:param table spec: Layout specification.
:returns: Layout definition object.
Defines a column layout.

View File

@@ -1,26 +0,0 @@
License
=======
Copyright (c) 2016 Matthias Richter
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,5 +0,0 @@
Themeing
========
.. note::
Under construction.

View File

@@ -1,213 +0,0 @@
Widgets
=======
.. note::
Still under construction...
Immutable Widgets
-----------------
.. function:: Button(text, [options], x,y,w,h)
:param string text: Button label.
:param table options: Optional settings (see below).
:param numbers x,y: Upper left corner of the widget.
:param numbers w,h: Width and height of the widget.o
:returns: Return state (see below).
Creates a button widget at position ``(x,y)`` with width ``w`` and height
``h``.
.. function:: Label(text, [options], x,y,w,h)
:param string text: Label text.
:param table options: Optional settings (see below).
:param numbers x,y: Upper left corner of the widget.
:param numbers w,h: Width and height of the widget.o
:returns: Return state (see below).
Creates a label at position ``(x,y)`` with width ``w`` and height ``h``.
.. function:: ImageButton(normal, options, x,y)
:param mixed 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).
Creates an image button widget at position ``(x,y)``.
Unlike all other widgets, an ``ImageButton`` is not affected by the current
theme.
The argument ``normal`` defines the image of the normal state as well as the
area of the widget.
The button activates when the mouse enters the area occupied by the widget.
If the option ``mask`` defined, the button activates only if the mouse is over
a pixel with non-zero alpha.
You can provide additional ``hovered`` and ``active`` images, but the widget area
is always computed from the ``normal`` image.
You can provide additional ``hovered`` and ``active`` images, but the widget area
is always computed from the ``normal`` image.
**Additional Options:**
``mask``
Alpha-mask of the button, i.e. an ``ImageData`` of the same size as the
``normal`` image that has non-zero alpha where the button should activate.
``normal``
Image for the normal state of the widget. Defaults to widget payload.
``hovered``
Image for the hovered state of the widget. Defaults to ``normal`` if omitted.
``active``
Image for the active state of the widget. Defaults to ``hovered`` if omitted.
.. note::
``ImageButton`` does not recieve width and height parameters. As such, it
does not necessarily honor the cell size of a :doc:`layout`.
.. note::
Unlike other widgets, ``ImageButton`` is tinted by the currently active
color. If you want the button to appear untinted, make sure the active color
is set to white before adding the button, e.g.::
love.graphics.setColor(255,255,255)
suit.ImageButton(push_me, {hovered=and_then_just, active=touch_me},
suit.layout:row())
Mutable Widgets
---------------
.. function:: Checkbox(checkbox, [options], x,y,w,h)
:param table checkbox: Checkbox state.
:param table options: Optional settings (see below).
:param numbers x,y: Upper left corner of the widget.
:param numbers w,h: Width and height of the widget.o
:returns: Return state (see below).
Creates a checkbox at position ``(x,y)`` with width ``w`` and height ``h``.
**State:**
``checkbox`` is a table with the following components:
``checked``
``true`` if the checkbox is checked, ``false`` otherwise.
``text``
Optional label to show besides the checkbox.
.. function:: Slider(slider, [options], x,y,w,h)
:param table slider: Slider state.
:param table options: Optional settings (see below).
:param numbers x,y: Upper left corner of the widget.
:param numbers w,h: Width and height of the widget.o
:returns: Return state (see below).
Creates a slider at position ``(x,y)`` with width ``w`` and height ``h``.
Sliders can be horizontal (default) or vertical.
**State:**
``value``
Current value of the slider. Mandatory argument.
``min``
Minimum value of the slider. Defaults to ``min(value, 0)`` if omitted.
``max``
Maximum value of the slider. Defaults to ``min(value, 1)`` if omitted.
``step``
Value stepping for keyboard input. Defaults to ``(max - min)/10`` if omitted.
**Additional Options:**
``vertical``
Whether the slider is vertical or horizontal.
**Additional Return State:**
``changed``
``true`` when the slider value was changed, ``false`` otherwise.
.. function:: Input(input, [options], x,y,w,h)
:param table input: Checkbox state
:param table options: Optional settings (see below).
:param numbers x,y: Upper left corner of the widget.
:param numbers w,h: Width and height of the widget.o
:returns: Return state (see below).
Creates an input box at position ``(x,y)`` with width ``w`` and height ``h``.
Implements typical movement (arrow keys, home and end key) and editing
(deletion with backspace and delete) facilities.
**State:**
``text``
Current text inside the input box. Defaults to the empty string if omitted.
``cursor``
Cursor position. Defined as the position before the character (including
EOS), so ``1`` is the position before the first character, etc. Defaults to
the end of ``text`` if omitted.
**Additional Return State:**
``submitted``
``true`` when enter was pressed while the widget has keyboard focus.
Common Options
--------------
``id``
Identifier of the widget regarding user interaction. Defaults to the first
argument (e.g., ``text`` for buttons) if omitted.
``font``
Font of the label. Defaults to the current font (``love.graphics.getFont()``).
``align``
Horizontal alignment of the label. One of ``"left"``, ``"center"``, or
``"right"``. Defaults to ``"center"``.
``valign``
Vertical alignment of the label. On of ``"top"``, ``"middle"``, or
``"bottom"``. Defaults to ``"middle"``.
``color``
A table to overwrite the color. Undefined colors default to the theme colors.
``cornerRadius``
The corner radius for boxes. Overwrites the theme corner radius.
``draw``
A function to replace the drawing function. Refer to :doc:`themes` for more information about the function signatures.
Common Return States
--------------------
``id``
Identifier of the widget.
``hit``
``true`` if the mouse was pressed and released on the button, ``false``
otherwise.
``hovered``
``true`` if the mouse is above the widget, ``false`` otherwise.
``entered``
``true`` if the mouse entered the widget area, ``false`` otherwise.
``left``
``true`` if the mouse left the widget area, ``false`` otherwise.

23
deps/suit/license.txt vendored
View File

@@ -1,23 +0,0 @@
Copyright (c) 2016 Matthias Richter
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,28 +0,0 @@
package = "suit"
version = "0.1-1"
source = {
url = "git://github.com/vrld/suit.git"
}
description = {
summary="Immediate mode GUI library in pure Lua.",
homepage = "https://suit.readthedocs.io",
license = "MIT",
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
["suit"] = "init.lua",
["suit.button"] = "button.lua",
["suit.checkbox"] = "checkbox.lua",
["suit.core"] = "core.lua",
["suit.imagebutton"] = "imagebutton.lua",
["suit.input"] = "input.lua",
["suit.label"] = "label.lua",
["suit.layout"] = "layout.lua",
["suit.slider"] = "slider.lua",
["suit.theme"] = "theme.lua",
}
}