From 80b067528da5e6442c2105c43963e2ced7b5b568 Mon Sep 17 00:00:00 2001 From: osch Date: Sun, 10 Dec 2023 11:35:23 +0100 Subject: [PATCH] Big update, but still work in progress: rework class system and generated documentation --- .github/workflows/test.yml | 7 +- .gitignore | 2 + README.md | 52 +- doc/Application.md | 49 +- doc/Class.md | 507 +++++++-- doc/Introduction.md | 37 + doc/Meta.md | 131 +++ doc/Mixin.md | 193 ++++ doc/README.md | 15 +- doc/Style.md | 9 +- doc/gen/lwtk/Actionable.md | 36 + doc/gen/lwtk/Animatable.md | 28 + doc/gen/lwtk/Animations.md | 32 + doc/gen/lwtk/Application.md | 127 +++ doc/gen/lwtk/Area.md | 73 ++ doc/gen/lwtk/Box.md | 57 + doc/gen/lwtk/BuiltinStyleTypes.md | 5 + doc/gen/lwtk/Button.md | 47 + doc/gen/lwtk/Callback.md | 14 + doc/gen/lwtk/ChildLookup.md | 12 + doc/gen/lwtk/Class.md | 7 + doc/gen/lwtk/Color.md | 74 ++ doc/gen/lwtk/Colored.md | 15 + doc/gen/lwtk/Column.md | 55 + doc/gen/lwtk/Component.md | 156 +++ doc/gen/lwtk/Compound.md | 32 + doc/gen/lwtk/Control.md | 23 + doc/gen/lwtk/DefaultKeyBinding.md | 5 + doc/gen/lwtk/DefaultStyle.md | 25 + doc/gen/lwtk/Drawable.md | 34 + doc/gen/lwtk/FocusGroup.md | 122 +++ doc/gen/lwtk/FocusHandler.md | 140 +++ doc/gen/lwtk/Focusable.md | 23 + doc/gen/lwtk/FontInfo.md | 32 + doc/gen/lwtk/FontInfos.md | 28 + doc/gen/lwtk/Group.md | 74 ++ doc/gen/lwtk/HotkeyListener.md | 17 + doc/gen/lwtk/InnerCompound.md | 30 + doc/gen/lwtk/KeyBinding.md | 12 + doc/gen/lwtk/KeyHandler.md | 15 + doc/gen/lwtk/LayoutFrame.md | 23 + doc/gen/lwtk/Matrix.md | 62 ++ doc/gen/lwtk/Meta.md | 7 + doc/gen/lwtk/Mixin.md | 7 + doc/gen/lwtk/MouseDispatcher.md | 30 + doc/gen/lwtk/Node.md | 38 + doc/gen/lwtk/Object.md | 91 ++ doc/gen/lwtk/PushButton.md | 132 +++ doc/gen/lwtk/Rect.md | 55 + doc/gen/lwtk/Row.md | 55 + doc/gen/lwtk/Space.md | 67 ++ doc/gen/lwtk/Square.md | 63 ++ doc/gen/lwtk/Style.md | 77 ++ doc/gen/lwtk/StyleRef.md | 3 + doc/gen/lwtk/StyleTypeAttributes.md | 3 + doc/gen/lwtk/Styleable.md | 32 + doc/gen/lwtk/TextCursor.md | 37 + doc/gen/lwtk/TextFragment.md | 65 ++ doc/gen/lwtk/TextInput.md | 136 +++ doc/gen/lwtk/TextLabel.md | 97 ++ doc/gen/lwtk/Timer.md | 21 + doc/gen/lwtk/TitleText.md | 42 + doc/gen/lwtk/ViewSwitcher.md | 69 ++ doc/gen/lwtk/WeakKeysTable.md | 3 + doc/gen/lwtk/Widget.md | 81 ++ doc/gen/lwtk/Window.md | 217 ++++ doc/gen/lwtk/_VERSION.md | 3 + doc/gen/lwtk/btest.md | 6 + doc/gen/lwtk/call.md | 5 + doc/gen/lwtk/errorf.md | 5 + doc/gen/lwtk/extract.md | 5 + doc/gen/lwtk/get.md | 3 + doc/gen/lwtk/getSuperClass.md | 5 + doc/gen/lwtk/init.md | 4 + doc/gen/lwtk/isInstanceOf.md | 11 + doc/gen/lwtk/layout.md | 3 + doc/gen/lwtk/love/Application.md | 80 ++ doc/gen/lwtk/love/DrawContext.md | 82 ++ doc/gen/lwtk/love/Driver.md | 68 ++ doc/gen/lwtk/love/LayoutContext.md | 49 + doc/gen/lwtk/love/View.md | 56 + doc/gen/lwtk/love/init.md | 4 + doc/gen/lwtk/love/keyNameMap.md | 3 + doc/gen/lwtk/lpugl/CairoDrawContext.md | 80 ++ doc/gen/lwtk/lpugl/CairoLayoutContext.md | 45 + doc/gen/lwtk/lpugl/Driver.md | 72 ++ doc/gen/lwtk/lpugl/init.md | 5 + doc/gen/lwtk/newClass.md | 15 + doc/gen/lwtk/newMeta.md | 9 + doc/gen/lwtk/newMixin.md | 9 + doc/gen/lwtk/tryrequire.md | 5 + doc/gen/lwtk/type.md | 15 + doc/gen/lwtk/undef.md | 5 + doc/gen/lwtk/utf8.md | 3 + doc/gen/modules.md | 103 ++ example/example01.lua | 41 +- example/example10.lua | 12 +- example/screenshot00.png | Bin 0 -> 5986 bytes lwtk-scm-0.rockspec | 30 +- scripts/substmodules.lua | 19 +- src/Makefile | 11 + src/alltests.lua | 41 +- src/doctest.lua | 18 +- src/lwtk/Actionable.lua | 32 +- src/lwtk/Animatable.lua | 55 +- src/lwtk/Animations.lua | 13 +- src/lwtk/Application.lua | 431 ++++---- src/lwtk/Area.lua | 44 +- src/lwtk/Bordered.lua | 3 - src/lwtk/Box.lua | 2 +- src/lwtk/Callback.lua | 8 +- src/lwtk/ChildLookup.lua | 10 +- src/lwtk/Class.lua | 259 ++++- src/lwtk/Color.lua | 54 +- src/lwtk/Colored.lua | 27 +- src/lwtk/Column.lua | 12 +- src/lwtk/Component.lua | 118 +- src/lwtk/Compound.lua | 39 +- src/lwtk/DefaultKeyBinding.lua | 3 + src/lwtk/DefaultStyle.lua | 12 +- src/lwtk/Drawable.lua | 67 ++ src/lwtk/FocusGroup.lua | 24 +- src/lwtk/FocusHandler.lua | 14 +- src/lwtk/Focusable.lua | 103 +- src/lwtk/FontInfo.lua | 11 + src/lwtk/FontInfos.lua | 5 + src/lwtk/Group.lua | 9 +- src/lwtk/HotkeyHandler.lua | 11 - src/lwtk/HotkeyListener.lua | 59 +- src/lwtk/KeyBinding.lua | 2 +- src/lwtk/KeyHandler.lua | 25 +- src/lwtk/LayoutFrame.lua | 25 +- src/lwtk/Matrix.lua | 21 +- src/lwtk/Meta.lua | 51 + src/lwtk/Mixin.lua | 16 +- src/lwtk/MouseDispatcher.lua | 38 +- src/lwtk/Node.lua | 23 + src/lwtk/Object.lua | 244 ++++- src/lwtk/PushButton.lua | 29 +- src/lwtk/Rect.lua | 11 +- src/lwtk/Row.lua | 12 +- src/lwtk/Space.lua | 18 +- src/lwtk/Square.lua | 6 +- src/lwtk/Style.lua | 30 +- src/lwtk/StyleTypeAttributes.lua | 10 +- src/lwtk/Styleable.lua | 87 +- src/lwtk/TextCursor.lua | 2 +- src/lwtk/TextFragment.lua | 37 +- src/lwtk/TextInput.lua | 32 +- src/lwtk/TextLabel.lua | 18 +- src/lwtk/Timer.lua | 7 +- src/lwtk/ViewSwitcher.lua | 6 +- src/lwtk/WeakKeysTable.lua | 9 +- src/lwtk/Widget.lua | 15 +- src/lwtk/WidgetWrapper.lua | 127 --- src/lwtk/Window.lua | 63 +- src/lwtk/btest.lua | 9 + src/lwtk/get.lua | 6 +- src/lwtk/init.lua | 3 + src/lwtk/internal/ColumnImpl.lua | 14 +- src/lwtk/internal/StyleRuleContext.lua | 9 + src/lwtk/internal/TypeRule.lua | 9 +- src/lwtk/internal/utf8string.lua | 2 +- src/lwtk/{ => internal}/vivid.lua | 0 src/lwtk/isInstanceOf.lua | 27 +- src/lwtk/layout.lua | 3 +- src/lwtk/love/Application.lua | 87 +- src/lwtk/love/DrawContext.lua | 9 +- src/lwtk/love/Driver.lua | 9 + src/lwtk/love/LayoutContext.lua | 7 + src/lwtk/love/View.lua | 9 +- src/lwtk/love/init.lua | 3 + src/lwtk/love/keyNameMap.lua | 67 ++ src/lwtk/lpugl/CairoDrawContext.lua | 6 +- src/lwtk/lpugl/CairoLayoutContext.lua | 6 + src/lwtk/lpugl/Driver.lua | 6 + src/lwtk/lpugl/init.lua | 4 + src/lwtk/newClass.lua | 27 +- src/lwtk/newMeta.lua | 21 + src/lwtk/newMixin.lua | 145 ++- src/lwtk/type.lua | 13 + src/lwtk/undef.lua | 24 + src/mkdoc/README.md | 18 + src/mkdoc/comments.lua | 289 +++++ src/mkdoc/lua-parser/LICENSE | 20 + src/mkdoc/lua-parser/parser.lua | 489 +++++++++ src/mkdoc/lua-parser/scope.lua | 74 ++ src/mkdoc/lua-parser/validator.lua | 394 +++++++ src/mkdoc/main.lua | 1260 ++++++++++++++++++++++ src/mkdoc/pprint.lua | 518 +++++++++ src/mkdoc/util.lua | 141 +++ src/perf.lua | 79 ++ src/printclasses.lua | 10 +- src/test01.lua | 28 +- src/test03a.lua | 14 +- src/test03b.lua | 13 +- src/tests/test01.lua | 176 +-- src/tests/test02.lua | 4 +- 198 files changed, 9963 insertions(+), 1273 deletions(-) create mode 100644 doc/Introduction.md create mode 100644 doc/Meta.md create mode 100644 doc/Mixin.md create mode 100644 doc/gen/lwtk/Actionable.md create mode 100644 doc/gen/lwtk/Animatable.md create mode 100644 doc/gen/lwtk/Animations.md create mode 100644 doc/gen/lwtk/Application.md create mode 100644 doc/gen/lwtk/Area.md create mode 100644 doc/gen/lwtk/Box.md create mode 100644 doc/gen/lwtk/BuiltinStyleTypes.md create mode 100644 doc/gen/lwtk/Button.md create mode 100644 doc/gen/lwtk/Callback.md create mode 100644 doc/gen/lwtk/ChildLookup.md create mode 100644 doc/gen/lwtk/Class.md create mode 100644 doc/gen/lwtk/Color.md create mode 100644 doc/gen/lwtk/Colored.md create mode 100644 doc/gen/lwtk/Column.md create mode 100644 doc/gen/lwtk/Component.md create mode 100644 doc/gen/lwtk/Compound.md create mode 100644 doc/gen/lwtk/Control.md create mode 100644 doc/gen/lwtk/DefaultKeyBinding.md create mode 100644 doc/gen/lwtk/DefaultStyle.md create mode 100644 doc/gen/lwtk/Drawable.md create mode 100644 doc/gen/lwtk/FocusGroup.md create mode 100644 doc/gen/lwtk/FocusHandler.md create mode 100644 doc/gen/lwtk/Focusable.md create mode 100644 doc/gen/lwtk/FontInfo.md create mode 100644 doc/gen/lwtk/FontInfos.md create mode 100644 doc/gen/lwtk/Group.md create mode 100644 doc/gen/lwtk/HotkeyListener.md create mode 100644 doc/gen/lwtk/InnerCompound.md create mode 100644 doc/gen/lwtk/KeyBinding.md create mode 100644 doc/gen/lwtk/KeyHandler.md create mode 100644 doc/gen/lwtk/LayoutFrame.md create mode 100644 doc/gen/lwtk/Matrix.md create mode 100644 doc/gen/lwtk/Meta.md create mode 100644 doc/gen/lwtk/Mixin.md create mode 100644 doc/gen/lwtk/MouseDispatcher.md create mode 100644 doc/gen/lwtk/Node.md create mode 100644 doc/gen/lwtk/Object.md create mode 100644 doc/gen/lwtk/PushButton.md create mode 100644 doc/gen/lwtk/Rect.md create mode 100644 doc/gen/lwtk/Row.md create mode 100644 doc/gen/lwtk/Space.md create mode 100644 doc/gen/lwtk/Square.md create mode 100644 doc/gen/lwtk/Style.md create mode 100644 doc/gen/lwtk/StyleRef.md create mode 100644 doc/gen/lwtk/StyleTypeAttributes.md create mode 100644 doc/gen/lwtk/Styleable.md create mode 100644 doc/gen/lwtk/TextCursor.md create mode 100644 doc/gen/lwtk/TextFragment.md create mode 100644 doc/gen/lwtk/TextInput.md create mode 100644 doc/gen/lwtk/TextLabel.md create mode 100644 doc/gen/lwtk/Timer.md create mode 100644 doc/gen/lwtk/TitleText.md create mode 100644 doc/gen/lwtk/ViewSwitcher.md create mode 100644 doc/gen/lwtk/WeakKeysTable.md create mode 100644 doc/gen/lwtk/Widget.md create mode 100644 doc/gen/lwtk/Window.md create mode 100644 doc/gen/lwtk/_VERSION.md create mode 100644 doc/gen/lwtk/btest.md create mode 100644 doc/gen/lwtk/call.md create mode 100644 doc/gen/lwtk/errorf.md create mode 100644 doc/gen/lwtk/extract.md create mode 100644 doc/gen/lwtk/get.md create mode 100644 doc/gen/lwtk/getSuperClass.md create mode 100644 doc/gen/lwtk/init.md create mode 100644 doc/gen/lwtk/isInstanceOf.md create mode 100644 doc/gen/lwtk/layout.md create mode 100644 doc/gen/lwtk/love/Application.md create mode 100644 doc/gen/lwtk/love/DrawContext.md create mode 100644 doc/gen/lwtk/love/Driver.md create mode 100644 doc/gen/lwtk/love/LayoutContext.md create mode 100644 doc/gen/lwtk/love/View.md create mode 100644 doc/gen/lwtk/love/init.md create mode 100644 doc/gen/lwtk/love/keyNameMap.md create mode 100644 doc/gen/lwtk/lpugl/CairoDrawContext.md create mode 100644 doc/gen/lwtk/lpugl/CairoLayoutContext.md create mode 100644 doc/gen/lwtk/lpugl/Driver.md create mode 100644 doc/gen/lwtk/lpugl/init.md create mode 100644 doc/gen/lwtk/newClass.md create mode 100644 doc/gen/lwtk/newMeta.md create mode 100644 doc/gen/lwtk/newMixin.md create mode 100644 doc/gen/lwtk/tryrequire.md create mode 100644 doc/gen/lwtk/type.md create mode 100644 doc/gen/lwtk/undef.md create mode 100644 doc/gen/lwtk/utf8.md create mode 100644 doc/gen/modules.md create mode 100644 example/screenshot00.png create mode 100644 src/Makefile delete mode 100644 src/lwtk/Bordered.lua create mode 100644 src/lwtk/Drawable.lua delete mode 100644 src/lwtk/HotkeyHandler.lua create mode 100644 src/lwtk/Meta.lua create mode 100644 src/lwtk/Node.lua delete mode 100644 src/lwtk/WidgetWrapper.lua rename src/lwtk/{ => internal}/vivid.lua (100%) create mode 100644 src/lwtk/love/keyNameMap.lua create mode 100644 src/lwtk/newMeta.lua create mode 100644 src/lwtk/undef.lua create mode 100644 src/mkdoc/README.md create mode 100644 src/mkdoc/comments.lua create mode 100644 src/mkdoc/lua-parser/LICENSE create mode 100644 src/mkdoc/lua-parser/parser.lua create mode 100644 src/mkdoc/lua-parser/scope.lua create mode 100644 src/mkdoc/lua-parser/validator.lua create mode 100644 src/mkdoc/main.lua create mode 100644 src/mkdoc/pprint.lua create mode 100644 src/mkdoc/util.lua create mode 100644 src/perf.lua diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 76ac7f9..6764eb4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,6 +37,7 @@ jobs: - name: setup common run: | + luarocks install lpath luarocks install oocairo luarocks --server=https://luarocks.org/dev install lpugl luarocks --server=https://luarocks.org/dev install lpugl_cairo @@ -49,7 +50,9 @@ jobs: run: | set -e lua -v + lua src/alltests.lua src/tests cd src - lua alltests.lua - lua doctest.lua ../doc/*md + export LUA_PATH='./?.lua;./?/init.lua;'$LUA_PATH + echo "LUA_PATH=$LUA_PATH" + lua doctest.lua \ No newline at end of file diff --git a/.gitignore b/.gitignore index 20ca93b..f293826 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /.files +*.trace + diff --git a/README.md b/README.md index bc8add9..afe95d9 100644 --- a/README.md +++ b/README.md @@ -32,11 +32,11 @@ of standard widgets. So far only very simple standard widgets are provided, e.g. ## First Example -* The first example demonstrates a simple dialog using the `lwtk.TextInput` widget. +* The first example demonstrates a simple "Hello World" dialog. The appearance of the widgets is configured in [lwtk.DefaultStyle](src/lwtk/DefaultStyle.lua). The key bindings are configured in [lwtk.DefaultKeyBinding](src/lwtk/DefaultKeyBinding.lua). - ![Screenshot example01](./example/screenshot01.png) + ![Screenshot example01](./example/screenshot00.png) ```lua local lwtk = require("lwtk") @@ -45,67 +45,27 @@ of standard widgets. So far only very simple standard widgets are provided, e.g. local Column = lwtk.Column local Row = lwtk.Row local PushButton = lwtk.PushButton - local TextInput = lwtk.TextInput local TitleText = lwtk.TitleText local Space = lwtk.Space - local app = Application("example01.lua") + local app = Application("example") local function quit() app:close() end local win = app:newWindow { - title = "example01", + title = "example", Column { - id = "c1", - TitleText { text = "What's your name?" }, - TextInput { id = "i1", focus = true, style = { Columns = 40 } }, + TitleText { text = "Hello World!", style = { textSize = 35 } }, Row { Space {}, - PushButton { id = "b1", text = "&OK", disabled = true, - default = true }, - - PushButton { id = "b2", text = "&Quit", onClicked = quit }, + PushButton { text = "&OK", onClicked = quit }, Space {} } }, - Column { - id = "c2", - visible = false, - Space {}, - TitleText { id = "t2", style = { TextAlign = "center" } }, - Space {}, - Row { - Space {}, - PushButton { id = "b3", text = "&Again" }, - - PushButton { id = "b4", text = "&Quit", default = true, - onClicked = quit }, - Space {} - } - } } - - win:childById("c1"):setOnInputChanged(function(widget, input) - widget:childById("b1"):setDisabled(input.text == "") - end) - - win:childById("b1"):setOnClicked(function(widget) - win:childById("t2"):setText("Hello "..win:childById("i1").text.."!") - win:childById("c1"):setVisible(false) - win:childById("c2"):setVisible(true) - end) - - win:childById("b3"):setOnClicked(function(widget) - win:childById("i1"):setText("") - win:childById("i1"):setFocus() - win:childById("c1"):setVisible(true) - win:childById("c2"):setVisible(false) - end) - win:show() - app:runEventLoop() ``` diff --git a/doc/Application.md b/doc/Application.md index 81648d4..b52ff32 100644 --- a/doc/Application.md +++ b/doc/Application.md @@ -1,53 +1,16 @@ -# lwtk.Application +# lwtk.Application Usage -TODO - - -## Contents - - - * [Application Methods](#application-methods) - * [Application:runEventLoop()](#Application_runEventLoop) - * [Application:update()](#Application_update) - - +[lwtk.Application] objects are needed to control lwtk event processing and window +management for desktop applications. +[lwtk.Application]: ./gen/lwtk/Application.md -## Application Methods - - -* **`Application:runEventLoop(timeout) - `** - - Update by processing events from the window system. - - * *timeout* - optional float, timeout in seconds - - If *timeout* is given, this function will process events from the window system until - the time period in seconds has elapsed or until all window objects have been closed. - - If *timeout* is `nil` or not given, this function will process events from the window system - until all window objects have been closed. - +## Contents -* **`Application:update(timeout) - `** +TODO - Update by processing events from the window system. - - * *timeout* - optional float, timeout in seconds - - If *timeout* is given, this function will wait for *timeout* seconds until - events from the window system become available. If *timeout* is `nil` or not - given, this function will block indefinitely until an event occurs. - - As soon as events are available, all events in the queue are processed and this function - returns `true`. - - If *timeout* is given and there are no events available after *timeout* - seconds, this function will return `false`. diff --git a/doc/Class.md b/doc/Class.md index d4f0b3e..3f2caea 100644 --- a/doc/Class.md +++ b/doc/Class.md @@ -1,53 +1,79 @@ -# lwtk.Class +# lwtk.Class Usage -Each lwtk *object* is actually a Lua table that has a lwtk *class* as metatable. The class -is also called the object's *type*. +Like [lwtk.Meta] objects, [lwtk.Class] objects are factories for creating derived objects +of a certain type. The thereby derived objects are belonging to a type hierarchy of super +classes providing inheritance mechanismen. + + +[lwtk.Meta]: ./gen/lwtk/Meta.md +[lwtk.Class]: ./gen/lwtk/Class.md +[lwtk.Mixin]: ./gen/lwtk/Mixin.md ## Contents - * [Declaring Classes](#declaring-classes) - * [Instantiating Objects](#instantiating-objects) - * [Declaring Methods](#declaring-methods) - * [Declaring Derived Classes](#declaring-derived-classes) + * [Creating Classes](#creating-classes) * [Instantiating Derived Objects](#instantiating-derived-objects) - * [Overriding Methods](#overriding-methods) + * [Declaring Members](#declaring-members) + * [Defining Methods](#defining-methods) + * [Creating Subclasses](#creating-subclasses) + * [Instantiating Derived Objects from Subclass](#instantiating-derived-objects-from-subclass) + * [Overriding Members](#overriding-members) + * [Implementing Members](#implementing-members) + * [Constructors](#constructors) + * [Static Members](#static-members) + * [Extra Members](#extra-members) -## Declaring Classes +## Creating Classes -Let's start by declaring a new class named `"Foo"`: +Let's start by creating a new class object named `"Foo"`: ```lua local lwtk = require("lwtk") local Foo = lwtk.newClass("Foo") ``` -The new class `Foo` is actually a Lua table that has `lwtk.Class` as metatable. -Its `tostring` value is the class name `"Foo"` and `lwtk.type()` evaluates to `"lwtk.Class"`: +The new class object `Foo` is actually a Lua table that has [lwtk.Class] as metatable. +Its `tostring` value is `"lwtk.Class"` and *[lwtk.type()]* evaluates to `"lwtk.Class"`: + +[lwtk.type()]: ./gen/lwtk/type.md ```lua assert(type(Foo) == "table") assert(getmetatable(Foo) == lwtk.Class) -assert(tostring(Foo) == "Foo") +assert(tostring(Foo) == "lwtk.Class") assert(lwtk.type(Foo) == "lwtk.Class") ``` + + +The class name is only used for debugging purposes: it is allowed to create two +different class objects with the same name (although this is not recommended): + +```lua +local Foo2 = lwtk.newClass("Foo") +assert(Foo ~= Foo2) +assert(tostring(Foo) == tostring(Foo2)) +``` -## Instantiating Objects +## Instantiating Derived Objects -Objects of a certain class are instantiated by calling the class: +The class object is used to instantiate new derived objects by simply calling the class object: ```lua local o1 = Foo() local o2 = Foo() ``` -The created objects are Lua tables that have `Foo` as metatable. Their `tostring` value -contains the class name `"Foo"` and `lwtk.type()` evaluates to `"Foo"`: +The instantiated objects are Lua tables that have the class object `Foo` as metatable. +Their `tostring` value contains the class name `"Foo"` and *[lwtk.type()]* evaluates +to `"Foo"`: ```lua for _, o in ipairs{o1, o2} do @@ -58,116 +84,223 @@ for _, o in ipairs{o1, o2} do end assert(o1 ~= o2) ``` + + +**Technical details** + +Strictly speaking, the class object is not the real metatable, but gives access to +the underlying metatable, which can be observed by using the Lua `debug` package: +```lua +local realMt = debug.getmetatable(o1) +assert(realMt == debug.getmetatable(o2)) +assert(realMt ~= Foo) +assert(realMt.__index == Foo.__index) +assert(realMt.__newindex == Foo.__newindex) +``` -## Declaring Methods +## Declaring Members -Methods declared for the class table become methods for all objects of this type: +Members of the class object become available in the derived objects: ```lua -function Foo:setX(x) - self._x = x -end -function Foo:getX(x) - return self._x -end -o1:setX(100) -o2:setX(200) -assert(o1:getX() == 100) -assert(o2:getX() == 200) -assert(o1._x == 100) -assert(o2._x == 200) +Foo.x = 100 +Foo.y = false +assert(o1.x == 100) +assert(o2.x == 100) +assert(o1.y == false) +assert(o2.y == false) +``` + +Members of the class object may not be changed once they are declared: + +```lua +local ok, err = pcall(function() Foo.x = 999 end) +assert(not ok and err:match('member "x" already defined in class')) +``` + +Througout lwtk, a _defined_ member denotes a member having a value that is +not `false` and not `nil`. A _declared_ member denotes a member having a value +that is not `nil`. So in our example, member `x` is defined (and declared) and +member `y` is only declared: + +```lua +local ok, err = pcall(function() Foo.y = 999 end) +assert(not ok and err:match('member "y" already declared in class')) +``` + +If a member value is changed in a derived object, it does not effect the +member value in the underlying class object or in other derived objects: + +```lua +o1.x = 200 +assert(o1.x == 200) +assert(o2.x == 100) +assert(Foo.x == 100) +``` + +It is not allowed to get or set members in a derived object that +are not declared in the underlying class object: + +```lua +local ok, err = pcall(function() o1.z = 300 end) +assert(not ok and err:match('member "z" not declared in class')) + +local ok, err = pcall(function() print(o1.z) end) +assert(not ok and err:match('member "z" not declared in class')) +``` + +Therefore all object members have to be declared in the underlying +class object. This can be done by setting them to an initial value (as +seen above) or by using the `declare` helper method, that sets the +given members to the value `false`: + +```lua +Foo:declare("a", "b") +o1.a = "A1" +o2.a = "A2" +assert(Foo.a == false) +assert(Foo.b == false) +assert(o1.a == "A1") +assert(o2.a == "A2") +``` + +**Technical details** + +Members are retrieved by metatable lookup from the underlying class object until +they are overwritten in the derived object: + +```lua +Foo.bar = {} +assert(o1.bar == Foo.bar) +assert(rawget(o1, "bar") == nil) +assert(rawget(Foo, "bar") == nil) +assert(rawget(Foo.__index, "bar") == Foo.bar) +o1.bar = {} +assert(o1.bar ~= Foo.bar) +assert(rawget(o1, "bar") == o1.bar) ``` -The methods are retrieved by metatable lookup from the class: + +## Defining Methods + + +Methods are members of type `function` which are defined using Lua's member syntax: ```lua -assert(rawget(o1, "setX") == nil) -assert(rawget(Foo, "setX") == Foo.setX) -assert(o1.setX == Foo.setX) +function Foo:setX(x) + self.x = x +end +function Foo:getX() + return self.x +end +o1:setX(10) +o2:setX(20) +assert(o1:getX() == 10) +assert(o2:getX() == 20) +assert(o1.x == 10) +assert(o2.x == 20) ``` -## Declaring Derived Classes +## Creating Subclasses -Let's create a derived class named `"Bar"` that has `Foo` as super class: +Let's create a new subclass named `"Bar"` that has `Foo` as superclass: ```lua local Bar = lwtk.newClass("Bar", Foo) ``` -Every class declared by `lwtk.newClass()` has a super class, -default super class is `lwtk.Object`: +Every class declared by `lwtk.newClass()` has a superclass, +default superclass is `lwtk.Object`: ```lua -assert(lwtk.getSuperClass(Bar) == Foo) -assert(lwtk.getSuperClass(Foo) == lwtk.Object) -assert(lwtk.getSuperClass(lwtk.Object) == nil) +assert(Bar:getSuperClass() == Foo) +assert(Foo:getSuperClass() == lwtk.Object) +assert(lwtk.Object:getSuperClass() == nil) +assert(Bar:getClassPath() == "Bar(Foo(lwtk.Object))") +assert(Bar:getReverseClassPath() == "/lwtk.Object/Foo/Bar") ``` -The new class object is a Lua table, its `tostring` value is the class name `"Bar"`, -`lwtk.type()` evaluates to `"lwtk.Class"` and has `lwtk.Class` as metatable: +The new class `Bar` is a Lua table that has `lwtk.Class` as metatable. +Its `tostring` value is `"lwtk.Class"` and `lwtk.type()` evaluates to `"lwtk.Class"`: ```lua assert(type(Bar) == "table") -assert(tostring(Bar) == "Bar") -assert(lwtk.type(Bar) == "lwtk.Class") assert(getmetatable(Bar) == lwtk.Class) +assert(tostring(Bar) == "lwtk.Class") +assert(lwtk.type(Bar) == "lwtk.Class") ``` -The derived class contains the methods of the super class at the time when `newClass` +The subclass contains the members of the superclass at the time when `newClass` was invoked: ```lua -assert(rawget(Bar, "setX") == Foo.setX) -assert(rawget(Bar, "getX") == Foo.getX) +assert(rawget(Bar.__index, "setX") == Foo.setX) +assert(rawget(Bar.__index, "getX") == Foo.getX) ``` -Methods declared for `Foo` after the creation of class `Bar` have no effect: +Members declared for `Foo` after the creation of class `Bar` have no effect: ```lua -function Foo:setY(y) - self._y = y -end -assert(Bar.setY == nil) -assert(Foo.setY ~= nil) +Foo.newMember = {} +local ok, err = pcall(function() print(Bar.newMember) end) +assert(not ok and err:match('no member "newMember" in class')) +assert(rawget(Foo.__index, "newMember") == Foo.newMember) +assert(rawget(Bar.__index, "newMember") == nil) +assert(rawget(Bar, "newMember") == nil) ``` -## Instantiating Derived Objects +## Instantiating Derived Objects from Subclass -Let's instantiate an object of the derived class `Bar`: +Let's instantiate a derived object of the subclass `Bar`: ```lua local o3 = Bar() ``` -The created object is a Lua table, the `tostring` value contains the class name `"Bar"`, -`lwtk.type()` evaluates to `"Bar"` and its metatable is `Bar`: - +The instantiated object is a Lua table, it has the class object `Bar` as metatable. +The `tostring` value contains the class name `"Bar"` and *[lwtk.type()]* evaluates +to `"Bar"`: ```lua assert(type(o3) == "table") +assert(getmetatable(o3) == Bar) assert(tostring(o3):match("^Bar: [xa-fA-F0-9]+$")) -- e.g. "Bar: 0x55d1e35c2430" assert(lwtk.type(o3) == "Bar") -assert(getmetatable(o3) == Bar) ``` -The created object has the methods of the super class: +The instantiated object has the members of the superclass: ```lua assert(o3.setX == Foo.setX) -assert(o3.setY == nil) o3:setX(300) assert(o3:getX()== 300) -assert(o3._x == 300) +assert(o3.x == 300) +``` + +Members declared for the subclass are only available for subclass derived objects: + + +```lua +function Bar:addX(x) + return self.x + x +end +assert(o3:addX(2) == 302) + +local ok, err = pcall(function() print(o2.addX) end) +assert(not ok and err:match('member "addX" not declared in class')) ``` + Use `lwtk.isInstanceOf()` to check if an object is an instance of the specified class: ```lua @@ -183,32 +316,254 @@ assert(lwtk.isInstanceOf(o2, lwtk.Object)) -## Overriding Methods +## Overriding Members -Methods declared for the derived class are only available for derived objects: +For going on, let's instantiate new class objects: + +```lua +local Foo = lwtk.newClass("Foo") +do + Foo.x = 100 + Foo.y = false + function Foo:getX() + return self.x + end +end +local Bar = lwtk.newClass("Bar", Foo) +``` +It's not allowed to simply declare a member in a subclass that is alread declared in the +superclass: ```lua -function Bar:addX(x) - return self._x + x + +local ok, err = pcall(function() Bar.x = false end) +assert(not ok and err:match('member "x" .* is already defined in superclass')) + +local ok, err = pcall(function() Bar:declare("x") end) +assert(not ok and err:match('member "x" .* is already defined in superclass')) + +local ok, err = pcall(function() Bar.y = 999 end) +assert(not ok and err:match('member "y" .* is already declared in superclass')) + +local ok, err = pcall(function() Bar:declare("y") end) +assert(not ok and err:match('member "y" .* is already declared in superclass')) +``` + +To indicate that overriding a member of the superclass is intentional, +a special `override` syntax has to be used: + +```lua +local t = {} + +Bar.override.x = false +Bar.override.y = t + +local foo = Foo() +local bar = Bar() + +assert(foo.x == 100 and foo.y == false) +assert(bar.x == false and bar.y == t) + +assert(Foo.x == 100 and Foo.y == false) +assert(Bar.x == false and Bar.y == t) +``` + +Each class object may have a special `override` table containing the +overridden members: + +```lua +for k, v in pairs(Bar.override) do + assert(k == "x" and v == false + or k == "y" and v == t) end -assert(o2.addX == nil) -assert(o3.addX ~= nil) -assert(o3:addX(2) == 302) +``` + +This example demonstrates an overriding method calling the +overridden super method: + +```lua +function Bar.override:getX() + return 2 * Foo.getX(self) -- double the value from the superclass +end +foo.x = 100 +bar.x = 200 +assert(foo:getX() == 100) -- invokes Foo.getX +assert(bar:getX() == 400) -- invokes Bar.getX +``` + + +## Implementing Members + + +Use the `implement` table to ensure that the overridden member has no +definition in the superclass. This is especially useful for methods where it +could be crucial to know that a superclass implementation needs not to be +considered: + +```lua +local Foo = lwtk.newClass("Foo") +do + function Foo:m1() + return 100 + end + + Foo.m2 = false + + function Foo:m3() + return 300 + end + + Foo.m4 = false +end + +local Bar = lwtk.newClass("Bar", Foo) +function Bar.override:m1() + return 1000 + Foo.m1(self) -- consider superclass method +end + +function Bar.implement:m2() + return 2000 -- no m2 in superclass +end ``` -Let's override the method `getX` for the derived class: +It is an error to implement members that are defined in the superclass: ```lua -function Bar:getX() - return 2 * Foo.getX(self) -- double the value from the super class +local ok, err = pcall(function() + function Bar.implement:m3() + return 3000 + end +end) +assert(not ok and err:match('member "m3" .* already defined in superclass')) +``` + +It is also an error to implement members that are not declared in the superclass: + +```lua +local ok, err = pcall(function() + function Bar.implement:m3a() + return 3000 + end +end) +assert(not ok and err:match('cannot implement member "m3a"')) +``` + +It is possible to override superclass members that are only declared and not +defined in the superclass (this is especially useful for implementing objects of +type [lwtk.Mixin]): + +```lua +function Bar.override:m4() + if Foo.m4 then + return 4000 + Foo.m4(self) -- consider superclass method + end end -assert(o1:getX() == 100) -- invokes Foo.getX -assert(o3:getX() == 600) -- invokes Bar.getX + ``` + +## Constructors + + +The construction of new derived objects can be customized by implementing the method `new` in +the class object. The `new` method receives the newly created derived object as `self` argument. + +```lua +local Foo = lwtk.newClass("Foo") +do + Foo.x = false + function Foo:new(x) + self.x = x + end +end +local o1 = Foo(100) +local o2 = Foo(200) +assert(o1.x == 100) +assert(o2.x == 200) +``` + +The `new` method can also be overriden like normal methods: + +```lua +local Bar = lwtk.newClass("Bar", Foo) +do + function Bar.override:new(x) + Foo.new(self, 2 * x) -- call superclass new + end +end +local o3 = Bar(300) +assert(o3.x == 600) +``` + + + +## Static Members + + +A table named `static` can be used to declare members that are only available in the +class object and not in the derived objects: + +```lua +local Foo = lwtk.newClass("Foo") +local t = {} +Foo.static.T = t +assert(Foo.T == t) + +local foo = Foo() -- derived object + +local ok, err = pcall(function() print(foo.T) end) +assert(not ok and err:match('member "T" not declared')) + +local ok, err = pcall(function() print(foo.static.T) end) +assert(not ok and err:match('member "static" not declared')) +``` + +Such static members are inherited by subclasses like normal members: +```lua +local Bar = lwtk.newClass("Bar", Foo) +assert(Bar.T == t) +assert(Bar.static.T == t) +``` + + +## Extra Members + + +The `extra` table can be used to declare members that are only available +in the class object's extra table and are not inherited by subclasses +and also not in derived objects: + +```lua +local Foo = lwtk.newClass("Foo") +local t = {} +Foo.extra.T = t + +local ok, err = pcall(function() print(Foo.T) end) +assert(not ok and err:match('no member "T" in class')) + +local Bar = lwtk.newClass("Bar", Foo) +assert(Bar.extra.T == nil) +assert(Foo.extra.T == t) + +local foo = Foo() -- derived object +local bar = Bar() -- derived object + +local ok, err = pcall(function() print(foo.T) end) +assert(not ok and err:match('member "T" not declared in class')) + +local ok, err = pcall(function() print(foo.extra.T) end) +assert(not ok and err:match('member "extra" not declared in class')) + +local ok, err = pcall(function() print(bar.T) end) +assert(not ok and err:match('member "T" not declared in class')) + +local ok, err = pcall(function() print(bar.extra.T) end) +assert(not ok and err:match('member "extra" not declared in class')) + +``` + diff --git a/doc/Meta.md b/doc/Meta.md new file mode 100644 index 0000000..6062dd1 --- /dev/null +++ b/doc/Meta.md @@ -0,0 +1,131 @@ +# lwtk.Meta Usage + +[lwtk.Meta] objects are factories for creating derived objects that are sharing the +same Lua metatable. They are lightweight wrappers around the standard Lua +metatable mechanism. + +[lwtk.Meta]: ./gen/lwtk/Meta.md + + +## Contents + + + * [Creating Meta Objects](#creating-meta-objects) + * [Instantiating Derived Objects](#instantiating-derived-objects) + * [Constructors](#constructors) + * [Example](#example) + + +## Creating Meta Objects + + +Let's start by creating a new meta object named `"Foo"`: + +```lua +local lwtk = require("lwtk") +local Foo = lwtk.newMeta("Foo") +``` + +The new meta object `Foo` is actually a Lua table that has [lwtk.Meta] as metatable. +Its `tostring` value is `"lwtk.Meta"` and *[lwtk.type()]* evaluates to `"lwtk.Meta"`: + +[lwtk.type()]: ./gen/lwtk/type.md + +```lua +assert(type(Foo) == "table") +assert(getmetatable(Foo) == lwtk.Meta) +assert(tostring(Foo) == "lwtk.Meta") +assert(lwtk.type(Foo) == "lwtk.Meta") +``` + + + +The meta object's name is only used for debugging purposes: it is allowed to create two +different meta objects with the same name (although this is not recommended): + +```lua +local Foo2 = lwtk.newMeta("Foo") +assert(Foo ~= Foo2) +assert(tostring(Foo) == tostring(Foo2)) +``` + + +## Instantiating Derived Objects + + +The meta object is used to create new derived objects by simply calling the meta object: + +```lua +local o1 = Foo() +local o2 = Foo() +``` + +The thereby created objects are Lua tables that have `Foo` as metatable. Their `tostring` value +contains the meta name `"Foo"` and *[lwtk.type()]* evaluates to `"Foo"`: + +```lua +for _, o in ipairs{o1, o2} do + assert(type(o) == "table") + assert(getmetatable(o) == Foo) + assert(tostring(o):match("^Foo: [xa-fA-F0-9]+$")) -- e.g. "Foo: 0x55d1e35c2430" + assert(lwtk.type(o) == "Foo") +end +assert(o1 ~= o2) +``` + + + +## Constructors + + +The construction of new derived objects can be customized by implementing the method `new` in +the meta object. The `new` method receives the newly created derived object as `self` argument. + +```lua +function Foo:new(arg) + assert(getmetatable(self) == Foo) + self.arg = arg +end +local o3 = Foo(300) +local o4 = Foo(400) +assert(o3.arg == 300) +assert(o4.arg == 400) +``` + + +## Example + + +Meta objects can be used to create enriched objects by implementing standard Lua metamethods: + +```lua +local Vector = lwtk.newMeta("Vector") + +function Vector:new(x, y) + self.x = x + self.y = y +end + +function Vector:__add(other) + return Vector(self.x + other.x, + self.y + other.y) +end + +function Vector:__tostring() + return string.format("Vector(%d,%d)", self.x, self.y) +end + +local v1 = Vector(100,10) +local v2 = Vector(200,20) + +assert(tostring(v1 + v2) == "Vector(300,30)") +``` + + + diff --git a/doc/Mixin.md b/doc/Mixin.md new file mode 100644 index 0000000..efca9c9 --- /dev/null +++ b/doc/Mixin.md @@ -0,0 +1,193 @@ +# lwtk.Mixin Usage + +[lwtk.Mixin] objects can be used to inject reusable functionality into new [lwtk.Class] +objects. + +[lwtk.Meta]: ./gen/lwtk/Meta.md +[lwtk.Class]: ./gen/lwtk/Class.md +[lwtk.Mixin]: ./gen/lwtk/Mixin.md + + +## Contents + + + * [Creating Mixins](#creating-mixins) + * [Deriving Classes from Mixins](#deriving-classes-from-mixins) + * [First Example](#first-example) + * [Referring to Superclasses](#referring.to-superclasses) + + +## Creating Mixins + + +Let's start by creating a new mixin object named `"Foo"`: + +```lua +local lwtk = require("lwtk") +local Foo = lwtk.newMixin("Foo") +``` + +The new mixin object `Foo` is actually a Lua table that has [lwtk.Mixin] as metatable. +Its `tostring` value is `"lwtk.Mixin"` and *[lwtk.type()]* evaluates to `"lwtk.Mixin"`: + +[lwtk.type()]: ./gen/lwtk/type.md + +```lua +assert(type(Foo) == "table") +assert(getmetatable(Foo) == lwtk.Mixin) +assert(tostring(Foo) == "lwtk.Mixin") +assert(lwtk.type(Foo) == "lwtk.Mixin") +``` + + +The mixin object's name is only used for debugging purposes: it is allowed to create two +different mixin objects with the same name (although this is not recommended): + +```lua +local Foo2 = lwtk.newMixin("Foo") +assert(Foo ~= Foo2) +assert(tostring(Foo) == tostring(Foo2)) +``` + + +## Deriving Classes from Mixins + + +A new class is created by calling the mixin object: + +```lua +local C1 = Foo() +assert(lwtk.type(C1) == "lwtk.Class") +assert(tostring(C1) == "lwtk.Class") +``` +This call is cached, i.e. calling the mixin object again leads to the same class object: + +```lua +assert(C1 == Foo()) +``` + +Objects derived by calling the class have as type name the name `Foo()`: + +```lua +local o1 = C1() +assert(lwtk.type(o1) == "Foo()") +assert(tostring(o1):match("^Foo%(%): [xa-fA-F0-9]+$")) -- e.g. "Foo(): 0x55d1e35c2430" +assert(o1:getClass() == C1) +assert(o1:getSuperClass() == lwtk.Object) +``` + +A base class may be given to the mixin object's call to derive a new class with the +base class as superclass: + +```lua +local Base = lwtk.newClass("Base") +local C2 = Foo(Base) +assert(lwtk.type(C2) == "lwtk.Class") +assert(tostring(C2) == "lwtk.Class") +assert(C2 == Foo(Base)) +assert(C2:getSuperClass() == Base) +``` + +```lua +local o2 = C2() +assert(lwtk.type(o2) == "Foo(Base)") +assert(tostring(o2):match("^Foo%(Base%): [xa-fA-F0-9]+$")) -- e.g. "Foo(Base): 0x55d1e35c2430" +assert(o2:getClass() == C2) +assert(o2:getSuperClass() == Base) +``` + +The mixin class name is marked with a `#` character in the class path: + +```lua +assert(C1:getClassPath() == "#Foo(lwtk.Object)") +assert(C2:getClassPath() == "#Foo(Base(lwtk.Object))") +``` + + +## First Example + + +```lua +local Base1 = lwtk.newClass("Base1") +local Base2 = lwtk.newClass("Base2") + +local Colored = lwtk.newMixin("Colored") +do + Colored.color = false + function Colored:setColor(c) + self.color = c + end + function Colored:getColor(c) + return self.color + end +end + +local Sub1 = lwtk.newClass("Sub1", Colored(Base1)) +local Sub2 = lwtk.newClass("Sub2", Colored(Base2)) + +assert(Sub1:getClassPath() == "Sub1(#Colored(Base1(lwtk.Object)))") +assert(Sub2:getClassPath() == "Sub2(#Colored(Base2(lwtk.Object)))") + +local s1 = Sub1() +local s2 = Sub2() + +s1:setColor("red") +assert(s1:getColor() == "red") + +s2:setColor("blue") +assert(s2:getColor() == "blue") + +assert(Sub1:getSuperClass() == Colored(Base1)) + +``` + + + +## Referring to Superclasses + + +The effective superclass is unknown at the time when a new mixin object is created. A function +may be given to `lwtk.newMixin()` that is called when the mixin object is called to create +a new class object. This function is called with the concrete derived class object and +the superclass: + +```lua +local MyMixin = lwtk.newMixin("MyMixin", + function(MyMixin, Super) + assert(lwtk.type(MyMixin) == "lwtk.Class") + assert(tostring(MyMixin):match("^lwtk.Class$")) + function MyMixin.override:getX() + return 1000 + Super.getX(self) + end + end +) +function MyMixin:getY() + return 2000 +end +function Base1:getX() + return 10 +end +function Base2:getX() + return 20 +end +local Class1 = lwtk.newClass("Class1", MyMixin(Base1)) +local Class2 = lwtk.newClass("Class2", MyMixin(Base2)) +local c1 = Class1() +local c2 = Class2() +assert(c1:getX() == 1010) +assert(c2:getX() == 1020) +assert(c1:getY() == 2000) +assert(c2:getY() == 2000) +``` + + + + + diff --git a/doc/README.md b/doc/README.md index f6b621a..5d3ad8f 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,7 +1,14 @@ # lwtk Documentation -TODO - * [lwtk.Class](Class.md) - declaring classes and instantiate objects - * [lwtk.Application](Application.md) - handling windows and events - * [lwtk.Style](Style.md) - configuring widget styles +## Overview + * [Introduction](Introduction.md) - using lwtk modules. submodules and types + * [lwtk.Meta Usage](Meta.md) - simplified metatable handling + * [lwtk.Class Usage](Class.md) - declaring classes and instantiate objects + * [lwtk.Mixin Usage](Mixin.md) - resusable class extensions + * [lwtk.Application Usage](Application.md) - handling windows and events + * [lwtk.Style Usage](Style.md) - configuring widget styles * TODO + +## Reference + * [Module Index](./gen/modules.md) - list of all lwtk modules + \ No newline at end of file diff --git a/doc/Style.md b/doc/Style.md index c100de1..233888a 100644 --- a/doc/Style.md +++ b/doc/Style.md @@ -1,7 +1,9 @@ -# lwtk.Style +# lwtk.Style Usage The appearance of gui widgets can be configured for the whole application using -objects of type *lwtk.Style*. +objects of type [lwtk.Style]. + +[lwtk.Style]: ./gen/lwtk/Style.md *Style* objects contain rule sets for determining the values of named parameters for a widget according to the widget's class name and the widget's state. @@ -97,9 +99,8 @@ assert(not ok and err:match("Cannot deduce parameter type")) Let's define more widget classes: ```lua -local MyWidget1 = lwtk.newClass("MyWidget1", lwtk.Widget) local MyWidget2 = lwtk.newClass("MyWidget2", lwtk.Widget) -local MyWidget3 = lwtk.newClass("MyWidget3", MyWidget2) -- MyWidget3 is derived from MyWidget2 +local MyWidget3 = lwtk.newClass("MyWidget3", MyWidget2) -- MyWidget3 is subclass of MyWidget2 local MyWidget4 = lwtk.newClass("MyWidget4", lwtk.Widget) ``` diff --git a/doc/gen/lwtk/Actionable.md b/doc/gen/lwtk/Actionable.md new file mode 100644 index 0000000..ca9a3f3 --- /dev/null +++ b/doc/gen/lwtk/Actionable.md @@ -0,0 +1,36 @@ +# Mixin lwtk.Actionable + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _`Actionable`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / _`Actionable`_ / + * **[FocusHandler](../lwtk/FocusHandler.md#inheritance)** + * [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / + * **[Component](../lwtk/Component.md#subclasses)** / + * [Compound](../lwtk/Compound.md#subclasses) / **[InnerCompound](../lwtk/InnerCompound.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + * **[TextCursor](../lwtk/TextCursor.md#inheritance)** + * **[TextFragment](../lwtk/TextFragment.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [KeyHandler](../lwtk/KeyHandler.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Window](../lwtk/Window.md#inheritance)** + diff --git a/doc/gen/lwtk/Animatable.md b/doc/gen/lwtk/Animatable.md new file mode 100644 index 0000000..cc4068a --- /dev/null +++ b/doc/gen/lwtk/Animatable.md @@ -0,0 +1,28 @@ +# Mixin lwtk.Animatable + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / _`Animatable`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / _`Animatable`_ / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + diff --git a/doc/gen/lwtk/Animations.md b/doc/gen/lwtk/Animations.md new file mode 100644 index 0000000..596c335 --- /dev/null +++ b/doc/gen/lwtk/Animations.md @@ -0,0 +1,32 @@ +# Class lwtk.Animations + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [add()](#.add) + * [hasActive()](#.hasActive) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`Animations`**_ + +## Constructor + * **`Animations(app)`** + + + +## Methods + * **`Animations:add(animatable)`** + + + * **`Animations:hasActive()`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Application.md b/doc/gen/lwtk/Application.md new file mode 100644 index 0000000..9064dab --- /dev/null +++ b/doc/gen/lwtk/Application.md @@ -0,0 +1,127 @@ +# Class lwtk.Application + +Default application implementation. + +Use this for standalone desktop applications. Use [lwtk.love.Application](../lwtk/love/Application.md) for +running within the [LÖVE](https://love2d.org/) 2D game engine. + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addStyle()](#.addStyle) + * [close()](#.close) + * [deferChanges()](#.deferChanges) + * [getCurrentTime()](#.getCurrentTime) + * [getFontInfo()](#.getFontInfo) + * [getLayoutContext()](#.getLayoutContext) + * [getScreenScale()](#.getScreenScale) + * [hasWindows()](#.hasWindows) + * [newWindow()](#.newWindow) + * [runEventLoop()](#.runEventLoop) - Update by processing events from the window system. + * [setErrorFunc()](#.setErrorFunc) + * [setExtensions()](#.setExtensions) + * [setStyle()](#.setStyle) + * [setTimer()](#.setTimer) + * [update()](#.update) - Update by processing events from the window system. + * [_addWindow()](#._addWindow) + * [_processAllChanges()](#._processAllChanges) + * [_removeWindow()](#._removeWindow) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`Application`**_ + +## Constructor + * **`Application(arg1, arg2)`** + + + +## Methods + * **`Application:addStyle(additionalStyle)`** + + + * **`Application:close()`** + + + * **`Application:deferChanges(callback)`** + + + * **`Application:getCurrentTime()`** + + + * **`Application:getFontInfo(family, slant, weight, size)`** + + + * **`Application:getLayoutContext()`** + + + * **`Application:getScreenScale()`** + + + * **`Application:hasWindows()`** + + + * **`Application:newWindow(attributes)`** + + + * **`Application:runEventLoop(timeout)`** + + Update by processing events from the window system. + + * *timeout* - optional float, timeout in seconds + + If *timeout* is given, this function will process events from the window system until + the time period in seconds has elapsed or until all window objects have been closed. + + If *timeout* is `nil` or not given, this function will process events from the window system + until all window objects have been closed. + + * **`Application:setErrorFunc(...)`** + + + * **`Application:setExtensions(extensions)`** + + + * **`Application:setStyle(style)`** + + + * **`Application:setTimer(seconds, func, ...)`** + + + * **`Application:update(timeout)`** + + Update by processing events from the window system. + + * *timeout* - optional float, timeout in seconds + + If *timeout* is given, this function will wait for *timeout* seconds until + events from the window system become available. If *timeout* is `nil` or not + given, this function will block indefinitely until an event occurs. + + As soon as events are available, all events in the queue are processed and this function + returns `true`. + + If *timeout* is given and there are no events available after *timeout* + seconds, this function will return `false`. + + * **`Application:_addWindow(win)`** + + + * **`Application:_processAllChanges()`** + + + * **`Application:_removeWindow(win)`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / _**`Application`**_ / [Node](../lwtk/Node.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[love.Application](../lwtk/love/Application.md#inheritance)** + diff --git a/doc/gen/lwtk/Area.md b/doc/gen/lwtk/Area.md new file mode 100644 index 0000000..3e84aed --- /dev/null +++ b/doc/gen/lwtk/Area.md @@ -0,0 +1,73 @@ +# Class lwtk.Area + +A list of rectangle coordinates forming an area. + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addRect()](#.addRect) - Adds the rectangle coordinates to the area. + * [clear()](#.clear) - Clears all rectangle coordinates. + * [getRect()](#.getRect) - Obtain coordinates of the i-th rectangle from the area. + * [intersects()](#.intersects) - Returns *true* if the given rectangle coordinates intersect the area. + * [intersectsBorder()](#.intersectsBorder) + * [isWithin()](#.isWithin) - Returns *true* if the given rectangle coordinates are within the area. + * [iteration()](#.iteration) - Iterate through all rectangle coordinates. + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`Area`**_ + +## Constructor + * **`Area()`** + + Creates an empty area object. + + +## Methods + * **`Area:addRect(x, y, w, h)`** + + Adds the rectangle coordinates to the area. + + * **`Area:clear()`** + + Clears all rectangle coordinates. After this the + area does not contain any rectangle, i.e. *area.count == 0*. + + * **`Area:getRect(i)`** + + Obtain coordinates of the i-th rectangle from the area. + + * *i* - index of the rectangle, *1 <= i <= area.count* + + Returns *x, y, w, h* rectangle coordinates + + * **`Area:intersects(x, y, w, h)`** + + Returns *true* if the given rectangle coordinates intersect + the area. + + * **`Area:intersectsBorder(x, y, w, h, borderWidth)`** + + + * **`Area:isWithin(x, y, w, h)`** + + Returns *true* if the given rectangle coordinates are + within the area. + + * **`Area:iteration()`** + + Iterate through all rectangle coordinates. + + Returns an *iterator function*, *self* and *0*, so that the construction + ```lua + for i, x, y, w, h in area:iteration() do ... end + ``` + will iterate over all rectangle indices and coordinates. + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Box.md b/doc/gen/lwtk/Box.md new file mode 100644 index 0000000..49045a5 --- /dev/null +++ b/doc/gen/lwtk/Box.md @@ -0,0 +1,57 @@ +# Class lwtk.Box + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getMeasures()](#.getMeasures) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / _**`Box`**_ + +## Constructor + * **`Box(initParams)`** + + * Inherited from: **[Group()](../lwtk/Group.md#constructor)** + + +## Methods + * **`Box:getMeasures()`** + + * Implementation: [LayoutFrame:extra.getMeasures()](../lwtk/LayoutFrame.md#extra.getMeasures) + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + +## Inherited Methods + * [LayoutFrame](../lwtk/LayoutFrame.md): + * [addChild()](../lwtk/LayoutFrame.md#.addChild), [onDraw()](../lwtk/LayoutFrame.md#.onDraw), [onLayout()](../lwtk/LayoutFrame.md#.onLayout) + * **[Group](../lwtk/Group.md)**: + * [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / _**`Box`**_ / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + diff --git a/doc/gen/lwtk/BuiltinStyleTypes.md b/doc/gen/lwtk/BuiltinStyleTypes.md new file mode 100644 index 0000000..e5a2e53 --- /dev/null +++ b/doc/gen/lwtk/BuiltinStyleTypes.md @@ -0,0 +1,5 @@ +# Function lwtk.BuiltinStyleTypes + + * **`BuiltinStyleTypes()`** + + diff --git a/doc/gen/lwtk/Button.md b/doc/gen/lwtk/Button.md new file mode 100644 index 0000000..84e0229 --- /dev/null +++ b/doc/gen/lwtk/Button.md @@ -0,0 +1,47 @@ +# Class lwtk.Button + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / [HotkeyListener](../lwtk/HotkeyListener.md#inheritance) / _**`Button`**_ + +## Constructor + * **`Button(initParams)`** + + * Inherited from: **[Widget()](../lwtk/Widget.md#constructor)** + + +## Inherited Methods + * [HotkeyListener](../lwtk/HotkeyListener.md): + * [isHotkeyEnabled()](../lwtk/HotkeyListener.md#.isHotkeyEnabled), [onDisabled()](../lwtk/HotkeyListener.md#.onDisabled), [onEffectiveVisibilityChanged()](../lwtk/HotkeyListener.md#.onEffectiveVisibilityChanged), [onHotkeyDisabled()](../lwtk/HotkeyListener.md#.onHotkeyDisabled), [onHotkeyEnabled()](../lwtk/HotkeyListener.md#.onHotkeyEnabled), [setHotkey()](../lwtk/HotkeyListener.md#.setHotkey), [_handleHasFocusHandler()](../lwtk/HotkeyListener.md#._handleHasFocusHandler) + * [LayoutFrame](../lwtk/LayoutFrame.md): + * [addChild()](../lwtk/LayoutFrame.md#.addChild), [onDraw()](../lwtk/LayoutFrame.md#.onDraw), [onLayout()](../lwtk/LayoutFrame.md#.onLayout) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / _**`Button`**_ / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + diff --git a/doc/gen/lwtk/Callback.md b/doc/gen/lwtk/Callback.md new file mode 100644 index 0000000..ab31502 --- /dev/null +++ b/doc/gen/lwtk/Callback.md @@ -0,0 +1,14 @@ +# Meta lwtk.Callback + +Holds a function with arguments that can +be called. + +## Contents + + * [Constructor](#constructor) + + +## Constructor + * **`Callback(func, ...)`** + + diff --git a/doc/gen/lwtk/ChildLookup.md b/doc/gen/lwtk/ChildLookup.md new file mode 100644 index 0000000..46b0ff2 --- /dev/null +++ b/doc/gen/lwtk/ChildLookup.md @@ -0,0 +1,12 @@ +# Meta lwtk.ChildLookup + + +## Contents + + * [Constructor](#constructor) + + +## Constructor + * **`ChildLookup(group)`** + + diff --git a/doc/gen/lwtk/Class.md b/doc/gen/lwtk/Class.md new file mode 100644 index 0000000..4d3a606 --- /dev/null +++ b/doc/gen/lwtk/Class.md @@ -0,0 +1,7 @@ +# Table lwtk.Class + +Metatable for objects created by [lwtk.newClass](../lwtk/newClass.md)(). + +See [lwtk.Class Usage](../../Class.md) for detailed documentation +and usage examples. + diff --git a/doc/gen/lwtk/Color.md b/doc/gen/lwtk/Color.md new file mode 100644 index 0000000..5da7e6c --- /dev/null +++ b/doc/gen/lwtk/Color.md @@ -0,0 +1,74 @@ +# Class lwtk.Color + +RGBA Color value. + +Contains the float values *r (red)*, *g (green)*, *b (blue)* and optional +*a (alpha value)* in the range >= 0 and <= 1. + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [lighten()](#.lighten) + * [saturate()](#.saturate) + * [toHex()](#.toHex) + * [toRGB()](#.toRGB) + * [toRGBA()](#.toRGBA) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`Color`**_ + +## Constructor + * **`Color(...)`** + + Creates a new RGBA color value. + + Possible invocations: + + * **`Color()`** + + If called without arguments, the color black is created, i.e. + *r = g = b = 0*. + + * **`Color(r,g,b,a)`** + + If more than one arg is given, arguments are the float color + values *r*, *g*, *b*, *a* with the alpha value *a* being optional. + + * **`Color(table)`** + + * *table* - a table with the entries for the keys *r*, *g*, *b* + with optional alpha value *a*. + Missing entries for *r*, *g*, *b* are treated as 0. + + * **`Color(string)`** + + * *string* - a string in hex encoding with length 6 or 8 + (format *"rrggbb"* or *"rrggbbaa"*). Each color value + consists of two hexadecimal digits and is in the range + *00 <= value <= ff*, alpha value is optional. + + +## Methods + * **`Color:lighten(amount)`** + + + * **`Color:saturate(amount)`** + + + * **`Color:toHex()`** + + + * **`Color:toRGB()`** + + + * **`Color:toRGBA(a)`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Colored.md b/doc/gen/lwtk/Colored.md new file mode 100644 index 0000000..4ade7b7 --- /dev/null +++ b/doc/gen/lwtk/Colored.md @@ -0,0 +1,15 @@ +# Mixin lwtk.Colored + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / _`Colored`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / _`Colored`_ / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + diff --git a/doc/gen/lwtk/Column.md b/doc/gen/lwtk/Column.md new file mode 100644 index 0000000..e45bd3a --- /dev/null +++ b/doc/gen/lwtk/Column.md @@ -0,0 +1,55 @@ +# Class lwtk.Column + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getMeasures()](#.getMeasures) + * [onLayout()](#.onLayout) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / _**`Column`**_ + +## Constructor + * **`Column(initParams)`** + + * Inherited from: **[Group()](../lwtk/Group.md#constructor)** + + +## Methods + * **`Column:getMeasures()`** + + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`Column:onLayout(width, height, isLayoutTransition)`** + + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + +## Inherited Methods + * **[Group](../lwtk/Group.md)**: + * [addChild()](../lwtk/Group.md#.addChild), [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Component.md b/doc/gen/lwtk/Component.md new file mode 100644 index 0000000..f8764aa --- /dev/null +++ b/doc/gen/lwtk/Component.md @@ -0,0 +1,156 @@ +# Class lwtk.Component + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [animateFrame()](#.animateFrame) + * [byId()](#.byId) + * [getCurrentTime()](#.getCurrentTime) + * [getFocusHandler()](#.getFocusHandler) + * [getFontInfo()](#.getFontInfo) + * [getFrame()](#.getFrame) + * [getLayoutContext()](#.getLayoutContext) + * [getParent()](#.getParent) + * [getRoot()](#.getRoot) + * [getSize()](#.getSize) + * [handleRemainingInitParams()](#.handleRemainingInitParams) + * [parentById()](#.parentById) + * [setFrame()](#.setFrame) + * [setInitParams()](#.setInitParams) + * [setTimer()](#.setTimer) + * [transformXY()](#.transformXY) + * [triggerLayout()](#.triggerLayout) + * [triggerRedraw()](#.triggerRedraw) + * [updateAnimation()](#.updateAnimation) + * [updateFrameTransition()](#.updateFrameTransition) + * [_processChanges()](#._processChanges) + * [_processDraw()](#._processDraw) + * [_setApp()](#._setApp) + * [_setFrame()](#._setFrame) + * [_setParent()](#._setParent) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / _**`Component`**_ + +## Constructor + * **`Component(initParams)`** + + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`Component:animateFrame(...)`** + + + * **`Component:byId(id)`** + + + * **`Component:getCurrentTime()`** + + + * **`Component:getFocusHandler()`** + + + * **`Component:getFontInfo(family, slant, weight, size)`** + + + * **`Component:getFrame()`** + + + * **`Component:getLayoutContext()`** + + + * **`Component:getParent()`** + + + * **`Component:getRoot()`** + + + * **`Component:getSize()`** + + + * **`Component:handleRemainingInitParams(initParams)`** + + * Overrides: [Actionable:handleRemainingInitParams()](../lwtk/Actionable.md#.handleRemainingInitParams) + + + * **`Component:parentById(id)`** + + + * **`Component:setFrame(...)`** + + + * **`Component:setInitParams(initParams)`** + + * Overrides: [Actionable:setInitParams()](../lwtk/Actionable.md#.setInitParams) + + + * **`Component:setTimer(seconds, func, ...)`** + + + * **`Component:transformXY(x, y, parent)`** + + + * **`Component:triggerLayout()`** + + + * **`Component:triggerRedraw()`** + + + * **`Component:updateAnimation()`** + + + * **`Component:updateFrameTransition()`** + + + * **`Component:_processChanges(x0, y0, cx, cy, cw, ch, damagedArea)`** + + + * **`Component:_processDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea)`** + + + * **`Component:_setApp(app)`** + + + * **`Component:_setFrame(newX, newY, newW, newH, fromFrameAnimation)`** + + + * **`Component:_setParent(parent)`** + + + +## Inherited Methods + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [getStyleParam()](../lwtk/Drawable.md#.getStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / _**`Component`**_ / + * [Compound](../lwtk/Compound.md#subclasses) / **[InnerCompound](../lwtk/InnerCompound.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + * **[TextCursor](../lwtk/TextCursor.md#inheritance)** + * **[TextFragment](../lwtk/TextFragment.md#inheritance)** + diff --git a/doc/gen/lwtk/Compound.md b/doc/gen/lwtk/Compound.md new file mode 100644 index 0000000..741fb20 --- /dev/null +++ b/doc/gen/lwtk/Compound.md @@ -0,0 +1,32 @@ +# Mixin lwtk.Compound + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / + * _`Compound`_ + * [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / _`Compound`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / + * _`Compound`_ / **[InnerCompound](../lwtk/InnerCompound.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / _`Compound`_ / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + diff --git a/doc/gen/lwtk/Control.md b/doc/gen/lwtk/Control.md new file mode 100644 index 0000000..674280d --- /dev/null +++ b/doc/gen/lwtk/Control.md @@ -0,0 +1,23 @@ +# Mixin lwtk.Control + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / + * [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / _`Control`_ + * [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / _`Control`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / _`Control`_ / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / _`Control`_ / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + diff --git a/doc/gen/lwtk/DefaultKeyBinding.md b/doc/gen/lwtk/DefaultKeyBinding.md new file mode 100644 index 0000000..8e79c7b --- /dev/null +++ b/doc/gen/lwtk/DefaultKeyBinding.md @@ -0,0 +1,5 @@ +# Function lwtk.DefaultKeyBinding + + * **`DefaultKeyBinding()`** + + Returns new [lwtk.KeyBinding](../lwtk/KeyBinding.md) object with default settings. diff --git a/doc/gen/lwtk/DefaultStyle.md b/doc/gen/lwtk/DefaultStyle.md new file mode 100644 index 0000000..96ed246 --- /dev/null +++ b/doc/gen/lwtk/DefaultStyle.md @@ -0,0 +1,25 @@ +# Class lwtk.DefaultStyle + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / **[Style](../lwtk/Style.md#inheritance)** / _**`DefaultStyle`**_ + +## Constructor + * **`DefaultStyle(initParams)`** + + * Overrides: **[Style()](../lwtk/Style.md#constructor)** + + + +## Inherited Methods + * **[Style](../lwtk/Style.md)**: + * [addRules()](../lwtk/Style.md#.addRules), [clearCache()](../lwtk/Style.md#.clearCache), [getScaleFactor()](../lwtk/Style.md#.getScaleFactor), [getStyleParam()](../lwtk/Style.md#.getStyleParam), [isAnimatable()](../lwtk/Style.md#.isAnimatable), [isScalable()](../lwtk/Style.md#.isScalable), [setRules()](../lwtk/Style.md#.setRules), [setScaleFactor()](../lwtk/Style.md#.setScaleFactor), [_getStyleParam()](../lwtk/Style.md#._getStyleParam), [_getStyleParam2()](../lwtk/Style.md#._getStyleParam2), [_replaceParentStyle()](../lwtk/Style.md#._replaceParentStyle), [_setParentStyle()](../lwtk/Style.md#._setParentStyle) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Drawable.md b/doc/gen/lwtk/Drawable.md new file mode 100644 index 0000000..2118085 --- /dev/null +++ b/doc/gen/lwtk/Drawable.md @@ -0,0 +1,34 @@ +# Mixin lwtk.Drawable + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / _`Drawable`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / _`Drawable`_ / + * **[Component](../lwtk/Component.md#subclasses)** / + * [Compound](../lwtk/Compound.md#subclasses) / **[InnerCompound](../lwtk/InnerCompound.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + * **[TextCursor](../lwtk/TextCursor.md#inheritance)** + * **[TextFragment](../lwtk/TextFragment.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [KeyHandler](../lwtk/KeyHandler.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Window](../lwtk/Window.md#inheritance)** + diff --git a/doc/gen/lwtk/FocusGroup.md b/doc/gen/lwtk/FocusGroup.md new file mode 100644 index 0000000..9c9e449 --- /dev/null +++ b/doc/gen/lwtk/FocusGroup.md @@ -0,0 +1,122 @@ +# Class lwtk.FocusGroup + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [handleHotkey()](#.handleHotkey) + * [invokeActionMethod()](#.invokeActionMethod) + * [onActionEnterFocusGroup()](#.onActionEnterFocusGroup) + * [onActionExitFocusGroup()](#.onActionExitFocusGroup) + * [onKeyDown()](#.onKeyDown) + * [setFocus()](#.setFocus) + * [_handleChildRequestsFocus()](#._handleChildRequestsFocus) + * [_handleFocusIn()](#._handleFocusIn) + * [_handleFocusOut()](#._handleFocusOut) + * [_processMouseDown()](#._processMouseDown) + * [_setApp()](#._setApp) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / **[Box](../lwtk/Box.md#inheritance)** / [Focusable](../lwtk/Focusable.md#inheritance) / _**`FocusGroup`**_ + +## Constructor + * **`FocusGroup(...)`** + + * Overrides: **[Group()](../lwtk/Group.md#constructor)** + * Overrides: [MouseDispatcher()](../lwtk/MouseDispatcher.md#constructor) + * Overrides: **[Widget()](../lwtk/Widget.md#constructor)** + * Overrides: [Animatable()](../lwtk/Animatable.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`FocusGroup:handleHotkey(key, modifier, ...)`** + + * Implements: [Focusable:handleHotkey()](../lwtk/Focusable.md#.handleHotkey) + + + * **`FocusGroup:invokeActionMethod(actionMethodName)`** + + * Overrides: [Actionable:invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + + + * **`FocusGroup:onActionEnterFocusGroup()`** + + + * **`FocusGroup:onActionExitFocusGroup()`** + + + * **`FocusGroup:onKeyDown(key, modifier, ...)`** + + * Implements: [Focusable:onKeyDown()](../lwtk/Focusable.md#.onKeyDown) + + + * **`FocusGroup:setFocus(flag)`** + + * Overrides: [Focusable:setFocus()](../lwtk/Focusable.md#.setFocus) + + + * **`FocusGroup:_handleChildRequestsFocus()`** + + * Implements: [Group:_handleChildRequestsFocus()](../lwtk/Group.md#._handleChildRequestsFocus) + + + * **`FocusGroup:_handleFocusIn()`** + + * Overrides: [Focusable:_handleFocusIn()](../lwtk/Focusable.md#._handleFocusIn) + * Implements: [Component:_handleFocusIn()](../lwtk/Component.md#._handleFocusIn) + + + * **`FocusGroup:_handleFocusOut(reallyLostFocus)`** + + * Overrides: [Focusable:_handleFocusOut()](../lwtk/Focusable.md#._handleFocusOut) + + + * **`FocusGroup:_processMouseDown(mx, my, button, modState)`** + + * Overrides: [MouseDispatcher:_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown) + * Overrides: [Drawable:_processMouseDown()](../lwtk/Drawable.md#._processMouseDown) + * Implements: [Node:_processMouseDown()](../lwtk/Node.md#._processMouseDown) + + + * **`FocusGroup:_setApp(app)`** + + * Overrides: [Widget:_setApp()](../lwtk/Widget.md#._setApp) + * Overrides: [Component:_setApp()](../lwtk/Component.md#._setApp) + + + +## Inherited Methods + * [Focusable](../lwtk/Focusable.md): + * [onDisabled()](../lwtk/Focusable.md#.onDisabled), [onEffectiveVisibilityChanged()](../lwtk/Focusable.md#.onEffectiveVisibilityChanged), [_handleHasFocusHandler()](../lwtk/Focusable.md#._handleHasFocusHandler) + * **[Box](../lwtk/Box.md)**: + * [getMeasures()](../lwtk/Box.md#.getMeasures) + * [LayoutFrame](../lwtk/LayoutFrame.md): + * [addChild()](../lwtk/LayoutFrame.md#.addChild), [onDraw()](../lwtk/LayoutFrame.md#.onDraw), [onLayout()](../lwtk/LayoutFrame.md#.onLayout) + * **[Group](../lwtk/Group.md)**: + * [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/FocusHandler.md b/doc/gen/lwtk/FocusHandler.md new file mode 100644 index 0000000..92bed50 --- /dev/null +++ b/doc/gen/lwtk/FocusHandler.md @@ -0,0 +1,140 @@ +# Class lwtk.FocusHandler + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [childById()](#.childById) + * [deregisterHotkeys()](#.deregisterHotkeys) + * [findNextInput()](#.findNextInput) + * [findPrevInput()](#.findPrevInput) + * [handleHotkey()](#.handleHotkey) + * [hasActionMethod()](#.hasActionMethod) + * [invokeActionMethod()](#.invokeActionMethod) + * [isDefault()](#.isDefault) + * [onActionCloseWindow()](#.onActionCloseWindow) + * [onActionDefaultButton()](#.onActionDefaultButton) + * [onActionFocusDown()](#.onActionFocusDown) + * [onActionFocusLeft()](#.onActionFocusLeft) + * [onActionFocusNext()](#.onActionFocusNext) + * [onActionFocusPrev()](#.onActionFocusPrev) + * [onActionFocusRight()](#.onActionFocusRight) + * [onActionFocusUp()](#.onActionFocusUp) + * [onKeyDown()](#.onKeyDown) + * [registerHotkeys()](#.registerHotkeys) + * [releaseFocus()](#.releaseFocus) + * [setDefault()](#.setDefault) + * [setFocusDisabled()](#.setFocusDisabled) + * [setFocusTo()](#.setFocusTo) + * [setFocusToNextInput()](#.setFocusToNextInput) + * [setFocusToPrevInput()](#.setFocusToPrevInput) + * [_handleFocusIn()](#._handleFocusIn) + * [_handleFocusOut()](#._handleFocusOut) + * [_setParentFocusHandler()](#._setParentFocusHandler) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / _**`FocusHandler`**_ + +## Constructor + * **`FocusHandler(baseWidget)`** + + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`FocusHandler:childById(id)`** + + + * **`FocusHandler:deregisterHotkeys(widget, hotkeys)`** + + + * **`FocusHandler:findNextInput(child)`** + + + * **`FocusHandler:findPrevInput(child)`** + + + * **`FocusHandler:handleHotkey(key, modifier, ...)`** + + + * **`FocusHandler:hasActionMethod(actionMethodName)`** + + * Overrides: [Actionable:hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod) + + + * **`FocusHandler:invokeActionMethod(actionMethodName)`** + + * Overrides: [Actionable:invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + + + * **`FocusHandler:isDefault(childOrId)`** + + + * **`FocusHandler:onActionCloseWindow()`** + + + * **`FocusHandler:onActionDefaultButton()`** + + + * **`FocusHandler:onActionFocusDown()`** + + + * **`FocusHandler:onActionFocusLeft()`** + + + * **`FocusHandler:onActionFocusNext()`** + + + * **`FocusHandler:onActionFocusPrev()`** + + + * **`FocusHandler:onActionFocusRight()`** + + + * **`FocusHandler:onActionFocusUp()`** + + + * **`FocusHandler:onKeyDown(key, modifier, keyText, hotKeyName)`** + + + * **`FocusHandler:registerHotkeys(widget, hotkeys)`** + + + * **`FocusHandler:releaseFocus(child)`** + + + * **`FocusHandler:setDefault(childOrId, defaultFlag)`** + + + * **`FocusHandler:setFocusDisabled(child, disableFlag)`** + + + * **`FocusHandler:setFocusTo(newFocusChild)`** + + + * **`FocusHandler:setFocusToNextInput(child)`** + + + * **`FocusHandler:setFocusToPrevInput(child)`** + + + * **`FocusHandler:_handleFocusIn()`** + + + * **`FocusHandler:_handleFocusOut()`** + + + * **`FocusHandler:_setParentFocusHandler(parentFocusHandler)`** + + + +## Inherited Methods + * [Actionable](../lwtk/Actionable.md): + * [handleRemainingInitParams()](../lwtk/Actionable.md#.handleRemainingInitParams), [setInitParams()](../lwtk/Actionable.md#.setInitParams) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Focusable.md b/doc/gen/lwtk/Focusable.md new file mode 100644 index 0000000..e385e1a --- /dev/null +++ b/doc/gen/lwtk/Focusable.md @@ -0,0 +1,23 @@ +# Mixin lwtk.Focusable + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / + * [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / + * _`Focusable`_ + * [HotkeyListener](../lwtk/HotkeyListener.md#inheritance) / **[Button](../lwtk/Button.md#inheritance)** / _`Focusable`_ + * [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / **[Box](../lwtk/Box.md#inheritance)** / _`Focusable`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * _`Focusable`_ / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / _`Focusable`_ / **[PushButton](../lwtk/PushButton.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / _`Focusable`_ / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + diff --git a/doc/gen/lwtk/FontInfo.md b/doc/gen/lwtk/FontInfo.md new file mode 100644 index 0000000..62be7dc --- /dev/null +++ b/doc/gen/lwtk/FontInfo.md @@ -0,0 +1,32 @@ +# Class lwtk.FontInfo + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getTextWidth()](#.getTextWidth) + * [selectInto()](#.selectInto) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`FontInfo`**_ + +## Constructor + * **`FontInfo(layoutContext, family, slant, weight, size)`** + + + +## Methods + * **`FontInfo:getTextWidth(text)`** + + + * **`FontInfo:selectInto(otherCtx)`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/FontInfos.md b/doc/gen/lwtk/FontInfos.md new file mode 100644 index 0000000..ce92362 --- /dev/null +++ b/doc/gen/lwtk/FontInfos.md @@ -0,0 +1,28 @@ +# Class lwtk.FontInfos + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getFontInfo()](#.getFontInfo) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`FontInfos`**_ + +## Constructor + * **`FontInfos(layoutContext)`** + + + +## Methods + * **`FontInfos:getFontInfo(family, slant, weight, size)`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Group.md b/doc/gen/lwtk/Group.md new file mode 100644 index 0000000..e48630b --- /dev/null +++ b/doc/gen/lwtk/Group.md @@ -0,0 +1,74 @@ +# Class lwtk.Group + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addChild()](#.addChild) + * [childById()](#.childById) + * [_clearChildLookup()](#._clearChildLookup) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / _**`Group`**_ + +## Constructor + * **`Group(initParams)`** + + * Overrides: [MouseDispatcher()](../lwtk/MouseDispatcher.md#constructor) + * Overrides: **[Widget()](../lwtk/Widget.md#constructor)** + * Overrides: [Animatable()](../lwtk/Animatable.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`Group:addChild(child)`** + + * Overrides: [Compound:addChild()](../lwtk/Compound.md#.addChild) + * Implements: [Drawable:addChild()](../lwtk/Drawable.md#.addChild) + + + * **`Group:childById(id)`** + + + * **`Group:_clearChildLookup()`** + + + +## Inherited Methods + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / _**`Group`**_ / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + diff --git a/doc/gen/lwtk/HotkeyListener.md b/doc/gen/lwtk/HotkeyListener.md new file mode 100644 index 0000000..51cc054 --- /dev/null +++ b/doc/gen/lwtk/HotkeyListener.md @@ -0,0 +1,17 @@ +# Mixin lwtk.HotkeyListener + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / _`HotkeyListener`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / _`HotkeyListener`_ / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + diff --git a/doc/gen/lwtk/InnerCompound.md b/doc/gen/lwtk/InnerCompound.md new file mode 100644 index 0000000..e1ae0e1 --- /dev/null +++ b/doc/gen/lwtk/InnerCompound.md @@ -0,0 +1,30 @@ +# Class lwtk.InnerCompound + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / _**`InnerCompound`**_ + +## Constructor + * **`InnerCompound(initParams)`** + + * Inherited from: **[Component()](../lwtk/Component.md#constructor)** + + +## Inherited Methods + * [Compound](../lwtk/Compound.md): + * [addChild()](../lwtk/Compound.md#.addChild), [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Component](../lwtk/Component.md)**: + * [animateFrame()](../lwtk/Component.md#.animateFrame), [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateAnimation()](../lwtk/Component.md#.updateAnimation), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setApp()](../lwtk/Component.md#._setApp), [_setFrame()](../lwtk/Component.md#._setFrame), [_setParent()](../lwtk/Component.md#._setParent) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [getStyleParam()](../lwtk/Drawable.md#.getStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/KeyBinding.md b/doc/gen/lwtk/KeyBinding.md new file mode 100644 index 0000000..80ccb20 --- /dev/null +++ b/doc/gen/lwtk/KeyBinding.md @@ -0,0 +1,12 @@ +# Meta lwtk.KeyBinding + + +## Contents + + * [Constructor](#constructor) + + +## Constructor + * **`KeyBinding(rules)`** + + diff --git a/doc/gen/lwtk/KeyHandler.md b/doc/gen/lwtk/KeyHandler.md new file mode 100644 index 0000000..4662f4a --- /dev/null +++ b/doc/gen/lwtk/KeyHandler.md @@ -0,0 +1,15 @@ +# Mixin lwtk.KeyHandler + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / [Styleable](../lwtk/Styleable.md#inheritance) / _`KeyHandler`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / [Styleable](../lwtk/Styleable.md#subclasses) / _`KeyHandler`_ / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Window](../lwtk/Window.md#inheritance)** + diff --git a/doc/gen/lwtk/LayoutFrame.md b/doc/gen/lwtk/LayoutFrame.md new file mode 100644 index 0000000..df734fc --- /dev/null +++ b/doc/gen/lwtk/LayoutFrame.md @@ -0,0 +1,23 @@ +# Mixin lwtk.LayoutFrame + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / + * _`LayoutFrame`_ + * [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / _`LayoutFrame`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * _`LayoutFrame`_ / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / _`LayoutFrame`_ / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + diff --git a/doc/gen/lwtk/Matrix.md b/doc/gen/lwtk/Matrix.md new file mode 100644 index 0000000..d436f0f --- /dev/null +++ b/doc/gen/lwtk/Matrix.md @@ -0,0 +1,62 @@ +# Class lwtk.Matrix + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getMeasures()](#.getMeasures) + * [onLayout()](#.onLayout) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / _**`Matrix`**_ + +## Constructor + * **`Matrix(initParams)`** + + * Overrides: **[Group()](../lwtk/Group.md#constructor)** + * Overrides: [MouseDispatcher()](../lwtk/MouseDispatcher.md#constructor) + * Overrides: **[Widget()](../lwtk/Widget.md#constructor)** + * Overrides: [Animatable()](../lwtk/Animatable.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`Matrix:getMeasures()`** + + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`Matrix:onLayout(width, height, isLayoutTransition)`** + + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + +## Inherited Methods + * **[Group](../lwtk/Group.md)**: + * [addChild()](../lwtk/Group.md#.addChild), [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Meta.md b/doc/gen/lwtk/Meta.md new file mode 100644 index 0000000..6e88ec6 --- /dev/null +++ b/doc/gen/lwtk/Meta.md @@ -0,0 +1,7 @@ +# Table lwtk.Meta + +Metatable for objects created by [lwtk.newMeta](../lwtk/newMeta.md)(). + +See [lwtk,Meta Usage](../../Meta.md) for detailed documentation +and usage examples. + diff --git a/doc/gen/lwtk/Mixin.md b/doc/gen/lwtk/Mixin.md new file mode 100644 index 0000000..799b4a6 --- /dev/null +++ b/doc/gen/lwtk/Mixin.md @@ -0,0 +1,7 @@ +# Table lwtk.Mixin + +Metatable for objects created by [lwtk.newMixin](../lwtk/newMixin.md)(). + +See [lwtk.Mixin Usage](../../Mixin.md) for detailed documentation +and usage examples. + diff --git a/doc/gen/lwtk/MouseDispatcher.md b/doc/gen/lwtk/MouseDispatcher.md new file mode 100644 index 0000000..a04262d --- /dev/null +++ b/doc/gen/lwtk/MouseDispatcher.md @@ -0,0 +1,30 @@ +# Mixin lwtk.MouseDispatcher + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / + * [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / + * **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / _`MouseDispatcher`_ + * [Styleable](../lwtk/Styleable.md#inheritance) / [KeyHandler](../lwtk/KeyHandler.md#inheritance) / _`MouseDispatcher`_ + * **[Application](../lwtk/Application.md#inheritance)** / [Node](../lwtk/Node.md#inheritance) / _`MouseDispatcher`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / + * [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / + * **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / _`MouseDispatcher`_ / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [KeyHandler](../lwtk/KeyHandler.md#subclasses) / _`MouseDispatcher`_ / **[Window](../lwtk/Window.md#inheritance)** + * **[Application](../lwtk/Application.md#subclasses)** / [Node](../lwtk/Node.md#subclasses) / _`MouseDispatcher`_ / **[love.Application](../lwtk/love/Application.md#inheritance)** + diff --git a/doc/gen/lwtk/Node.md b/doc/gen/lwtk/Node.md new file mode 100644 index 0000000..293ea32 --- /dev/null +++ b/doc/gen/lwtk/Node.md @@ -0,0 +1,38 @@ +# Mixin lwtk.Node + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / + * [Actionable](../lwtk/Actionable.md#inheritance) / _`Node`_ + * **[Application](../lwtk/Application.md#inheritance)** / _`Node`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / + * [Actionable](../lwtk/Actionable.md#subclasses) / _`Node`_ / [Drawable](../lwtk/Drawable.md#subclasses) / + * **[Component](../lwtk/Component.md#subclasses)** / + * [Compound](../lwtk/Compound.md#subclasses) / **[InnerCompound](../lwtk/InnerCompound.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + * **[TextCursor](../lwtk/TextCursor.md#inheritance)** + * **[TextFragment](../lwtk/TextFragment.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [KeyHandler](../lwtk/KeyHandler.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Window](../lwtk/Window.md#inheritance)** + * **[Application](../lwtk/Application.md#subclasses)** / _`Node`_ / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[love.Application](../lwtk/love/Application.md#inheritance)** + diff --git a/doc/gen/lwtk/Object.md b/doc/gen/lwtk/Object.md new file mode 100644 index 0000000..e153c1e --- /dev/null +++ b/doc/gen/lwtk/Object.md @@ -0,0 +1,91 @@ +# Class lwtk.Object + +Superclass for all classes created by [lwtk.newClass](../lwtk/newClass.md)(). + +## Contents + + * [Methods](#methods) + * [getClass()](#.getClass) + * [getClassPath()](#.getClassPath) + * [getMember()](#.getMember) + * [getReverseClassPath()](#.getReverseClassPath) + * [getSuperClass()](#.getSuperClass) - Returns the superclass of this object. + * [isInstanceOf()](#.isInstanceOf) - Determines if object is instance of the given class. + * [setAttributes()](#.setAttributes) + * [Subclasses](#subclasses) + + +## Methods + * **`Object:getClass()`** + + + * **`Object:getClassPath()`** + + + * **`Object:getMember(name)`** + + + * **`Object:getReverseClassPath()`** + + + * **`Object:getSuperClass()`** + + Returns the superclass of this object. + + This method can also be called on a class. In this + case the superclass of the given class is returned. + + * **`Object:isInstanceOf(C)`** + + Determines if object is instance of the given class. + + Returns *true*, if *self* is an object that was created by invoking class *C* + or by invoking a subclass of *C*. + + Returns also *true* if *C* is a metatable of *self* or somewhere in the + metatable chain of *self*. + * Implementation: [lwtk.isInstanceOf()](../lwtk/isInstanceOf.md) + + * **`Object:setAttributes(attr)`** + + + +## Subclasses + * / _**`Object`**_ / + * [Actionable](../lwtk/Actionable.md#subclasses) / + * **[FocusHandler](../lwtk/FocusHandler.md#inheritance)** + * [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / + * **[Component](../lwtk/Component.md#subclasses)** / + * [Compound](../lwtk/Compound.md#subclasses) / **[InnerCompound](../lwtk/InnerCompound.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + * **[TextCursor](../lwtk/TextCursor.md#inheritance)** + * **[TextFragment](../lwtk/TextFragment.md#inheritance)** + * [Styleable](../lwtk/Styleable.md#subclasses) / [KeyHandler](../lwtk/KeyHandler.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Window](../lwtk/Window.md#inheritance)** + * **[Animations](../lwtk/Animations.md#inheritance)** + * **[Application](../lwtk/Application.md#subclasses)** / [Node](../lwtk/Node.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[love.Application](../lwtk/love/Application.md#inheritance)** + * **[Area](../lwtk/Area.md#inheritance)** + * **[Color](../lwtk/Color.md#inheritance)** + * **[FontInfo](../lwtk/FontInfo.md#inheritance)** + * **[FontInfos](../lwtk/FontInfos.md#inheritance)** + * **[Rect](../lwtk/Rect.md#inheritance)** + * **[Style](../lwtk/Style.md#subclasses)** / **[DefaultStyle](../lwtk/DefaultStyle.md#inheritance)** + * **[Timer](../lwtk/Timer.md#inheritance)** + * **[love.Driver](../lwtk/love/Driver.md#inheritance)** + * **[love.LayoutContext](../lwtk/love/LayoutContext.md#subclasses)** / **[love.DrawContext](../lwtk/love/DrawContext.md#inheritance)** + * **[love.View](../lwtk/love/View.md#inheritance)** + * **[lpugl.CairoLayoutContext](../lwtk/lpugl/CairoLayoutContext.md#subclasses)** / **[lpugl.CairoDrawContext](../lwtk/lpugl/CairoDrawContext.md#inheritance)** + * **[lpugl.Driver](../lwtk/lpugl/Driver.md#inheritance)** + diff --git a/doc/gen/lwtk/PushButton.md b/doc/gen/lwtk/PushButton.md new file mode 100644 index 0000000..9ce80eb --- /dev/null +++ b/doc/gen/lwtk/PushButton.md @@ -0,0 +1,132 @@ +# Class lwtk.PushButton + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getMeasures()](#.getMeasures) + * [onActionFocusedButtonClick()](#.onActionFocusedButtonClick) + * [onDefaultChanged()](#.onDefaultChanged) + * [onHotkeyDisabled()](#.onHotkeyDisabled) + * [onHotkeyDown()](#.onHotkeyDown) + * [onHotkeyEnabled()](#.onHotkeyEnabled) + * [onLayout()](#.onLayout) + * [onMouseDown()](#.onMouseDown) + * [onMouseEnter()](#.onMouseEnter) + * [onMouseLeave()](#.onMouseLeave) + * [onMouseUp()](#.onMouseUp) + * [setDefault()](#.setDefault) + * [setDisabled()](#.setDisabled) + * [setOnClicked()](#.setOnClicked) + * [setText()](#.setText) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / [HotkeyListener](../lwtk/HotkeyListener.md#inheritance) / **[Button](../lwtk/Button.md#inheritance)** / [Focusable](../lwtk/Focusable.md#inheritance) / _**`PushButton`**_ + +## Constructor + * **`PushButton(initParams)`** + + * Overrides: **[Widget()](../lwtk/Widget.md#constructor)** + * Overrides: [Animatable()](../lwtk/Animatable.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`PushButton:getMeasures()`** + + * Implementation: [TextLabel:getMeasures()](../lwtk/TextLabel.md#getMeasures) + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`PushButton:onActionFocusedButtonClick()`** + + + * **`PushButton:onDefaultChanged(isCurrentDefault, isPrincipalDefault)`** + + + * **`PushButton:onHotkeyDisabled(hotkey)`** + + * Overrides: [HotkeyListener:onHotkeyDisabled()](../lwtk/HotkeyListener.md#.onHotkeyDisabled) + + + * **`PushButton:onHotkeyDown()`** + + * Implements: [Focusable:onHotkeyDown()](../lwtk/Focusable.md#.onHotkeyDown) + + + * **`PushButton:onHotkeyEnabled(hotkey)`** + + * Overrides: [HotkeyListener:onHotkeyEnabled()](../lwtk/HotkeyListener.md#.onHotkeyEnabled) + * Implements: [Component:onHotkeyEnabled()](../lwtk/Component.md#.onHotkeyEnabled) + + + * **`PushButton:onLayout(width, height)`** + + * Overrides: [LayoutFrame:onLayout()](../lwtk/LayoutFrame.md#.onLayout) + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + * **`PushButton:onMouseDown(x, y, button, modState)`** + + * Implements: [Node:onMouseDown()](../lwtk/Node.md#.onMouseDown) + + + * **`PushButton:onMouseEnter(x, y)`** + + * Implements: [Node:onMouseEnter()](../lwtk/Node.md#.onMouseEnter) + + + * **`PushButton:onMouseLeave(x, y)`** + + * Implements: [Node:onMouseLeave()](../lwtk/Node.md#.onMouseLeave) + + + * **`PushButton:onMouseUp(x, y, button, modState)`** + + * Implements: [Node:onMouseUp()](../lwtk/Node.md#.onMouseUp) + + + * **`PushButton:setDefault(defaultFlag)`** + + * Implementation: [Focusable:extra.setDefault()](../lwtk/Focusable.md#extra.setDefault) + + * **`PushButton:setDisabled(flag)`** + + + * **`PushButton:setOnClicked(onClicked)`** + + + * **`PushButton:setText(text)`** + + + +## Inherited Methods + * [Focusable](../lwtk/Focusable.md): + * [onDisabled()](../lwtk/Focusable.md#.onDisabled), [onEffectiveVisibilityChanged()](../lwtk/Focusable.md#.onEffectiveVisibilityChanged), [setFocus()](../lwtk/Focusable.md#.setFocus), [_handleFocusIn()](../lwtk/Focusable.md#._handleFocusIn), [_handleFocusOut()](../lwtk/Focusable.md#._handleFocusOut), [_handleHasFocusHandler()](../lwtk/Focusable.md#._handleHasFocusHandler) + * [HotkeyListener](../lwtk/HotkeyListener.md): + * [isHotkeyEnabled()](../lwtk/HotkeyListener.md#.isHotkeyEnabled), [setHotkey()](../lwtk/HotkeyListener.md#.setHotkey) + * [LayoutFrame](../lwtk/LayoutFrame.md): + * [addChild()](../lwtk/LayoutFrame.md#.addChild), [onDraw()](../lwtk/LayoutFrame.md#.onDraw) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Rect.md b/doc/gen/lwtk/Rect.md new file mode 100644 index 0000000..3617db5 --- /dev/null +++ b/doc/gen/lwtk/Rect.md @@ -0,0 +1,55 @@ +# Class lwtk.Rect + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [contains()](#.contains) + * [intersects()](#.intersects) + * [toXYWH()](#.toXYWH) + * [Functions](#functions) + * [areRectsIntersected()](#.areRectsIntersected) + * [doesRectContain()](#.doesRectContain) + * [intersectRects()](#.intersectRects) + * [round()](#.round) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`Rect`**_ + +## Constructor + * **`Rect(x, y, w, h)`** + + + +## Methods + * **`Rect:contains(x, y, w, h)`** + + + * **`Rect:intersects(x, y, w, h)`** + + + * **`Rect:toXYWH()`** + + + +## Functions + * **`Rect.areRectsIntersected(x1, y1, w1, h1, x2, y2, w2, h2)`** + + + * **`Rect.doesRectContain(x1, y1, w1, h1, x2, y2, w2, h2)`** + + + * **`Rect.intersectRects(x1, y1, w1, h1, x2, y2, w2, h2)`** + + + * **`Rect.round(x, y, w, h)`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Row.md b/doc/gen/lwtk/Row.md new file mode 100644 index 0000000..14d4ab6 --- /dev/null +++ b/doc/gen/lwtk/Row.md @@ -0,0 +1,55 @@ +# Class lwtk.Row + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getMeasures()](#.getMeasures) + * [onLayout()](#.onLayout) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / _**`Row`**_ + +## Constructor + * **`Row(initParams)`** + + * Inherited from: **[Group()](../lwtk/Group.md#constructor)** + + +## Methods + * **`Row:getMeasures()`** + + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`Row:onLayout(width, height, isLayoutTransition)`** + + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + +## Inherited Methods + * **[Group](../lwtk/Group.md)**: + * [addChild()](../lwtk/Group.md#.addChild), [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Space.md b/doc/gen/lwtk/Space.md new file mode 100644 index 0000000..bc44710 --- /dev/null +++ b/doc/gen/lwtk/Space.md @@ -0,0 +1,67 @@ +# Class lwtk.Space + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addChild()](#.addChild) + * [getMeasures()](#.getMeasures) + * [onLayout()](#.onLayout) + * [setUnlimited()](#.setUnlimited) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / _**`Space`**_ + +## Constructor + * **`Space(initParams)`** + + * Inherited from: **[Group()](../lwtk/Group.md#constructor)** + + +## Methods + * **`Space:addChild(child)`** + + * Overrides: [Group:addChild()](../lwtk/Group.md#.addChild) + * Overrides: [Compound:addChild()](../lwtk/Compound.md#.addChild) + * Implements: [Drawable:addChild()](../lwtk/Drawable.md#.addChild) + + + * **`Space:getMeasures()`** + + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`Space:onLayout(w, h)`** + + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + * **`Space:setUnlimited(unlimited)`** + + + +## Inherited Methods + * **[Group](../lwtk/Group.md)**: + * [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Square.md b/doc/gen/lwtk/Square.md new file mode 100644 index 0000000..587c57a --- /dev/null +++ b/doc/gen/lwtk/Square.md @@ -0,0 +1,63 @@ +# Class lwtk.Square + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addChild()](#.addChild) + * [getMeasures()](#.getMeasures) + * [onLayout()](#.onLayout) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / _**`Square`**_ + +## Constructor + * **`Square(initParams)`** + + * Inherited from: **[Group()](../lwtk/Group.md#constructor)** + + +## Methods + * **`Square:addChild(child)`** + + * Overrides: [Group:addChild()](../lwtk/Group.md#.addChild) + * Overrides: [Compound:addChild()](../lwtk/Compound.md#.addChild) + * Implements: [Drawable:addChild()](../lwtk/Drawable.md#.addChild) + + + * **`Square:getMeasures()`** + + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`Square:onLayout(w, h)`** + + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + +## Inherited Methods + * **[Group](../lwtk/Group.md)**: + * [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/Style.md b/doc/gen/lwtk/Style.md new file mode 100644 index 0000000..1e9a897 --- /dev/null +++ b/doc/gen/lwtk/Style.md @@ -0,0 +1,77 @@ +# Class lwtk.Style + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addRules()](#.addRules) + * [clearCache()](#.clearCache) + * [getScaleFactor()](#.getScaleFactor) + * [getStyleParam()](#.getStyleParam) + * [isAnimatable()](#.isAnimatable) + * [isScalable()](#.isScalable) + * [setRules()](#.setRules) + * [setScaleFactor()](#.setScaleFactor) + * [_getStyleParam()](#._getStyleParam) + * [_getStyleParam2()](#._getStyleParam2) + * [_replaceParentStyle()](#._replaceParentStyle) + * [_setParentStyle()](#._setParentStyle) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`Style`**_ + +## Constructor + * **`Style(ruleList)`** + + + +## Methods + * **`Style:addRules(rules)`** + + + * **`Style:clearCache()`** + + + * **`Style:getScaleFactor()`** + + + * **`Style:getStyleParam(widget, parName)`** + + + * **`Style:isAnimatable(parName)`** + + + * **`Style:isScalable(parName)`** + + + * **`Style:setRules(rules)`** + + + * **`Style:setScaleFactor(scaleFactor)`** + + + * **`Style:_getStyleParam(parName, classSelectorPath, stateSelectorPath, considerLocal, extraParentStyle)`** + + + * **`Style:_getStyleParam2(parName, classSelectorPath, stateSelectorPath, ctxRules)`** + + + * **`Style:_replaceParentStyle(parentStyle)`** + + + * **`Style:_setParentStyle(parentStyle)`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / _**`Style`**_ / **[DefaultStyle](../lwtk/DefaultStyle.md#inheritance)** + diff --git a/doc/gen/lwtk/StyleRef.md b/doc/gen/lwtk/StyleRef.md new file mode 100644 index 0000000..b703e38 --- /dev/null +++ b/doc/gen/lwtk/StyleRef.md @@ -0,0 +1,3 @@ +# Table lwtk.StyleRef + + diff --git a/doc/gen/lwtk/StyleTypeAttributes.md b/doc/gen/lwtk/StyleTypeAttributes.md new file mode 100644 index 0000000..1b43b95 --- /dev/null +++ b/doc/gen/lwtk/StyleTypeAttributes.md @@ -0,0 +1,3 @@ +# Table lwtk.StyleTypeAttributes + + diff --git a/doc/gen/lwtk/Styleable.md b/doc/gen/lwtk/Styleable.md new file mode 100644 index 0000000..a673f48 --- /dev/null +++ b/doc/gen/lwtk/Styleable.md @@ -0,0 +1,32 @@ +# Mixin lwtk.Styleable + + +## Contents + + * [Inheritance](#inheritance) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / + * **[Component](../lwtk/Component.md#inheritance)** / _`Styleable`_ + * _`Styleable`_ + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / + * **[Component](../lwtk/Component.md#subclasses)** / _`Styleable`_ / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + * _`Styleable`_ / [KeyHandler](../lwtk/KeyHandler.md#subclasses) / [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Window](../lwtk/Window.md#inheritance)** + diff --git a/doc/gen/lwtk/TextCursor.md b/doc/gen/lwtk/TextCursor.md new file mode 100644 index 0000000..925f11d --- /dev/null +++ b/doc/gen/lwtk/TextCursor.md @@ -0,0 +1,37 @@ +# Class lwtk.TextCursor + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [onDraw()](#.onDraw) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / _**`TextCursor`**_ + +## Constructor + * **`TextCursor(initParams)`** + + * Inherited from: **[Component()](../lwtk/Component.md#constructor)** + + +## Methods + * **`TextCursor:onDraw(ctx)`** + + * Implements: [Component:onDraw()](../lwtk/Component.md#.onDraw) + + + +## Inherited Methods + * **[Component](../lwtk/Component.md)**: + * [animateFrame()](../lwtk/Component.md#.animateFrame), [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateAnimation()](../lwtk/Component.md#.updateAnimation), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_processChanges()](../lwtk/Component.md#._processChanges), [_processDraw()](../lwtk/Component.md#._processDraw), [_setApp()](../lwtk/Component.md#._setApp), [_setFrame()](../lwtk/Component.md#._setFrame), [_setParent()](../lwtk/Component.md#._setParent) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [getStyleParam()](../lwtk/Drawable.md#.getStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/TextFragment.md b/doc/gen/lwtk/TextFragment.md new file mode 100644 index 0000000..69ae57c --- /dev/null +++ b/doc/gen/lwtk/TextFragment.md @@ -0,0 +1,65 @@ +# Class lwtk.TextFragment + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getFontInfo()](#.getFontInfo) + * [getTextMeasures()](#.getTextMeasures) + * [onDraw()](#.onDraw) + * [setConsiderHotkey()](#.setConsiderHotkey) + * [setShowHotkey()](#.setShowHotkey) + * [setText()](#.setText) + * [setTextPos()](#.setTextPos) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / _**`TextFragment`**_ + +## Constructor + * **`TextFragment(initParams)`** + + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`TextFragment:getFontInfo(family, slant, weight, size)`** + + * Overrides: [Component:getFontInfo()](../lwtk/Component.md#.getFontInfo) + + + * **`TextFragment:getTextMeasures()`** + + + * **`TextFragment:onDraw(ctx, ...)`** + + * Implements: [Component:onDraw()](../lwtk/Component.md#.onDraw) + + + * **`TextFragment:setConsiderHotkey(flag)`** + + + * **`TextFragment:setShowHotkey(flag)`** + + + * **`TextFragment:setText(text)`** + + + * **`TextFragment:setTextPos(tx, ty)`** + + + +## Inherited Methods + * **[Component](../lwtk/Component.md)**: + * [animateFrame()](../lwtk/Component.md#.animateFrame), [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateAnimation()](../lwtk/Component.md#.updateAnimation), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_processChanges()](../lwtk/Component.md#._processChanges), [_processDraw()](../lwtk/Component.md#._processDraw), [_setApp()](../lwtk/Component.md#._setApp), [_setFrame()](../lwtk/Component.md#._setFrame), [_setParent()](../lwtk/Component.md#._setParent) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [getStyleParam()](../lwtk/Drawable.md#.getStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/TextInput.md b/doc/gen/lwtk/TextInput.md new file mode 100644 index 0000000..be44082 --- /dev/null +++ b/doc/gen/lwtk/TextInput.md @@ -0,0 +1,136 @@ +# Class lwtk.TextInput + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getMeasures()](#.getMeasures) + * [onActionCursorLeft()](#.onActionCursorLeft) + * [onActionCursorRight()](#.onActionCursorRight) + * [onActionCursorToBeginOfLine()](#.onActionCursorToBeginOfLine) + * [onActionCursorToEndOfLine()](#.onActionCursorToEndOfLine) + * [onActionDeleteCharLeft()](#.onActionDeleteCharLeft) + * [onActionDeleteCharRight()](#.onActionDeleteCharRight) + * [onActionInputNext()](#.onActionInputNext) + * [onActionInputPrev()](#.onActionInputPrev) + * [onFocusIn()](#.onFocusIn) + * [onFocusOut()](#.onFocusOut) + * [onKeyDown()](#.onKeyDown) + * [onLayout()](#.onLayout) + * [onMouseDown()](#.onMouseDown) + * [onRealize()](#.onRealize) + * [setDefault()](#.setDefault) + * [setFilterInput()](#.setFilterInput) + * [setText()](#.setText) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / [Focusable](../lwtk/Focusable.md#inheritance) / _**`TextInput`**_ + +## Constructor + * **`TextInput(initParams)`** + + * Overrides: **[Widget()](../lwtk/Widget.md#constructor)** + * Overrides: [Animatable()](../lwtk/Animatable.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`TextInput:getMeasures()`** + + * Implementation: [TextLabel:getMeasures()](../lwtk/TextLabel.md#getMeasures) + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`TextInput:onActionCursorLeft()`** + + + * **`TextInput:onActionCursorRight()`** + + + * **`TextInput:onActionCursorToBeginOfLine()`** + + + * **`TextInput:onActionCursorToEndOfLine()`** + + + * **`TextInput:onActionDeleteCharLeft()`** + + + * **`TextInput:onActionDeleteCharRight()`** + + + * **`TextInput:onActionInputNext()`** + + + * **`TextInput:onActionInputPrev()`** + + + * **`TextInput:onFocusIn()`** + + * Implements: [Focusable:onFocusIn()](../lwtk/Focusable.md#.onFocusIn) + + + * **`TextInput:onFocusOut()`** + + * Implements: [Focusable:onFocusOut()](../lwtk/Focusable.md#.onFocusOut) + + + * **`TextInput:onKeyDown(keyName, keyState, keyText)`** + + * Implements: [Focusable:onKeyDown()](../lwtk/Focusable.md#.onKeyDown) + + + * **`TextInput:onLayout(width, height)`** + + * Overrides: [LayoutFrame:onLayout()](../lwtk/LayoutFrame.md#.onLayout) + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + * **`TextInput:onMouseDown(mx, my, button, modState)`** + + * Implements: [Node:onMouseDown()](../lwtk/Node.md#.onMouseDown) + + + * **`TextInput:onRealize()`** + + * Implements: [Component:onRealize()](../lwtk/Component.md#.onRealize) + + + * **`TextInput:setDefault(buttonId)`** + + + * **`TextInput:setFilterInput(filterInput)`** + + + * **`TextInput:setText(text)`** + + + +## Inherited Methods + * [Focusable](../lwtk/Focusable.md): + * [onDisabled()](../lwtk/Focusable.md#.onDisabled), [onEffectiveVisibilityChanged()](../lwtk/Focusable.md#.onEffectiveVisibilityChanged), [setFocus()](../lwtk/Focusable.md#.setFocus), [_handleFocusIn()](../lwtk/Focusable.md#._handleFocusIn), [_handleFocusOut()](../lwtk/Focusable.md#._handleFocusOut), [_handleHasFocusHandler()](../lwtk/Focusable.md#._handleHasFocusHandler) + * [LayoutFrame](../lwtk/LayoutFrame.md): + * [addChild()](../lwtk/LayoutFrame.md#.addChild), [onDraw()](../lwtk/LayoutFrame.md#.onDraw) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/TextLabel.md b/doc/gen/lwtk/TextLabel.md new file mode 100644 index 0000000..a78c724 --- /dev/null +++ b/doc/gen/lwtk/TextLabel.md @@ -0,0 +1,97 @@ +# Class lwtk.TextLabel + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getMeasures()](#.getMeasures) + * [onHotkeyDisabled()](#.onHotkeyDisabled) + * [onHotkeyDown()](#.onHotkeyDown) + * [onHotkeyEnabled()](#.onHotkeyEnabled) + * [onLayout()](#.onLayout) + * [onMouseDown()](#.onMouseDown) + * [setInput()](#.setInput) + * [setText()](#.setText) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / [HotkeyListener](../lwtk/HotkeyListener.md#inheritance) / **[Button](../lwtk/Button.md#inheritance)** / _**`TextLabel`**_ + +## Constructor + * **`TextLabel(initParams)`** + + * Overrides: **[Widget()](../lwtk/Widget.md#constructor)** + * Overrides: [Animatable()](../lwtk/Animatable.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`TextLabel:getMeasures()`** + + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`TextLabel:onHotkeyDisabled(hotkey)`** + + * Overrides: [HotkeyListener:onHotkeyDisabled()](../lwtk/HotkeyListener.md#.onHotkeyDisabled) + + + * **`TextLabel:onHotkeyDown()`** + + + * **`TextLabel:onHotkeyEnabled(hotkey)`** + + * Overrides: [HotkeyListener:onHotkeyEnabled()](../lwtk/HotkeyListener.md#.onHotkeyEnabled) + * Implements: [Component:onHotkeyEnabled()](../lwtk/Component.md#.onHotkeyEnabled) + + + * **`TextLabel:onLayout(width, height)`** + + * Overrides: [LayoutFrame:onLayout()](../lwtk/LayoutFrame.md#.onLayout) + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + * **`TextLabel:onMouseDown(x, y, button, modState)`** + + * Implements: [Node:onMouseDown()](../lwtk/Node.md#.onMouseDown) + + + * **`TextLabel:setInput(inputId)`** + + + * **`TextLabel:setText(text)`** + + + +## Inherited Methods + * [HotkeyListener](../lwtk/HotkeyListener.md): + * [isHotkeyEnabled()](../lwtk/HotkeyListener.md#.isHotkeyEnabled), [onDisabled()](../lwtk/HotkeyListener.md#.onDisabled), [onEffectiveVisibilityChanged()](../lwtk/HotkeyListener.md#.onEffectiveVisibilityChanged), [setHotkey()](../lwtk/HotkeyListener.md#.setHotkey), [_handleHasFocusHandler()](../lwtk/HotkeyListener.md#._handleHasFocusHandler) + * [LayoutFrame](../lwtk/LayoutFrame.md): + * [addChild()](../lwtk/LayoutFrame.md#.addChild), [onDraw()](../lwtk/LayoutFrame.md#.onDraw) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / **[Widget](../lwtk/Widget.md#subclasses)** / [Compound](../lwtk/Compound.md#subclasses) / [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / _**`TextLabel`**_ / **[TitleText](../lwtk/TitleText.md#inheritance)** + diff --git a/doc/gen/lwtk/Timer.md b/doc/gen/lwtk/Timer.md new file mode 100644 index 0000000..a28e2eb --- /dev/null +++ b/doc/gen/lwtk/Timer.md @@ -0,0 +1,21 @@ +# Class lwtk.Timer + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / _**`Timer`**_ + +## Constructor + * **`Timer(func, ...)`** + + + +## Inherited Methods + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/TitleText.md b/doc/gen/lwtk/TitleText.md new file mode 100644 index 0000000..45bc98a --- /dev/null +++ b/doc/gen/lwtk/TitleText.md @@ -0,0 +1,42 @@ +# Class lwtk.TitleText + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [LayoutFrame](../lwtk/LayoutFrame.md#inheritance) / [Control](../lwtk/Control.md#inheritance) / [HotkeyListener](../lwtk/HotkeyListener.md#inheritance) / **[Button](../lwtk/Button.md#inheritance)** / **[TextLabel](../lwtk/TextLabel.md#inheritance)** / _**`TitleText`**_ + +## Constructor + * **`TitleText(initParams)`** + + * Inherited from: **[TextLabel()](../lwtk/TextLabel.md#constructor)** + + +## Inherited Methods + * **[TextLabel](../lwtk/TextLabel.md)**: + * [getMeasures()](../lwtk/TextLabel.md#.getMeasures), [onHotkeyDisabled()](../lwtk/TextLabel.md#.onHotkeyDisabled), [onHotkeyDown()](../lwtk/TextLabel.md#.onHotkeyDown), [onHotkeyEnabled()](../lwtk/TextLabel.md#.onHotkeyEnabled), [onLayout()](../lwtk/TextLabel.md#.onLayout), [onMouseDown()](../lwtk/TextLabel.md#.onMouseDown), [setInput()](../lwtk/TextLabel.md#.setInput), [setText()](../lwtk/TextLabel.md#.setText) + * [HotkeyListener](../lwtk/HotkeyListener.md): + * [isHotkeyEnabled()](../lwtk/HotkeyListener.md#.isHotkeyEnabled), [onDisabled()](../lwtk/HotkeyListener.md#.onDisabled), [onEffectiveVisibilityChanged()](../lwtk/HotkeyListener.md#.onEffectiveVisibilityChanged), [setHotkey()](../lwtk/HotkeyListener.md#.setHotkey), [_handleHasFocusHandler()](../lwtk/HotkeyListener.md#._handleHasFocusHandler) + * [LayoutFrame](../lwtk/LayoutFrame.md): + * [addChild()](../lwtk/LayoutFrame.md#.addChild), [onDraw()](../lwtk/LayoutFrame.md#.onDraw) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/ViewSwitcher.md b/doc/gen/lwtk/ViewSwitcher.md new file mode 100644 index 0000000..17960e0 --- /dev/null +++ b/doc/gen/lwtk/ViewSwitcher.md @@ -0,0 +1,69 @@ +# Class lwtk.ViewSwitcher + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addChild()](#.addChild) + * [getMeasures()](#.getMeasures) + * [onLayout()](#.onLayout) + * [showChild()](#.showChild) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / **[Widget](../lwtk/Widget.md#inheritance)** / [Compound](../lwtk/Compound.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / **[Group](../lwtk/Group.md#inheritance)** / [Colored](../lwtk/Colored.md#inheritance) / _**`ViewSwitcher`**_ + +## Constructor + * **`ViewSwitcher(initParams)`** + + * Inherited from: **[Group()](../lwtk/Group.md#constructor)** + + +## Methods + * **`ViewSwitcher:addChild(child)`** + + * Overrides: [Group:addChild()](../lwtk/Group.md#.addChild) + * Overrides: [Compound:addChild()](../lwtk/Compound.md#.addChild) + * Implements: [Drawable:addChild()](../lwtk/Drawable.md#.addChild) + + + * **`ViewSwitcher:getMeasures()`** + + * Implements: [Component:getMeasures()](../lwtk/Component.md#.getMeasures) + + + * **`ViewSwitcher:onLayout(w, h)`** + + * Implements: [Component:onLayout()](../lwtk/Component.md#.onLayout) + + + * **`ViewSwitcher:showChild(child)`** + + + +## Inherited Methods + * [Colored](../lwtk/Colored.md): + * [onDraw()](../lwtk/Colored.md#.onDraw) + * **[Group](../lwtk/Group.md)**: + * [childById()](../lwtk/Group.md#.childById), [_clearChildLookup()](../lwtk/Group.md#._clearChildLookup) + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [Compound](../lwtk/Compound.md): + * [_processChanges()](../lwtk/Compound.md#._processChanges), [_processDraw()](../lwtk/Compound.md#._processDraw) + * **[Widget](../lwtk/Widget.md)**: + * [notifyInputChanged()](../lwtk/Widget.md#.notifyInputChanged), [setOnInputChanged()](../lwtk/Widget.md#.setOnInputChanged), [setOnRealize()](../lwtk/Widget.md#.setOnRealize), [_setApp()](../lwtk/Widget.md#._setApp), [_setParent()](../lwtk/Widget.md#._setParent) + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/WeakKeysTable.md b/doc/gen/lwtk/WeakKeysTable.md new file mode 100644 index 0000000..8579c30 --- /dev/null +++ b/doc/gen/lwtk/WeakKeysTable.md @@ -0,0 +1,3 @@ +# Meta lwtk.WeakKeysTable + + diff --git a/doc/gen/lwtk/Widget.md b/doc/gen/lwtk/Widget.md new file mode 100644 index 0000000..bd284df --- /dev/null +++ b/doc/gen/lwtk/Widget.md @@ -0,0 +1,81 @@ +# Class lwtk.Widget + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [notifyInputChanged()](#.notifyInputChanged) + * [setOnInputChanged()](#.setOnInputChanged) + * [setOnRealize()](#.setOnRealize) + * [_setApp()](#._setApp) + * [_setParent()](#._setParent) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / **[Component](../lwtk/Component.md#inheritance)** / [Styleable](../lwtk/Styleable.md#inheritance) / [Animatable](../lwtk/Animatable.md#inheritance) / _**`Widget`**_ + +## Constructor + * **`Widget(initParams)`** + + * Overrides: [Animatable()](../lwtk/Animatable.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: **[Component()](../lwtk/Component.md#constructor)** + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`Widget:notifyInputChanged()`** + + + * **`Widget:setOnInputChanged(onInputChanged)`** + + + * **`Widget:setOnRealize(onRealize)`** + + + * **`Widget:_setApp(app)`** + + * Overrides: [Component:_setApp()](../lwtk/Component.md#._setApp) + + + * **`Widget:_setParent(parent)`** + + * Overrides: [Component:_setParent()](../lwtk/Component.md#._setParent) + + + +## Inherited Methods + * [Animatable](../lwtk/Animatable.md): + * [animateFrame()](../lwtk/Animatable.md#.animateFrame), [getStyle()](../lwtk/Animatable.md#.getStyle), [getStyleParam()](../lwtk/Animatable.md#.getStyleParam), [isVisible()](../lwtk/Animatable.md#.isVisible), [setState()](../lwtk/Animatable.md#.setState), [setStates()](../lwtk/Animatable.md#.setStates), [setStyle()](../lwtk/Animatable.md#.setStyle), [setVisible()](../lwtk/Animatable.md#.setVisible), [updateAnimation()](../lwtk/Animatable.md#.updateAnimation), [_setStyleFromParent()](../lwtk/Animatable.md#._setStyleFromParent) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam) + * **[Component](../lwtk/Component.md)**: + * [byId()](../lwtk/Component.md#.byId), [getCurrentTime()](../lwtk/Component.md#.getCurrentTime), [getFocusHandler()](../lwtk/Component.md#.getFocusHandler), [getFontInfo()](../lwtk/Component.md#.getFontInfo), [getFrame()](../lwtk/Component.md#.getFrame), [getLayoutContext()](../lwtk/Component.md#.getLayoutContext), [getParent()](../lwtk/Component.md#.getParent), [getRoot()](../lwtk/Component.md#.getRoot), [getSize()](../lwtk/Component.md#.getSize), [handleRemainingInitParams()](../lwtk/Component.md#.handleRemainingInitParams), [parentById()](../lwtk/Component.md#.parentById), [setFrame()](../lwtk/Component.md#.setFrame), [setInitParams()](../lwtk/Component.md#.setInitParams), [setTimer()](../lwtk/Component.md#.setTimer), [transformXY()](../lwtk/Component.md#.transformXY), [triggerLayout()](../lwtk/Component.md#.triggerLayout), [triggerRedraw()](../lwtk/Component.md#.triggerRedraw), [updateFrameTransition()](../lwtk/Component.md#.updateFrameTransition), [_processChanges()](../lwtk/Component.md#._processChanges), [_processDraw()](../lwtk/Component.md#._processDraw), [_setFrame()](../lwtk/Component.md#._setFrame) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam), [_processMouseDown()](../lwtk/Drawable.md#._processMouseDown), [_processMouseEnter()](../lwtk/Drawable.md#._processMouseEnter), [_processMouseLeave()](../lwtk/Drawable.md#._processMouseLeave), [_processMouseMove()](../lwtk/Drawable.md#._processMouseMove), [_processMouseScroll()](../lwtk/Drawable.md#._processMouseScroll), [_processMouseUp()](../lwtk/Drawable.md#._processMouseUp) + * [Actionable](../lwtk/Actionable.md): + * [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../lwtk/Object.md#subclasses)** / [Actionable](../lwtk/Actionable.md#subclasses) / [Node](../lwtk/Node.md#subclasses) / [Drawable](../lwtk/Drawable.md#subclasses) / **[Component](../lwtk/Component.md#subclasses)** / [Styleable](../lwtk/Styleable.md#subclasses) / [Animatable](../lwtk/Animatable.md#subclasses) / _**`Widget`**_ / [Compound](../lwtk/Compound.md#subclasses) / + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[TextInput](../lwtk/TextInput.md#inheritance)** + * [HotkeyListener](../lwtk/HotkeyListener.md#subclasses) / **[Button](../lwtk/Button.md#subclasses)** / + * [Focusable](../lwtk/Focusable.md#subclasses) / **[PushButton](../lwtk/PushButton.md#inheritance)** + * **[TextLabel](../lwtk/TextLabel.md#subclasses)** / **[TitleText](../lwtk/TitleText.md#inheritance)** + * [MouseDispatcher](../lwtk/MouseDispatcher.md#subclasses) / **[Group](../lwtk/Group.md#subclasses)** / + * [Colored](../lwtk/Colored.md#subclasses) / **[ViewSwitcher](../lwtk/ViewSwitcher.md#inheritance)** + * **[Column](../lwtk/Column.md#inheritance)** + * [LayoutFrame](../lwtk/LayoutFrame.md#subclasses) / [Control](../lwtk/Control.md#subclasses) / **[Box](../lwtk/Box.md#subclasses)** / [Focusable](../lwtk/Focusable.md#subclasses) / **[FocusGroup](../lwtk/FocusGroup.md#inheritance)** + * **[Matrix](../lwtk/Matrix.md#inheritance)** + * **[Row](../lwtk/Row.md#inheritance)** + * **[Space](../lwtk/Space.md#inheritance)** + * **[Square](../lwtk/Square.md#inheritance)** + diff --git a/doc/gen/lwtk/Window.md b/doc/gen/lwtk/Window.md new file mode 100644 index 0000000..bb5e039 --- /dev/null +++ b/doc/gen/lwtk/Window.md @@ -0,0 +1,217 @@ +# Class lwtk.Window + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [addChild()](#.addChild) + * [byId()](#.byId) + * [childById()](#.childById) + * [close()](#.close) + * [getCurrentTime()](#.getCurrentTime) + * [getFontInfo()](#.getFontInfo) + * [getLayoutContext()](#.getLayoutContext) + * [getNativeHandle()](#.getNativeHandle) + * [getRoot()](#.getRoot) + * [getSize()](#.getSize) + * [hide()](#.hide) + * [isClosed()](#.isClosed) + * [requestClose()](#.requestClose) + * [requestFocus()](#.requestFocus) + * [setColor()](#.setColor) + * [setFrame()](#.setFrame) + * [setInterceptKeyDown()](#.setInterceptKeyDown) + * [setInterceptMouseDown()](#.setInterceptMouseDown) + * [setMaxSize()](#.setMaxSize) + * [setMaxSizeFixed()](#.setMaxSizeFixed) + * [setMinSize()](#.setMinSize) + * [setOnClose()](#.setOnClose) + * [setOnSizeRequest()](#.setOnSizeRequest) + * [setSize()](#.setSize) + * [setTimer()](#.setTimer) + * [setTitle()](#.setTitle) + * [show()](#.show) + * [triggerLayout()](#.triggerLayout) + * [triggerRedraw()](#.triggerRedraw) + * [_clearChildLookup()](#._clearChildLookup) + * [_handleConfigure()](#._handleConfigure) + * [_handleExpose()](#._handleExpose) + * [_handleFocusIn()](#._handleFocusIn) + * [_handleFocusOut()](#._handleFocusOut) + * [_handleMap()](#._handleMap) + * [_handleMouseDown()](#._handleMouseDown) + * [_handleMouseEnter()](#._handleMouseEnter) + * [_handleMouseLeave()](#._handleMouseLeave) + * [_handleMouseMove()](#._handleMouseMove) + * [_handleMouseScroll()](#._handleMouseScroll) + * [_handleMouseUp()](#._handleMouseUp) + * [_postProcessChanges()](#._postProcessChanges) + * [_processChanges()](#._processChanges) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../lwtk/Object.md#inheritance)** / [Actionable](../lwtk/Actionable.md#inheritance) / [Node](../lwtk/Node.md#inheritance) / [Drawable](../lwtk/Drawable.md#inheritance) / [Styleable](../lwtk/Styleable.md#inheritance) / [KeyHandler](../lwtk/KeyHandler.md#inheritance) / [MouseDispatcher](../lwtk/MouseDispatcher.md#inheritance) / _**`Window`**_ + +## Constructor + * **`Window(app, initParams)`** + + * Overrides: [MouseDispatcher()](../lwtk/MouseDispatcher.md#constructor) + * Overrides: [KeyHandler()](../lwtk/KeyHandler.md#constructor) + * Overrides: [Styleable()](../lwtk/Styleable.md#constructor) + * Overrides: [Actionable()](../lwtk/Actionable.md#constructor) + + + +## Methods + * **`Window:addChild(child)`** + + * Implements: [Drawable:addChild()](../lwtk/Drawable.md#.addChild) + + + * **`Window:byId(id)`** + + + * **`Window:childById(id)`** + + * Implementation: [Group:childById()](../lwtk/Group.md#childById) + + * **`Window:close()`** + + + * **`Window:getCurrentTime()`** + + + * **`Window:getFontInfo(family, slant, weight, size)`** + + + * **`Window:getLayoutContext()`** + + + * **`Window:getNativeHandle()`** + + + * **`Window:getRoot()`** + + * Implementation: [Component:getRoot()](../lwtk/Component.md#getRoot) + + * **`Window:getSize()`** + + + * **`Window:hide()`** + + + * **`Window:isClosed()`** + + + * **`Window:requestClose()`** + + + * **`Window:requestFocus()`** + + + * **`Window:setColor(color)`** + + + * **`Window:setFrame(x, y, w, h)`** + + + * **`Window:setInterceptKeyDown(interceptKeyDown)`** + + + * **`Window:setInterceptMouseDown(interceptMouseDown)`** + + + * **`Window:setMaxSize(w, h)`** + + + * **`Window:setMaxSizeFixed(flag)`** + + + * **`Window:setMinSize(w, h)`** + + + * **`Window:setOnClose(onClose)`** + + + * **`Window:setOnSizeRequest(onSizeRequest)`** + + + * **`Window:setSize(w, h)`** + + + * **`Window:setTimer(seconds, func, ...)`** + + + * **`Window:setTitle(title)`** + + + * **`Window:show()`** + + + * **`Window:triggerLayout()`** + + * Implementation: [Component:triggerLayout()](../lwtk/Component.md#triggerLayout) + + * **`Window:triggerRedraw()`** + + * Implementation: [Component:triggerRedraw()](../lwtk/Component.md#triggerRedraw) + + * **`Window:_clearChildLookup()`** + + + * **`Window:_handleConfigure(x, y, w, h)`** + + + * **`Window:_handleExpose(x, y, w, h, count)`** + + + * **`Window:_handleFocusIn()`** + + + * **`Window:_handleFocusOut()`** + + + * **`Window:_handleMap()`** + + + * **`Window:_handleMouseDown(mx, my, button, modState)`** + + + * **`Window:_handleMouseEnter(mx, my)`** + + + * **`Window:_handleMouseLeave(mx, my)`** + + + * **`Window:_handleMouseMove(mx, my)`** + + + * **`Window:_handleMouseScroll(dx, dy)`** + + + * **`Window:_handleMouseUp(mx, my, button, modState)`** + + + * **`Window:_postProcessChanges()`** + + + * **`Window:_processChanges()`** + + + +## Inherited Methods + * [MouseDispatcher](../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../lwtk/MouseDispatcher.md#._processMouseUp) + * [KeyHandler](../lwtk/KeyHandler.md): + * [resetKeyHandling()](../lwtk/KeyHandler.md#.resetKeyHandling), [_handleKeyDown()](../lwtk/KeyHandler.md#._handleKeyDown), [_handleKeyUp()](../lwtk/KeyHandler.md#._handleKeyUp) + * [Styleable](../lwtk/Styleable.md): + * [clearStyleCache()](../lwtk/Styleable.md#.clearStyleCache), [getStateString()](../lwtk/Styleable.md#.getStateString), [getStyle()](../lwtk/Styleable.md#.getStyle), [getStyleParam()](../lwtk/Styleable.md#.getStyleParam), [setState()](../lwtk/Styleable.md#.setState), [setStyle()](../lwtk/Styleable.md#.setStyle), [_getStyleParam()](../lwtk/Styleable.md#._getStyleParam), [_setStyleFromParent()](../lwtk/Styleable.md#._setStyleFromParent) + * [Drawable](../lwtk/Drawable.md): + * [getMandatoryStyleParam()](../lwtk/Drawable.md#.getMandatoryStyleParam) + * [Actionable](../lwtk/Actionable.md): + * [handleRemainingInitParams()](../lwtk/Actionable.md#.handleRemainingInitParams), [hasActionMethod()](../lwtk/Actionable.md#.hasActionMethod), [invokeActionMethod()](../lwtk/Actionable.md#.invokeActionMethod), [setInitParams()](../lwtk/Actionable.md#.setInitParams) + * **[Object](../lwtk/Object.md)**: + * [getClass()](../lwtk/Object.md#.getClass), [getClassPath()](../lwtk/Object.md#.getClassPath), [getMember()](../lwtk/Object.md#.getMember), [getReverseClassPath()](../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../lwtk/Object.md#.isInstanceOf), [setAttributes()](../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/_VERSION.md b/doc/gen/lwtk/_VERSION.md new file mode 100644 index 0000000..5b7f4f6 --- /dev/null +++ b/doc/gen/lwtk/_VERSION.md @@ -0,0 +1,3 @@ +# lwtk._VERSION + + diff --git a/doc/gen/lwtk/btest.md b/doc/gen/lwtk/btest.md new file mode 100644 index 0000000..6f5feb6 --- /dev/null +++ b/doc/gen/lwtk/btest.md @@ -0,0 +1,6 @@ +# Function lwtk.btest + + * **`btest(...)`** + + + Returns *true* if bitwise AND of its operands is different from zero. diff --git a/doc/gen/lwtk/call.md b/doc/gen/lwtk/call.md new file mode 100644 index 0000000..6c0cea2 --- /dev/null +++ b/doc/gen/lwtk/call.md @@ -0,0 +1,5 @@ +# Function lwtk.call + + * **`call(methodName, obj, ...)`** + + diff --git a/doc/gen/lwtk/errorf.md b/doc/gen/lwtk/errorf.md new file mode 100644 index 0000000..ad6d6a0 --- /dev/null +++ b/doc/gen/lwtk/errorf.md @@ -0,0 +1,5 @@ +# Function lwtk.errorf + + * **`errorf(formatString, ...)`** + + diff --git a/doc/gen/lwtk/extract.md b/doc/gen/lwtk/extract.md new file mode 100644 index 0000000..3de8aff --- /dev/null +++ b/doc/gen/lwtk/extract.md @@ -0,0 +1,5 @@ +# Function lwtk.extract + + * **`extract(table, key)`** + + diff --git a/doc/gen/lwtk/get.md b/doc/gen/lwtk/get.md new file mode 100644 index 0000000..1a27524 --- /dev/null +++ b/doc/gen/lwtk/get.md @@ -0,0 +1,3 @@ +# Table lwtk.get + + diff --git a/doc/gen/lwtk/getSuperClass.md b/doc/gen/lwtk/getSuperClass.md new file mode 100644 index 0000000..fa0f5c4 --- /dev/null +++ b/doc/gen/lwtk/getSuperClass.md @@ -0,0 +1,5 @@ +# Function lwtk.getSuperClass + + * **`getSuperClass(class)`** + + diff --git a/doc/gen/lwtk/init.md b/doc/gen/lwtk/init.md new file mode 100644 index 0000000..d5ba6cf --- /dev/null +++ b/doc/gen/lwtk/init.md @@ -0,0 +1,4 @@ +# Table lwtk + +Root module for all other *lwtk* modules. + diff --git a/doc/gen/lwtk/isInstanceOf.md b/doc/gen/lwtk/isInstanceOf.md new file mode 100644 index 0000000..2cc6436 --- /dev/null +++ b/doc/gen/lwtk/isInstanceOf.md @@ -0,0 +1,11 @@ +# Function lwtk.isInstanceOf + + * **`isInstanceOf(self, C)`** + + Determines if object is instance of the given class. + + Returns *true*, if *self* is an object that was created by invoking class *C* + or by invoking a subclass of *C*. + + Returns also *true* if *C* is a metatable of *self* or somewhere in the + metatable chain of *self*. diff --git a/doc/gen/lwtk/layout.md b/doc/gen/lwtk/layout.md new file mode 100644 index 0000000..8631596 --- /dev/null +++ b/doc/gen/lwtk/layout.md @@ -0,0 +1,3 @@ +# Table lwtk.layout + + diff --git a/doc/gen/lwtk/love/Application.md b/doc/gen/lwtk/love/Application.md new file mode 100644 index 0000000..97fdbeb --- /dev/null +++ b/doc/gen/lwtk/love/Application.md @@ -0,0 +1,80 @@ +# Class lwtk.love.Application + +Application implementation for the [LÖVE](https://love2d.org/) 2D game engine. + +Use [lwtk.Application](../../lwtk/Application.md) for runing standalone desktop applications. + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [draw()](#.draw) + * [focus()](#.focus) + * [keypressed()](#.keypressed) + * [keyreleased()](#.keyreleased) + * [mousefocus()](#.mousefocus) + * [mousemoved()](#.mousemoved) + * [mousepressed()](#.mousepressed) + * [mousereleased()](#.mousereleased) + * [setFocusWindow()](#.setFocusWindow) + * [textinput()](#.textinput) + * [update()](#.update) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / **[Application](../../lwtk/Application.md#inheritance)** / [Node](../../lwtk/Node.md#inheritance) / [MouseDispatcher](../../lwtk/MouseDispatcher.md#inheritance) / _**`love.Application`**_ + +## Constructor + * **`love.Application(initParams)`** + + * Overrides: [MouseDispatcher()](../../lwtk/MouseDispatcher.md#constructor) + * Overrides: **[Application()](../../lwtk/Application.md#constructor)** + + + +## Methods + * **`love.Application:draw()`** + + + * **`love.Application:focus(focus)`** + + + * **`love.Application:keypressed(key)`** + + + * **`love.Application:keyreleased(key)`** + + + * **`love.Application:mousefocus(focus)`** + + + * **`love.Application:mousemoved(x, y)`** + + + * **`love.Application:mousepressed(x, y, button)`** + + + * **`love.Application:mousereleased(x, y, button)`** + + + * **`love.Application:setFocusWindow(window)`** + + + * **`love.Application:textinput(text)`** + + + * **`love.Application:update()`** + + * Overrides: [Application:update()](../../lwtk/Application.md#.update) + + + +## Inherited Methods + * [MouseDispatcher](../../lwtk/MouseDispatcher.md): + * [_processMouseDown()](../../lwtk/MouseDispatcher.md#._processMouseDown), [_processMouseEnter()](../../lwtk/MouseDispatcher.md#._processMouseEnter), [_processMouseLeave()](../../lwtk/MouseDispatcher.md#._processMouseLeave), [_processMouseMove()](../../lwtk/MouseDispatcher.md#._processMouseMove), [_processMouseScroll()](../../lwtk/MouseDispatcher.md#._processMouseScroll), [_processMouseUp()](../../lwtk/MouseDispatcher.md#._processMouseUp) + * **[Application](../../lwtk/Application.md)**: + * [addStyle()](../../lwtk/Application.md#.addStyle), [close()](../../lwtk/Application.md#.close), [deferChanges()](../../lwtk/Application.md#.deferChanges), [getCurrentTime()](../../lwtk/Application.md#.getCurrentTime), [getFontInfo()](../../lwtk/Application.md#.getFontInfo), [getLayoutContext()](../../lwtk/Application.md#.getLayoutContext), [getScreenScale()](../../lwtk/Application.md#.getScreenScale), [hasWindows()](../../lwtk/Application.md#.hasWindows), [newWindow()](../../lwtk/Application.md#.newWindow), [runEventLoop()](../../lwtk/Application.md#.runEventLoop), [setErrorFunc()](../../lwtk/Application.md#.setErrorFunc), [setExtensions()](../../lwtk/Application.md#.setExtensions), [setStyle()](../../lwtk/Application.md#.setStyle), [setTimer()](../../lwtk/Application.md#.setTimer), [_addWindow()](../../lwtk/Application.md#._addWindow), [_processAllChanges()](../../lwtk/Application.md#._processAllChanges), [_removeWindow()](../../lwtk/Application.md#._removeWindow) + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/love/DrawContext.md b/doc/gen/lwtk/love/DrawContext.md new file mode 100644 index 0000000..93ad923 --- /dev/null +++ b/doc/gen/lwtk/love/DrawContext.md @@ -0,0 +1,82 @@ +# Class lwtk.love.DrawContext + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [beginOpacity()](#.beginOpacity) + * [drawBorder()](#.drawBorder) + * [drawLine()](#.drawLine) + * [drawText()](#.drawText) + * [endOpacity()](#.endOpacity) + * [fillRect()](#.fillRect) + * [intersectClip()](#.intersectClip) + * [restore()](#.restore) + * [save()](#.save) + * [setColor()](#.setColor) + * [setLineWidth()](#.setLineWidth) + * [translate()](#.translate) + * [_reset()](#._reset) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / **[love.LayoutContext](../../lwtk/love/LayoutContext.md#inheritance)** / _**`love.DrawContext`**_ + +## Constructor + * **`love.DrawContext(...)`** + + * Overrides: **[love.LayoutContext()](../../lwtk/love/LayoutContext.md#constructor)** + + + +## Methods + * **`love.DrawContext:beginOpacity(opacity)`** + + + * **`love.DrawContext:drawBorder(color, borderThickness, x, y, w, h)`** + + + * **`love.DrawContext:drawLine(x1, y1, x2, y2, ...)`** + + + * **`love.DrawContext:drawText(x, y, text)`** + + + * **`love.DrawContext:endOpacity()`** + + + * **`love.DrawContext:fillRect(color, x, y, w, h)`** + + + * **`love.DrawContext:intersectClip(x, y, w, h)`** + + + * **`love.DrawContext:restore()`** + + + * **`love.DrawContext:save()`** + + + * **`love.DrawContext:setColor(r, g, b, a)`** + + + * **`love.DrawContext:setLineWidth(w)`** + + + * **`love.DrawContext:translate(x, y)`** + + + * **`love.DrawContext:_reset()`** + + * Overrides: [love.LayoutContext:_reset()](../../lwtk/love/LayoutContext.md#._reset) + + + +## Inherited Methods + * **[love.LayoutContext](../../lwtk/love/LayoutContext.md)**: + * [getFontHeightMeasures()](../../lwtk/love/LayoutContext.md#.getFontHeightMeasures), [getTextMeasures()](../../lwtk/love/LayoutContext.md#.getTextMeasures), [getTextWidth()](../../lwtk/love/LayoutContext.md#.getTextWidth), [selectFont()](../../lwtk/love/LayoutContext.md#.selectFont) + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/love/Driver.md b/doc/gen/lwtk/love/Driver.md new file mode 100644 index 0000000..f279d6e --- /dev/null +++ b/doc/gen/lwtk/love/Driver.md @@ -0,0 +1,68 @@ +# Class lwtk.love.Driver + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [close()](#.close) + * [getDrawContext()](#.getDrawContext) + * [getLayoutContext()](#.getLayoutContext) + * [getScreenScale()](#.getScreenScale) + * [getTime()](#.getTime) + * [grabFocus()](#.grabFocus) + * [newView()](#.newView) + * [setErrorFunc()](#.setErrorFunc) + * [setMinSize()](#.setMinSize) + * [setNextProcessTime()](#.setNextProcessTime) + * [setProcessFunc()](#.setProcessFunc) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / _**`love.Driver`**_ + +## Constructor + * **`love.Driver(initParams)`** + + + +## Methods + * **`love.Driver:close()`** + + + * **`love.Driver:getDrawContext()`** + + + * **`love.Driver:getLayoutContext()`** + + + * **`love.Driver:getScreenScale()`** + + + * **`love.Driver:getTime()`** + + + * **`love.Driver:grabFocus(window)`** + + + * **`love.Driver:newView(window, initParams)`** + + + * **`love.Driver:setErrorFunc(...)`** + + + * **`love.Driver:setMinSize(window, minW, minH)`** + + + * **`love.Driver:setNextProcessTime(t)`** + + + * **`love.Driver:setProcessFunc(f)`** + + + +## Inherited Methods + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/love/LayoutContext.md b/doc/gen/lwtk/love/LayoutContext.md new file mode 100644 index 0000000..ca4961e --- /dev/null +++ b/doc/gen/lwtk/love/LayoutContext.md @@ -0,0 +1,49 @@ +# Class lwtk.love.LayoutContext + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getFontHeightMeasures()](#.getFontHeightMeasures) + * [getTextMeasures()](#.getTextMeasures) + * [getTextWidth()](#.getTextWidth) + * [selectFont()](#.selectFont) + * [_reset()](#._reset) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / _**`love.LayoutContext`**_ + +## Constructor + * **`love.LayoutContext()`** + + + +## Methods + * **`love.LayoutContext:getFontHeightMeasures()`** + + + * **`love.LayoutContext:getTextMeasures(text)`** + + + * **`love.LayoutContext:getTextWidth(text)`** + + + * **`love.LayoutContext:selectFont(family, slant, weight, size)`** + + + * **`love.LayoutContext:_reset()`** + + + +## Inherited Methods + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../../lwtk/Object.md#subclasses)** / _**`love.LayoutContext`**_ / **[love.DrawContext](../../lwtk/love/DrawContext.md#inheritance)** + diff --git a/doc/gen/lwtk/love/View.md b/doc/gen/lwtk/love/View.md new file mode 100644 index 0000000..910a817 --- /dev/null +++ b/doc/gen/lwtk/love/View.md @@ -0,0 +1,56 @@ +# Class lwtk.love.View + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [close()](#.close) + * [isClosed()](#.isClosed) + * [postRedisplay()](#.postRedisplay) + * [setFrame()](#.setFrame) + * [setMaxSize()](#.setMaxSize) + * [setMinSize()](#.setMinSize) + * [setSize()](#.setSize) + * [show()](#.show) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / _**`love.View`**_ + +## Constructor + * **`love.View(window, initParams)`** + + + +## Methods + * **`love.View:close()`** + + + * **`love.View:isClosed()`** + + + * **`love.View:postRedisplay(x, y, w, h)`** + + + * **`love.View:setFrame(x, y, w, h)`** + + + * **`love.View:setMaxSize()`** + + + * **`love.View:setMinSize()`** + + + * **`love.View:setSize(w, h)`** + + + * **`love.View:show()`** + + + +## Inherited Methods + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/love/init.md b/doc/gen/lwtk/love/init.md new file mode 100644 index 0000000..8006028 --- /dev/null +++ b/doc/gen/lwtk/love/init.md @@ -0,0 +1,4 @@ +# Table lwtk.love + +Modules for using *lwtk* with the [LÖVE](https://love2d.org/) 2D game engine. + diff --git a/doc/gen/lwtk/love/keyNameMap.md b/doc/gen/lwtk/love/keyNameMap.md new file mode 100644 index 0000000..e96d994 --- /dev/null +++ b/doc/gen/lwtk/love/keyNameMap.md @@ -0,0 +1,3 @@ +# Table lwtk.love.keyNameMap + + diff --git a/doc/gen/lwtk/lpugl/CairoDrawContext.md b/doc/gen/lwtk/lpugl/CairoDrawContext.md new file mode 100644 index 0000000..daa28b0 --- /dev/null +++ b/doc/gen/lwtk/lpugl/CairoDrawContext.md @@ -0,0 +1,80 @@ +# Class lwtk.lpugl.CairoDrawContext + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [beginOpacity()](#.beginOpacity) + * [drawBorder()](#.drawBorder) + * [drawLine()](#.drawLine) + * [drawText()](#.drawText) + * [endOpacity()](#.endOpacity) + * [fillRect()](#.fillRect) + * [intersectClip()](#.intersectClip) + * [restore()](#.restore) + * [save()](#.save) + * [setColor()](#.setColor) + * [setLineWidth()](#.setLineWidth) + * [translate()](#.translate) + * [_setCairoContext()](#._setCairoContext) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / **[lpugl.CairoLayoutContext](../../lwtk/lpugl/CairoLayoutContext.md#inheritance)** / _**`lpugl.CairoDrawContext`**_ + +## Constructor + * **`lpugl.CairoDrawContext(...)`** + + * Overrides: **[lpugl.CairoLayoutContext()](../../lwtk/lpugl/CairoLayoutContext.md#constructor)** + + + +## Methods + * **`lpugl.CairoDrawContext:beginOpacity(opacity)`** + + + * **`lpugl.CairoDrawContext:drawBorder(color, borderThickness, x, y, w, h)`** + + + * **`lpugl.CairoDrawContext:drawLine(x1, y1, x2, y2, ...)`** + + + * **`lpugl.CairoDrawContext:drawText(x, y, text)`** + + + * **`lpugl.CairoDrawContext:endOpacity()`** + + + * **`lpugl.CairoDrawContext:fillRect(color, x, y, w, h)`** + + + * **`lpugl.CairoDrawContext:intersectClip(x, y, w, h)`** + + + * **`lpugl.CairoDrawContext:restore()`** + + + * **`lpugl.CairoDrawContext:save()`** + + + * **`lpugl.CairoDrawContext:setColor(r, g, b, a)`** + + + * **`lpugl.CairoDrawContext:setLineWidth(w)`** + + + * **`lpugl.CairoDrawContext:translate(x, y)`** + + + * **`lpugl.CairoDrawContext:_setCairoContext(cairoCtx)`** + + + +## Inherited Methods + * **[lpugl.CairoLayoutContext](../../lwtk/lpugl/CairoLayoutContext.md)**: + * [getFontHeightMeasures()](../../lwtk/lpugl/CairoLayoutContext.md#.getFontHeightMeasures), [getTextMeasures()](../../lwtk/lpugl/CairoLayoutContext.md#.getTextMeasures), [getTextWidth()](../../lwtk/lpugl/CairoLayoutContext.md#.getTextWidth), [selectFont()](../../lwtk/lpugl/CairoLayoutContext.md#.selectFont) + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/lpugl/CairoLayoutContext.md b/doc/gen/lwtk/lpugl/CairoLayoutContext.md new file mode 100644 index 0000000..a2da7c9 --- /dev/null +++ b/doc/gen/lwtk/lpugl/CairoLayoutContext.md @@ -0,0 +1,45 @@ +# Class lwtk.lpugl.CairoLayoutContext + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [getFontHeightMeasures()](#.getFontHeightMeasures) + * [getTextMeasures()](#.getTextMeasures) + * [getTextWidth()](#.getTextWidth) + * [selectFont()](#.selectFont) + * [Inherited Methods](#inherited-methods) + * [Subclasses](#subclasses) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / _**`lpugl.CairoLayoutContext`**_ + +## Constructor + * **`lpugl.CairoLayoutContext(cairoCtx, platform)`** + + + +## Methods + * **`lpugl.CairoLayoutContext:getFontHeightMeasures()`** + + + * **`lpugl.CairoLayoutContext:getTextMeasures(text)`** + + + * **`lpugl.CairoLayoutContext:getTextWidth(text)`** + + + * **`lpugl.CairoLayoutContext:selectFont(family, slant, weight, size)`** + + + +## Inherited Methods + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) + +## Subclasses + * / **[Object](../../lwtk/Object.md#subclasses)** / _**`lpugl.CairoLayoutContext`**_ / **[lpugl.CairoDrawContext](../../lwtk/lpugl/CairoDrawContext.md#inheritance)** + diff --git a/doc/gen/lwtk/lpugl/Driver.md b/doc/gen/lwtk/lpugl/Driver.md new file mode 100644 index 0000000..0e2bc22 --- /dev/null +++ b/doc/gen/lwtk/lpugl/Driver.md @@ -0,0 +1,72 @@ +# Class lwtk.lpugl.Driver + + +## Contents + + * [Inheritance](#inheritance) + * [Constructor](#constructor) + * [Methods](#methods) + * [close()](#.close) + * [getDrawContext()](#.getDrawContext) + * [getLayoutContext()](#.getLayoutContext) + * [getScreenScale()](#.getScreenScale) + * [getTime()](#.getTime) + * [grabFocus()](#.grabFocus) + * [handleNextEvents()](#.handleNextEvents) + * [hasViews()](#.hasViews) + * [newView()](#.newView) + * [setErrorFunc()](#.setErrorFunc) + * [setNextProcessTime()](#.setNextProcessTime) + * [setProcessFunc()](#.setProcessFunc) + * [Inherited Methods](#inherited-methods) + + +## Inheritance + * / **[Object](../../lwtk/Object.md#inheritance)** / _**`lpugl.Driver`**_ + +## Constructor + * **`lpugl.Driver(initParams)`** + + + +## Methods + * **`lpugl.Driver:close()`** + + + * **`lpugl.Driver:getDrawContext(view)`** + + + * **`lpugl.Driver:getLayoutContext()`** + + + * **`lpugl.Driver:getScreenScale()`** + + + * **`lpugl.Driver:getTime()`** + + + * **`lpugl.Driver:grabFocus(window)`** + + + * **`lpugl.Driver:handleNextEvents(timeout)`** + + + * **`lpugl.Driver:hasViews()`** + + + * **`lpugl.Driver:newView(window, initParams)`** + + + * **`lpugl.Driver:setErrorFunc(...)`** + + + * **`lpugl.Driver:setNextProcessTime(t)`** + + + * **`lpugl.Driver:setProcessFunc(f)`** + + + +## Inherited Methods + * **[Object](../../lwtk/Object.md)**: + * [getClass()](../../lwtk/Object.md#.getClass), [getClassPath()](../../lwtk/Object.md#.getClassPath), [getMember()](../../lwtk/Object.md#.getMember), [getReverseClassPath()](../../lwtk/Object.md#.getReverseClassPath), [getSuperClass()](../../lwtk/Object.md#.getSuperClass), [isInstanceOf()](../../lwtk/Object.md#.isInstanceOf), [setAttributes()](../../lwtk/Object.md#.setAttributes) diff --git a/doc/gen/lwtk/lpugl/init.md b/doc/gen/lwtk/lpugl/init.md new file mode 100644 index 0000000..6d628d7 --- /dev/null +++ b/doc/gen/lwtk/lpugl/init.md @@ -0,0 +1,5 @@ +# Table lwtk.lpugl + +Modules for using *lwtk* on top of [LPugl](https://github.com/osch/lua-lpugl#lpugl), +a minimal Lua-API for building GUIs for Linux, Windows or macOS. + diff --git a/doc/gen/lwtk/newClass.md b/doc/gen/lwtk/newClass.md new file mode 100644 index 0000000..929cd80 --- /dev/null +++ b/doc/gen/lwtk/newClass.md @@ -0,0 +1,15 @@ +# Function lwtk.newClass + + * **`newClass(className, superClass, ...)`** + + Creates new class object. A class object has [lwtk.Class](../lwtk/Class.md) as metatable + and [lwtk.type](../lwtk/type.md)() evaluates to `"lwtk.Class"`. + + * *className* - string value + * *superClass* - optional class object, if not given, [lwtk.Object](../lwtk/Object.md) + is taken as superclass. + * *...* - optional further arguments that are reached over + to [lwtk.Object.newSubClass()](../lwtk/Object.md#.newSubClass). + + See [lwtk.Class Usage](../../Class.md) for detailed documentation + and usage examples. diff --git a/doc/gen/lwtk/newMeta.md b/doc/gen/lwtk/newMeta.md new file mode 100644 index 0000000..f13f24c --- /dev/null +++ b/doc/gen/lwtk/newMeta.md @@ -0,0 +1,9 @@ +# Function lwtk.newMeta + + * **`newMeta(name)`** + + Creates new meta object. A meta object has [lwtk.Meta](../lwtk/Meta.md) as metatable + and [lwtk.type](../lwtk/type.md)() evaluates to `"lwtk.Meta"`. + + See [lwtk.Meta Usage](../../Meta.md) for detailed documentation + and usage examples. diff --git a/doc/gen/lwtk/newMixin.md b/doc/gen/lwtk/newMixin.md new file mode 100644 index 0000000..d7026aa --- /dev/null +++ b/doc/gen/lwtk/newMixin.md @@ -0,0 +1,9 @@ +# Function lwtk.newMixin + + * **`newMixin(name, ...)`** + + Creates new mixin object. A mixin object has [lwtk.Mixin](../lwtk/Mixin.md) as metatable + and [lwtk.type](../lwtk/type.md)() evaluates to `"lwtk.Mixin"`. + + See [lwtk.Mixin Usage](../../Mixin.md) for detailed documentation + and usage examples. diff --git a/doc/gen/lwtk/tryrequire.md b/doc/gen/lwtk/tryrequire.md new file mode 100644 index 0000000..1a86021 --- /dev/null +++ b/doc/gen/lwtk/tryrequire.md @@ -0,0 +1,5 @@ +# Function lwtk.tryrequire + + * **`tryrequire(name)`** + + diff --git a/doc/gen/lwtk/type.md b/doc/gen/lwtk/type.md new file mode 100644 index 0000000..0cfbefc --- /dev/null +++ b/doc/gen/lwtk/type.md @@ -0,0 +1,15 @@ +# Function lwtk.type + + * **`type(arg)`** + + Returns the type name. + + * If *arg* is of type *"table"* or *"userdata"* and has a metatable of + type *"table"* with a field *"__name"*, than the value of this field + is returned. + + * If *arg* is of type *"table"* or *"userdata"* and has a metatable of + type *"string"*, than this string value is returned. + + * In all other cases this functions returns the same value, as the + builtin Lua function *type()* would return. diff --git a/doc/gen/lwtk/undef.md b/doc/gen/lwtk/undef.md new file mode 100644 index 0000000..9835312 --- /dev/null +++ b/doc/gen/lwtk/undef.md @@ -0,0 +1,5 @@ +# Function lwtk.undef + + * **`undef(class)`** + + diff --git a/doc/gen/lwtk/utf8.md b/doc/gen/lwtk/utf8.md new file mode 100644 index 0000000..d4a273e --- /dev/null +++ b/doc/gen/lwtk/utf8.md @@ -0,0 +1,3 @@ +# Table lwtk.utf8 + + diff --git a/doc/gen/modules.md b/doc/gen/modules.md new file mode 100644 index 0000000..7264163 --- /dev/null +++ b/doc/gen/modules.md @@ -0,0 +1,103 @@ +# Module Index + + * [lwtk](#lwtk) - Root module for all other *lwtk* modules. + * [lwtk.love](#lwtklove) - Modules for using *lwtk* with the [LÖVE](https://love2d.org/) 2D game engine. + * [lwtk.lpugl](#lwtklpugl) - Modules for using *lwtk* on top of [LPugl](https://github.com/osch/lua-lpugl#lpugl), a minimal Lua-API for building GUIs for Linux, Windows or macOS. + +## lwtk + +### Classes + * **[lwtk.Animations](lwtk/Animations.md)** + * **[lwtk.Application](lwtk/Application.md)** - Default application implementation. + * **[lwtk.Area](lwtk/Area.md)** - A list of rectangle coordinates forming an area. + * **[lwtk.Box](lwtk/Box.md)** + * **[lwtk.Button](lwtk/Button.md)** + * **[lwtk.Color](lwtk/Color.md)** - RGBA Color value. + * **[lwtk.Column](lwtk/Column.md)** + * **[lwtk.Component](lwtk/Component.md)** + * **[lwtk.DefaultStyle](lwtk/DefaultStyle.md)** + * **[lwtk.FocusGroup](lwtk/FocusGroup.md)** + * **[lwtk.FocusHandler](lwtk/FocusHandler.md)** + * **[lwtk.FontInfo](lwtk/FontInfo.md)** + * **[lwtk.FontInfos](lwtk/FontInfos.md)** + * **[lwtk.Group](lwtk/Group.md)** + * **[lwtk.InnerCompound](lwtk/InnerCompound.md)** + * **[lwtk.Matrix](lwtk/Matrix.md)** + * **[lwtk.Object](lwtk/Object.md)** - Superclass for all classes created by [lwtk.newClass](lwtk/newClass.md)(). + * **[lwtk.PushButton](lwtk/PushButton.md)** + * **[lwtk.Rect](lwtk/Rect.md)** + * **[lwtk.Row](lwtk/Row.md)** + * **[lwtk.Space](lwtk/Space.md)** + * **[lwtk.Square](lwtk/Square.md)** + * **[lwtk.Style](lwtk/Style.md)** + * **[lwtk.TextCursor](lwtk/TextCursor.md)** + * **[lwtk.TextFragment](lwtk/TextFragment.md)** + * **[lwtk.TextInput](lwtk/TextInput.md)** + * **[lwtk.TextLabel](lwtk/TextLabel.md)** + * **[lwtk.Timer](lwtk/Timer.md)** + * **[lwtk.TitleText](lwtk/TitleText.md)** + * **[lwtk.ViewSwitcher](lwtk/ViewSwitcher.md)** + * **[lwtk.Widget](lwtk/Widget.md)** + * **[lwtk.Window](lwtk/Window.md)** +### Mixins + * [lwtk.Actionable](lwtk/Actionable.md) + * [lwtk.Animatable](lwtk/Animatable.md) + * [lwtk.Colored](lwtk/Colored.md) + * [lwtk.Compound](lwtk/Compound.md) + * [lwtk.Control](lwtk/Control.md) + * [lwtk.Drawable](lwtk/Drawable.md) + * [lwtk.Focusable](lwtk/Focusable.md) + * [lwtk.HotkeyListener](lwtk/HotkeyListener.md) + * [lwtk.KeyHandler](lwtk/KeyHandler.md) + * [lwtk.LayoutFrame](lwtk/LayoutFrame.md) + * [lwtk.MouseDispatcher](lwtk/MouseDispatcher.md) + * [lwtk.Node](lwtk/Node.md) + * [lwtk.Styleable](lwtk/Styleable.md) +### Metas + * [lwtk.Callback](lwtk/Callback.md) - Holds a function with arguments that can be called. + * [lwtk.ChildLookup](lwtk/ChildLookup.md) + * [lwtk.KeyBinding](lwtk/KeyBinding.md) + * [lwtk.WeakKeysTable](lwtk/WeakKeysTable.md) +### Functions + * [lwtk.BuiltinStyleTypes](lwtk/BuiltinStyleTypes.md) + * [lwtk.DefaultKeyBinding](lwtk/DefaultKeyBinding.md) - Returns new [lwtk.KeyBinding](lwtk/KeyBinding.md) object with default settings. + * [lwtk.btest](lwtk/btest.md) - Returns *true* if bitwise AND of its operands is different from zero. + * [lwtk.call](lwtk/call.md) + * [lwtk.errorf](lwtk/errorf.md) + * [lwtk.extract](lwtk/extract.md) + * [lwtk.getSuperClass](lwtk/getSuperClass.md) + * [lwtk.isInstanceOf](lwtk/isInstanceOf.md) - Determines if object is instance of the given class. + * [lwtk.newClass](lwtk/newClass.md) - Creates new class object. + * [lwtk.newMeta](lwtk/newMeta.md) - Creates new meta object. + * [lwtk.newMixin](lwtk/newMixin.md) - Creates new mixin object. + * [lwtk.tryrequire](lwtk/tryrequire.md) + * [lwtk.type](lwtk/type.md) - Returns the type name. + * [lwtk.undef](lwtk/undef.md) +### Other + * [lwtk.Class](lwtk/Class.md) - Metatable for objects created by [lwtk.newClass](lwtk/newClass.md)(). + * [lwtk.Meta](lwtk/Meta.md) - Metatable for objects created by [lwtk.newMeta](lwtk/newMeta.md)(). + * [lwtk.Mixin](lwtk/Mixin.md) - Metatable for objects created by [lwtk.newMixin](lwtk/newMixin.md)(). + * [lwtk.StyleRef](lwtk/StyleRef.md) + * [lwtk.StyleTypeAttributes](lwtk/StyleTypeAttributes.md) + * [lwtk._VERSION](lwtk/_VERSION.md) + * [lwtk.get](lwtk/get.md) + * [lwtk.layout](lwtk/layout.md) + * [lwtk.utf8](lwtk/utf8.md) + +## lwtk.love + +### Classes + * **[lwtk.love.Application](lwtk/love/Application.md)** - Application implementation for the [LÖVE](https://love2d.org/) 2D game engine. + * **[lwtk.love.DrawContext](lwtk/love/DrawContext.md)** + * **[lwtk.love.Driver](lwtk/love/Driver.md)** + * **[lwtk.love.LayoutContext](lwtk/love/LayoutContext.md)** + * **[lwtk.love.View](lwtk/love/View.md)** +### Other + * [lwtk.love.keyNameMap](lwtk/love/keyNameMap.md) + +## lwtk.lpugl + +### Classes + * **[lwtk.lpugl.CairoDrawContext](lwtk/lpugl/CairoDrawContext.md)** + * **[lwtk.lpugl.CairoLayoutContext](lwtk/lpugl/CairoLayoutContext.md)** + * **[lwtk.lpugl.Driver](lwtk/lpugl/Driver.md)** diff --git a/example/example01.lua b/example/example01.lua index eabf67d..f3d73a8 100644 --- a/example/example01.lua +++ b/example/example01.lua @@ -18,12 +18,24 @@ local win = app:newWindow { title = "example01", Column { id = "c1", + onInputChanged = function(widget, input) + widget:byId("b1"):setDisabled(input.text == "") + end, + TitleText { text = "What's your name?" }, + TextInput { id = "i1", focus = true, style = { Columns = 40 } }, + Row { Space {}, PushButton { id = "b1", text = "&OK", disabled = true, - default = true }, + default = true, + onClicked = function(widget) + local name = widget:byId("i1").text + widget:byId("t2"):setText("Hello "..name.."!") + widget:byId("c1"):setVisible(false) + widget:byId("c2"):setVisible(true) + end }, PushButton { id = "b2", text = "&Quit", onClicked = quit }, Space {} @@ -37,7 +49,14 @@ local win = app:newWindow { Space {}, Row { Space {}, - PushButton { id = "b3", text = "&Again" }, + PushButton { id = "b3", text = "&Again", + onClicked = function(widget) + widget:byId("i1"):setText("") + widget:byId("i1"):setFocus() + widget:byId("t2"):setText("") + widget:byId("c2"):setVisible(false) + widget:byId("c1"):setVisible(true) + end }, PushButton { id = "b4", text = "&Quit", default = true, onClicked = quit }, @@ -46,24 +65,6 @@ local win = app:newWindow { } } -win:childById("c1"):setOnInputChanged(function(widget, input) - widget:childById("b1"):setDisabled(input.text == "") -end) - -win:childById("b1"):setOnClicked(function(widget) - win:childById("t2"):setText("Hello "..win:childById("i1").text.."!") - win:childById("c1"):setVisible(false) - win:childById("c2"):setVisible(true) -end) - -win:childById("b3"):setOnClicked(function(widget) - win:childById("i1"):setText("") - win:childById("i1"):setFocus() - win:childById("t2"):setText("") - win:childById("c1"):setVisible(true) - win:childById("c2"):setVisible(false) -end) - win:show() app:runEventLoop() diff --git a/example/example10.lua b/example/example10.lua index 71abd1f..0df5273 100644 --- a/example/example10.lua +++ b/example/example10.lua @@ -8,6 +8,8 @@ local newClass = lwtk.newClass local MyButton = newClass("MyButton", Widget) do + MyButton:declare("onClicked", "text") + function MyButton:setOnClicked(onClicked) self.onClicked = onClicked end @@ -15,22 +17,22 @@ do self.text = text self:triggerRedraw() end - function MyButton:onMouseEnter(x, y) + function MyButton.implement:onMouseEnter(x, y) self:setState("hover", true) end - function MyButton:onMouseLeave(x, y) + function MyButton.implement:onMouseLeave(x, y) self:setState("hover", false) end - function MyButton:onMouseDown(x, y, button, modState) + function MyButton.implement:onMouseDown(x, y, button, modState) self:setState("pressed", true) end - function MyButton:onMouseUp(x, y, button, modState) + function MyButton.implement:onMouseUp(x, y, button, modState) self:setState("pressed", false) if self.state.hover and self.onClicked then self:onClicked() end end - function MyButton:onDraw(ctx) + function MyButton.implement:onDraw(ctx) local w, h = self:getSize() ctx:fillRect(self:getStyleParam("BackgroundColor"), 0, 0, w, h) ctx:setColor(self:getStyleParam("TextColor"):toRGBA()) diff --git a/example/screenshot00.png b/example/screenshot00.png new file mode 100644 index 0000000000000000000000000000000000000000..db36e01421db508854feaffb2f9ff4d62a7db041 GIT binary patch literal 5986 zcmbtYbySqyw;rTn=tde8L>i>aVFnN+9bhP_55+;G28JBETLDo71f;u>Zcq>;hVJeh zO6rc^UBCbCx_{jJuJ=4=owfEl`Rw!TeIj(V)yPPgNdN!<*)w&pKDOS*78fD{EShI( zSz;?ZSI{#k5%%*T`X?OQW<)?>h!>8p5J)Q*TY!TV!dB4L#>Lk5ovWQAqA&SS0|1~u zeFlCC_4u-v=4nRr`nFf;Loj!+fA~Ev{(QRvsmLN0{T;NSX^BI{{`gg~U88wPt&-{a zMyYwDooUItqPG*cC5EOs@FG(>ic&9V5nUV!Q8**{n&SKTfnD|l&H%GnrkfUvvSClL zh1cl^@&mjJ8=rweGGWq`cvhq80Kg!d!!E&7%7>4J!tzUeIfy#Mc%XrlfPaD7l`w6W z5s@rTnfhM*WYe#CiLZ3sg8X-7+l>o(68hKTqo?xiDRkQ@`_?{}CPtGHmK>_CPAqK- z)P)-T)=Rg~S(-axgX)tk8}nOHWvIbkqmAR4=_FpZDv+DAWn1Bxbb=E-ykQWsq^^J%81rr&d;+g@uU?6pa2> zjNyy~TnUU^2}E2}xFSGC5rDK43!%5Sw_S}1_SZE^@t{taii$s;2MEZ-N3fSNpyd=Z zwGao5`jlWTeWa(gGVe5j0jCDYCA zwPaRh+~-o0Wc4(bSx01X~$bsp+T^jmj#$_TJ-5t>g}Snb)HM`Q3O#HUoEe%m;A zv9TVnPRJ1EzD#w;g_LrQ3}B#BD>z1}``c2~#5LvOqi)RCSjM~R`?)>eKv(JpG+B-T zmnSllf(mgzX5QKK{Ekgwo^1ab{qd@2&GAmwtiX2nf#R9w+3^?>3Y(!>lvP zclPin02w4t8l-TvH2n7B`c&-f<`1PBgM3KrpgUO$L5Bnrg#po&2WvZOue#H-G%h@iS4J1Q;(g0ftur>rxwqYdz8E*GNeH7`5v?<#AXJpi5fQEi$k)7OZBb zF4U3pZklaXSVy@MVteE>fLB~Q(R(4B!0f`jfVLkq4=ym(_rliCde)76k9t#}tI6XT z6C;%@sAi)8t)uTA1!bx26+(53(>bty^Ka$i|fG(p27pDoeLfiVG@{D zr`~@F6MvI~9pGrF{;Kbh-pbl-=tj*MGm$3ar=eRSf>#CB;Lg(3V{Mpd#nI}OcCx5>xsjGzkQ?zKz6uEDOY^ZHhBpO zF9?{k$DKR6wR6NA$Aey#U7<>5z=C{bbhY}OS(TrkY~Jw|8LRIBTT>6@MXn87PjvCw zjlxtdaP`=gkc2F0ceLbrw46RCZpEw%bk7{m+ewG(ien4cLw;5+N}nYt8{5_JmkW^Y z>-C0PrKo8wP0Is2+op`krKF_t(dhirTr{~c1YXXvc+@WJ0m~GHb6fkT`R)F7SF8Fm zma4nO0EZ2?laJ{xa=U5sG-dB}AhUbaiA6OY-eBG)w#|1KGqU!fIo-s$IaVj>oN~Ph z4xW0l&H=X9w?3uDKZ&=uqbFsW4~LIfd_E--0$|RoLSm!_>K;WDFK>q&%$iK!9m&56 z`KcJ0Up(JeqW(`qO)*V@IGdtC@R(j?^}zE)=2Vn#N4@E{j-^DOm5xyIP$ z%3AQ<{gs#rWbV@(tD|-pJHok2?KkfPiq;XAM4+?_w28LVdW{oMAtcet- ziqCuYkdkm~t%O#JbkX$s3AeB9k_Zr;`D2OIb!+Iy-~QR2lKR&Juq*cFn^YQQCp~{X zmYRMk_K0Gt8@`*d<%q^acjpSfwsmb#{U+pMRNqjoa(9b+WPVLITXG6HnIv+C0(!Mw!?`N^UZZiQfHZ+U@t0{C=r`qv{GRCGx8g+WYjyiO@+m2Svd zSXDW)L2332PyHA3fS^`7>-w^$A1Da##!B{)xk%d#@f(Un#@5s1r!>>k_8i+UGGG0Q zJPg}`NT-=tqcQ*L%8Q}w*i(V7anKV>ezlPfzhUPi0Q6r>00S;b8D@sAq`IY4fp(yjQzKk z0dyf`@9dR`0!0EkvutSfh(Sd0y2K#B{}JS!L1_|is99KcmliGKv{DrvD_N~ltH&0E zd3nQ>%7TIv5;bhA(q>r5=(k65G(CB5u6^#CS-v=-k?o0NADXc7xF9MziD9{nZjY(; zK7UtqY~G5R<5;L$K+V7=GWZ@oPidQ&N)gSz@0-pml%*&X%}CXAV9|gePD)C)c$5j{ zKk655W%Nmor*t&%jEEp6*eWj za0)4dkaCXL4N2?vHvEfRo;@2O9-ifLSH!ib=FQlJN9PKyo+&$Zq5m+uu0DTKy~k13 zGt(QKJnS+sTcd<~(>1u3GFjVdJNt8u*{&OdTF$9GAz(OFKJJ8|nAMh7_-8ySuv`_8z*pxE#j$UE^k}Dv(-OSoEz89%3+U{x~;B>#3y9 z*B3g!OkV2#)|HkXYgrgGJ2AS0sjKsWxu`-ZCqs8%EhpXds6Ra?MA+*M*eCYS>Bxz508!p!{P8|8u&zWVs*f{8PX9ArHFv1F}kWf#FX4$zd1fuJAriv$L zcQ5Z^^ZC3Kyhte?DqcfPPalc33S5!qdHB$J5`QI87@cc9O6ArY z%j&Td!Vn!7eQZ_%qWpjP)KcQYED2vAo<+q5hDEh z0D22DIIzSp>ckCapice|MYF?%jU@U@2LUGc6KGwgcNK8 zI!7tYx+9Ka$enRA^9F?Izf(sbB(RZ>EOI}Z?7rmThC#uYZoyc}6Z_3<2EH%y zo`E`7fBtaE{#oej>jN7b%ZQ0rVb9bZvpYotIP7Mykf@Jdw;JTs&e1n*7JS(hjQd+4 zwXUviSPUETnhm8Zcs9Ol_HusnX6vCZKc7b%cAV%sb_K8KXEPfaegSo+ttj6QyT`}J zGM}FJ%v@exI&W=ciq%eq`Ux=D&*lQ#pN3Dkt-U zd9O%|DvR2z;1!Vl4-Q5t!Rx7TFyl0@(v$ORp!tr-e48j#2 z^WVNrufdm=hG2U-3oX8vH;IXf1m>DH7pD``w~JVBEdD9(g|Q0<*P!QFZrU+5>N&Aa2*hIDXV2O=rI-C1kNNrE z>aokjil=yE&JS!26tOPp;WaK~=Xdz^>yH*7I~%Y9HjsCUpDV0rqtn#)j~I|eniAl2 zd2AcBUQ~0ES7N~Mr&cScbZA@^?&o($kd!T~{ry^$8g6Tw(@w)C&<`p?AK&ka{f6dD3_!{x(qnv4)(L!x?b@h*yzBLyhvqZSg4(W40C5f?%>^DztpfRdJ zt{W(VuTcXNWfmI_1E)HsMM5mBtR;$N54Qj8?!HYM8lOflZo_f47Lt|ulbFF_JtLDp z9PJZ+{6p}o_Sj{omGS4#pO-he5@DEOhWDrmPEoyyA%v@|N`|6u^g24DvS91u!v{=f zZoeQ<(;`y)`~%nTOgkpUHAPDm4u8aexX5#IpFfN3lLY5M2K-N2E?;GQ(*N8$M9vDo zd9Ky$(9@7SGNQk_hL+ruLu^h8+-{NY9dff;nG9IWIHueoJC|`h`t#`*DHW^yp}_*{@B1Cco(7a7cSd zxB9IQe5!Trx)%^oGs?xQ{YAvaSkuhx%hPWo8CiBDoSd8lR9u{#nS<5O^DEv05TrD4 z)p6mMO+-2RZ+_RI*^9+O1koWiKxW#$gA7@^*FBY3mVCaSO1m8;+|qS$F#A0yj-<9H zUvKF6Do-b)RvP}JQb6$rL!&rXVk(6=m~S@radvZq+}++>B0wOY=8%i^d?q{n0;sg_ zABj@4?^(!!V~~$&A*nr+f){No`~Ca&<+)RgSn5qyz1Goew57$4wNutQcsHz}p&??` z;SrSt>zt~34NR|j`z%){qn$#?i6v}nH1E@mzUM*nxzkbyzGAb7^GYhH=Qjfs1ma@X zvlU~yhl{Iai)+cZ>b8>w90!`7bVZk-L!LAp^+=%nH432C)74VChK8@kYAY+LNAq;V zJ)3eWo@HW_-M4cMbnfo%07R?5l%=wtfN>>bZ`>VT2nZ)h13yQfI0O{%B5%3;)i371 zp$S%h*BHLmNnj(H&O(Et3xtUYb0|4kN3K=|H#avfyoMP9fn03m-7SCL=&@SqA!~9_ zRtBsOrcD%M&tD_6K5k&(IiRiFs`KKz{)PY(~1n#Hd1?GEPIxw#6TOAPjQc*@JmS0E3hoLpSQ-i$JW zKnPq_H?=0gC*C-7KTEOp9CC6qi>~&6@}5lUo5T7e=^n?Yr1-zcLlhqZV9;2qK8;|x>jbjVqRzul6EdyFH638KYEZ2Tg0NIu$yAPK- z6H-#b{r&x4op;a8&27>~e-GgC#bm?D$S$Yo{t_fXok!Y3gr16uihfV=+KDb%(7P^4 zzUT!iHE|k1K+Y20)y2cZ)3tKA#EsPjko%beEgc<*E1?aWBKlsPsW=@vHJzE@-SwH; zcZdKDOH4wrG_u(kObd^ai>R(f(9$agfA~Nnub@ChO&y30Kx}p=odvi1!>PD|$vV?B zGu(WA*9|kwAP{Ir;p5bAcCo6QhI0A>Xry_gyA5{jlP$h-@87?V|M-!x07~NM=qP`+ z%Qx^vhUVtasfxC?cIri+C06E7yH6bSrJqtJJHrqIwW%$5Pd7O-se=LkZz#Vc>~)|D zTPr!gMfXw}j9K=p2IKrqdH}j$hkG)9_H*pf^s;G2HzVUhMD&sQc$@(B{}Jx3FWxFJ zvQiT%QM?9jPBA^6e;K@-1-iYc>LgffYniT#OH**Whhr|gIGJ!T(_x-P9IuQ2bFi$| za;>tiVpaI@p{WUZ%atg(%=y0cPtBFDh6USG8P^AKFlifpNk6)v4T~>h1Z*@~0m1yr zi3SE27mn=9W$Y!LT}HXe`^zME^Eyiljpy7-!VFjE`(ouvUOe=g>qB5nsW0P`{Se9H z&vqo(bmMp?sh>~qQBUwk3(*TRez%Uv4GZvf!H4VDY832UBYl^XE$18^=}ZRa&|qb3 z8WZ0UMzOfc6I4~zG%rdaEKEzMxHuZ|T00ZjHcG@|Jr|WlG!u-S(d=|%c4g(gwYAd) zR9Z$VY26v?1?FdKNr-B8`|KO4{L<2QT2c|O{+bd1nSl%pM%R?yZHp&`g&HhM?s(j) z z{1}P@=M5@eob?e)OUsT|A?*)heZx>4F^NSNnyd2V0y6|JX<|ayTxmqgw0&{0rE~S@ z#YQRfH#r2R?Gx#Q$+Tb={@<+`EOn=MaM7?^+;k4au1h^whiy#l0TGTe=r3q3JXCJQ z0aw%ihfR2x#%i#=3RMyZ9)S3N1?;nPeXV;S2hqtj#oR* "..tostring(a2), 2) @@ -62,5 +78,5 @@ for argI = 1, #args do error(err) end - scriptFunc() + scriptFunc() end diff --git a/src/lwtk/Actionable.lua b/src/lwtk/Actionable.lua index b97ed3f..9999d2c 100644 --- a/src/lwtk/Actionable.lua +++ b/src/lwtk/Actionable.lua @@ -3,14 +3,21 @@ local lwtk = require"lwtk" local match = string.match local getActions = lwtk.get.actions -local Super = lwtk.Object -local Actionable = lwtk.newClass("lwtk.Actionable", Super) +local Actionable = lwtk.newMixin("lwtk.Actionable", -function Actionable:new(initParams) - if initParams then - self:setInitParams(initParams) + function(Actionable, Super) + + function Actionable:new(initParams) + if initParams then + self:setInitParams(initParams) + end + end + + function Actionable:handleRemainingInitParams(initParams) + Super.setAttributes(self, initParams) + end end -end +) function Actionable:setInitParams(initParams) if initParams then @@ -18,7 +25,9 @@ function Actionable:setInitParams(initParams) local hasRemaining = false for k, v in pairs(initParams) do if type(k) == "string" and match(k, "^onAction") then - if not objectActions then objectActions = {} end + if not objectActions then + objectActions = {} + end objectActions[k] = v initParams[k] = nil else @@ -29,12 +38,7 @@ function Actionable:setInitParams(initParams) getActions[self] = objectActions end if hasRemaining then - local handleRemainingInitParams = self.handleRemainingInitParams - if handleRemainingInitParams then - handleRemainingInitParams(self, initParams) - else - Super.setAttributes(self, initParams) - end + self:handleRemainingInitParams(initParams) end end end @@ -49,7 +53,7 @@ function Actionable:hasActionMethod(actionMethodName) end function Actionable:invokeActionMethod(actionMethodName) - local method = self[actionMethodName] + local method = self:getMember(actionMethodName) if method then return method(self) else diff --git a/src/lwtk/Animatable.lua b/src/lwtk/Animatable.lua index 8e9e173..2651eb6 100644 --- a/src/lwtk/Animatable.lua +++ b/src/lwtk/Animatable.lua @@ -6,26 +6,27 @@ local getVisibilityChanges = lwtk.get.visibilityChanges local callOnLayout = lwtk.layout.callOnLayout -local Styleable = lwtk.Styleable -local Animatable = lwtk.newMixin("lwtk.Animatable", Styleable, Styleable.NO_STYLE_SELECTOR) - local getParamTransitions = lwtk.WeakKeysTable() local getStateTransitions = lwtk.WeakKeysTable() local getCurrentValues = lwtk.WeakKeysTable() -function Animatable.initClass(Animatable, Super) -- luacheck: ignore 431/Animatable +local Styleable = lwtk.Styleable +local Animatable = lwtk.newMixin("lwtk.Animatable", Styleable, Styleable.NO_STYLE_SELECTOR, + + function(Animatable, Super) + + Animatable:declare( + "_animationUpdated" + ) - function Animatable:new(initParams) - getParamTransitions[self] = {} - getStateTransitions[self] = {} - getCurrentValues[self] = {} - - self._animationActive = false - self._animationTriggered = false - self._animationUpdated = false - Super.new(self, initParams) + function Animatable.override:new(initParams) + getParamTransitions[self] = {} + getStateTransitions[self] = {} + getCurrentValues[self] = {} + Super.new(self, initParams) + end end -end +) local getStyleParam = Styleable.getStyleParam @@ -34,7 +35,7 @@ local function addToAnimations(self) app._animations:add(self) end -function Animatable:animateFrame(newX, newY, newW, newH, isLayoutTransition) +function Animatable.override:animateFrame(newX, newY, newW, newH, isLayoutTransition) if self.x ~= newX or self.y ~= newY or self.w ~= newW or self.h ~= newH then @@ -242,7 +243,7 @@ function Animatable:setVisible(shouldBeVisible) end end -function Animatable:setState(name, flag) +function Animatable.override:setState(name, flag) _setState(self, name, flag) end @@ -252,29 +253,29 @@ function Animatable:setStates(stateNames) end end -function Animatable:_setStyleFromParent(parentStyle) +function Animatable.override:_setStyleFromParent(parentStyle) getCurrentValues[self] = {} Styleable._setStyleFromParent(self, parentStyle) end -function Animatable:setStyle(style) +function Animatable.override:setStyle(style) getCurrentValues[self] = {} Styleable.setStyle(self, style) end local function clearCaches(self) getCurrentValues[self] = {} - for _, c in ipairs(self) do - clearCaches(c) + for i = 1, #self do + clearCaches(self[i]) end end -function Animatable:getStyle() +function Animatable.override:getStyle() clearCaches(self) return Styleable.getStyle(self) end -function Animatable:getStyleParam(paramName) +function Animatable.override:getStyleParam(paramName) local value = getCurrentValues[self][paramName] if value == nil then value = getStyleParam(self, paramName) @@ -291,15 +292,7 @@ function Animatable:getStyleParam(paramName) return value end -function Animatable:getMandatoryStyleParam(paramName) - local p = self:getStyleParam(paramName) - if not p then - lwtk.errorf("Missing StyleParam %q", paramName) - end - return p -end - -function Animatable:updateAnimation() +function Animatable.override:updateAnimation() if self._animationUpdated then return end diff --git a/src/lwtk/Animations.lua b/src/lwtk/Animations.lua index 0a8670f..0c6d04b 100644 --- a/src/lwtk/Animations.lua +++ b/src/lwtk/Animations.lua @@ -1,23 +1,28 @@ local lwtk = require("lwtk") local remove = table.remove +local rawset = rawset local UPDATE_INTERVAL = 0.015 -- seconds local processAnimations local Animations = lwtk.newClass("lwtk.Animations") +Animations:declare( + "app", + "timer" +) + function Animations:new(app) self.app = app - self.setTimer = app.setTimer self.timer = lwtk.Timer(processAnimations, self) end function Animations:add(animatable) - self[#self + 1] = animatable + rawset(self, #self + 1, animatable) local timer = self.timer if not timer.time then - self:setTimer(UPDATE_INTERVAL, timer) + self.app:setTimer(UPDATE_INTERVAL, timer) end end @@ -48,7 +53,7 @@ processAnimations = function(self) if #self > 0 then local timer = self.timer if not timer.time then - self:setTimer(UPDATE_INTERVAL, timer) + self.app:setTimer(UPDATE_INTERVAL, timer) end end end diff --git a/src/lwtk/Application.lua b/src/lwtk/Application.lua index e1d6c34..012adbd 100644 --- a/src/lwtk/Application.lua +++ b/src/lwtk/Application.lua @@ -1,9 +1,11 @@ local lwtk = require"lwtk" +local insert = table.insert +local remove = table.remove + local Timer = lwtk.Timer local Window = lwtk.Window local FontInfos = lwtk.FontInfos -local Application = lwtk.newClass("lwtk.Application") local extract = lwtk.extract local getApp = lwtk.get.app @@ -14,8 +16,38 @@ local getVisibilityChanges = lwtk.get.visibilityChanges local getDeferredChanges = lwtk.get.deferredChanges local isInstanceOf = lwtk.isInstanceOf -local isClosed = setmetatable({}, { __mode = "k" }) -local createClosures +local isClosed = lwtk.WeakKeysTable() + +--[[ + Default application implementation. + + Use this for standalone desktop applications. Use lwtk.love.Application for + running within the [LÖVE](https://love2d.org/) 2D game engine. +]] +local Application = lwtk.newClass("lwtk.Application") + +Application:declare( + "_animations", + "_eventFunc", + "_hasChanges", + "animationTimer", + "appName", + "driver", + "postprocessNeeded", + "procssingDeferedChanges", + "scale", + "timers" +) + +local function unpack2(t, i, n) + if i <= n then + return t[i], unpack2(t, i + 1, n) + end +end +local function unpack(t) + return unpack2(t, 1, t.n) +end + function Application:new(arg1, arg2) local appName @@ -31,13 +63,17 @@ function Application:new(arg1, arg2) initParams = arg1 or {} appName = extract(initParams, "name") end - self.driver = extract(initParams, "driver") - if not self.driver then + local driver = extract(initParams, "driver") + if not driver then assert(appName, "Application object needs name attribute") - self.driver = lwtk.lpugl.Driver{ appName = appName } + driver = lwtk.lpugl.Driver{ appName = appName } end + self.driver = driver isClosed[self] = false - + + local timers = {} + self.timers = timers + local style = initParams.style if style then initParams.style = nil @@ -55,7 +91,7 @@ function Application:new(arg1, arg2) end getVisibilityChanges[self] = lwtk.WeakKeysTable() - getDeferredChanges[self] = lwtk.WeakKeysTable() + getDeferredChanges[self] = {} if getApp[style] then error("Style was alread added to app") @@ -82,14 +118,83 @@ function Application:new(arg1, arg2) end end end - self.appName = appName - self.damageReports = nil + self.appName = appName + self.postprocessNeeded = {} + self._animations = lwtk.Animations(self) + local animationTimer = self._animations.timer + self.animationTimer = animationTimer + + getFontInfos[self] = FontInfos(self.driver:getLayoutContext()) - getFontInfos[self] = FontInfos(self.driver:getLayoutContext()) + self:setAttributes(initParams) - createClosures(self) + driver:setProcessFunc(function() + local now = driver:getTime() + local closed = isClosed[self] + while not closed do + local timer = timers[1] + if not timer or timer.time > now then + break + end + remove(timers, 1) + if timer == animationTimer then + self:_processAllChanges() + end + timer.time = false + timer.func(unpack(timer)) + closed = isClosed[self] + end + local timer = timers[1] + if timer then + local t = timer.time - now + t = (t >= 0) and t or 0 + if not closed then + driver:setNextProcessTime(t) + end + end + if not closed and not animationTimer.time then + self:_processAllChanges() + end + end) - self:setAttributes(initParams) + + self._eventFunc = function(window, view, event, ...) + --print(event, ...) + if event == "CONFIGURE" then + window:_handleConfigure(...) + elseif event == "EXPOSE" then + window:_handleExpose(...) + elseif event == "MOTION" then + window:_handleMouseMove(...) + elseif event == "POINTER_OUT" then + window:_handleMouseLeave(...) + elseif event == "POINTER_IN" then + window:_handleMouseEnter(...) + elseif event == "KEY_PRESS" then + window:_handleKeyDown(...) + elseif event == "KEY_RELEASE" then + window:_handleKeyUp(...) + elseif event == "BUTTON_PRESS" then + window:_handleMouseDown(...) + elseif event == "BUTTON_RELEASE" then + window:_handleMouseUp(...) + elseif event == "FOCUS_IN" then + window:_handleFocusIn(...) + elseif event == "FOCUS_OUT" then + window:_handleFocusOut(...) + elseif event == "SCROLL" then + window:_handleMouseScroll(...) + elseif event == "CLOSE" then + window:requestClose() + elseif event == "MAP" then + window:_handleMap(...) + elseif event == "CREATE" then + return + end + if not isClosed[self] and not animationTimer.time then + self:_processAllChanges() + end + end end function Application:close() @@ -162,219 +267,159 @@ function Application:hasWindows() end function Application:_addWindow(win) - self[#self + 1] = win + rawset(self, #self + 1, win) end function Application:_removeWindow(win) - for i = 1, #self do + for i = #self, 1, -1 do if self[i] == win then table.remove(self, i) end end end -local insert = table.insert -local remove = table.remove +function Application:setTimer(seconds, func, ...) + local driver = self.driver + local timers = self.timers -local function unpack2(t, i, n) - if i <= n then - return t[i], unpack2(t, i + 1, n) - end -end -local function unpack(t) - return unpack2(t, 1, t.n) -end - -createClosures = function(app) - - local driver = app.driver - local deferredChanges = getDeferredChanges[app] - local timers = {} - - function app:setTimer(seconds, func, ...) - local n = #timers - local timer - if type(func) == "table" then - timer = func - if timer.time then - for i = 1, n do - if timers[i] == timer then - remove(timers, i) - n = n - 1 - break - end + local n = #timers + local timer + if type(func) == "table" then + timer = func + if timer.time then + for i = 1, n do + if timers[i] == timer then + remove(timers, i) + n = n - 1 + break end end - else - assert(type(func) == "function", "Timer object or function expected") - timer = Timer(func, ...) end - local now = driver:getTime() - local time = now + seconds - timer.time = time - for i = 1, n do - if timers[i].time > time then - insert(timers, i, timer) - local t = timers[1].time - now - t = (t >= 0) and t or 0 - driver:setNextProcessTime(t) - return timer - end + else + assert(type(func) == "function", "Timer object or function expected") + timer = Timer(func, ...) + end + local now = driver:getTime() + local time = now + seconds + timer.time = time + for i = 1, n do + if timers[i].time > time then + insert(timers, i, timer) + local t = timers[1].time - now + t = (t >= 0) and t or 0 + driver:setNextProcessTime(t) + return timer end - timers[n + 1] = timer - local t = timers[1].time - now - t = (t >= 0) and t or 0 - driver:setNextProcessTime(t) - return timer end + timers[n + 1] = timer + local t = timers[1].time - now + t = (t >= 0) and t or 0 + driver:setNextProcessTime(t) + return timer +end - local animations = lwtk.Animations(app) - local animationTimer = animations.timer - app._animations = animations +function Application:getCurrentTime() + return self.driver:getTime() +end - function app:getCurrentTime() - return driver:getTime() - end - - local procssingDeferedChanges = false - local postprocessNeeded = {} - - function app:deferChanges(callback) - assert(not procssingDeferedChanges) - deferredChanges[#deferredChanges + 1] = callback - app._hasChanges = true - end - - local function _processAllChanges(self) - if app._hasChanges then - local visibilityChanges = getVisibilityChanges[app] - for widget, hidden in pairs(visibilityChanges) do - widget:onEffectiveVisibilityChanged(hidden) - visibilityChanges[widget] = nil - end - procssingDeferedChanges = true - for i = 1, #deferredChanges do - deferredChanges[i]:call() - deferredChanges[i] = nil - end - procssingDeferedChanges = false - app._hasChanges = false - for _, w in ipairs(app) do - if w._hasChanges then - if w:_processChanges() then - postprocessNeeded[#postprocessNeeded + 1] = w - end - assert(not w._hasChanges) - end - end - assert(not app._hasChanges) +function Application:deferChanges(callback) + assert(not self.procssingDeferedChanges) + local deferredChanges = getDeferredChanges[self] + deferredChanges[#deferredChanges + 1] = callback + self._hasChanges = true +end + +function Application:_processAllChanges() + local postprocessNeeded = self.postprocessNeeded + if self._hasChanges then + local visibilityChanges = getVisibilityChanges[self] + for widget, hidden in pairs(visibilityChanges) do + widget:onEffectiveVisibilityChanged(hidden) + visibilityChanges[widget] = nil end - for i = 1, #postprocessNeeded do - postprocessNeeded[i]:_postProcessChanges() - postprocessNeeded[i] = nil + self.procssingDeferedChanges = true + local deferredChanges = getDeferredChanges[self] + for i = 1, #deferredChanges do + deferredChanges[i]() + deferredChanges[i] = nil end - end - app._processAllChanges = _processAllChanges - - if driver.handleNextEvents then - function app:runEventLoop(timeout) - local endTime = timeout and (driver:getTime() + timeout) - if not animationTimer.time then - _processAllChanges() - end - while app:hasWindows() do - driver:handleNextEvents(endTime and driver:getTime() - endTime) - if not isClosed[app] and not animationTimer.time then - _processAllChanges() - end - if endTime and driver:getTime() >= endTime then - break + self.procssingDeferedChanges = false + self._hasChanges = false + for i = 1, #self do + local w = self[i] + if w._hasChanges then + if w:_processChanges() then + postprocessNeeded[#postprocessNeeded + 1] = w end + assert(not w._hasChanges) end end - else - function app:runEventLoop(timeout) - error("method 'runEventLoop' not supported") - end + assert(not self._hasChanges) end - + for i = 1, #postprocessNeeded do + postprocessNeeded[i]:_postProcessChanges() + postprocessNeeded[i] = nil + end +end + +--[[ + Update by processing events from the window system. + + * *timeout* - optional float, timeout in seconds + + If *timeout* is given, this function will process events from the window system until + the time period in seconds has elapsed or until all window objects have been closed. + + If *timeout* is `nil` or not given, this function will process events from the window system + until all window objects have been closed. +]] +function Application:runEventLoop(timeout) + local driver = self.driver if driver.handleNextEvents then - function app:update(timeout) - if not animationTimer.time then - _processAllChanges() - end - return driver:handleNextEvents(timeout) + local endTime = timeout and (driver:getTime() + timeout) + if not self.animationTimer.time then + self:_processAllChanges() end - end - - driver:setProcessFunc(function() - local now = driver:getTime() - local closed = isClosed[app] - while not closed do - local timer = timers[1] - if not timer or timer.time > now then - break + while self:hasWindows() do + driver:handleNextEvents(endTime and driver:getTime() - endTime) + if not isClosed[self] and not self.animationTimer.time then + self:_processAllChanges() end - remove(timers, 1) - if timer == animationTimer then - _processAllChanges() - end - timer.time = false - timer.func(unpack(timer)) - closed = isClosed[app] - end - local timer = timers[1] - if timer then - local t = timer.time - now - t = (t >= 0) and t or 0 - if not closed then - driver:setNextProcessTime(t) + if endTime and driver:getTime() >= endTime then + break end end - if not closed and not animationTimer.time then - _processAllChanges() - end - end) + else + error("method 'runEventLoop' not supported") + end +end + +--[[ + Update by processing events from the window system. + + * *timeout* - optional float, timeout in seconds + + If *timeout* is given, this function will wait for *timeout* seconds until + events from the window system become available. If *timeout* is `nil` or not + given, this function will block indefinitely until an event occurs. + + As soon as events are available, all events in the queue are processed and this function + returns `true`. - function app._eventFunc(window, view, event, ...) - --print(event, ...) - if event == "CONFIGURE" then - window:_handleConfigure(...) - elseif event == "EXPOSE" then - window:_handleExpose(...) - elseif event == "MOTION" then - window:_handleMouseMove(...) - elseif event == "POINTER_OUT" then - window:_handleMouseLeave(...) - elseif event == "POINTER_IN" then - window:_handleMouseEnter(...) - elseif event == "KEY_PRESS" then - window:_handleKeyDown(...) - elseif event == "KEY_RELEASE" then - window:_handleKeyUp(...) - elseif event == "BUTTON_PRESS" then - window:_handleMouseDown(...) - elseif event == "BUTTON_RELEASE" then - window:_handleMouseUp(...) - elseif event == "FOCUS_IN" then - window:_handleFocusIn(...) - elseif event == "FOCUS_OUT" then - window:_handleFocusOut(...) - elseif event == "SCROLL" then - window:_handleMouseScroll(...) - elseif event == "CLOSE" then - window:_handleClose() - elseif event == "MAP" then - window:_handleMap(...) - elseif event == "CREATE" then - return - end - if not isClosed[app] and not animationTimer.time then - _processAllChanges() + If *timeout* is given and there are no events available after *timeout* + seconds, this function will return `false`. +]] +function Application:update(timeout) + local driver = self.driver + if driver.handleNextEvents then + if not self.animationTimer.time then + self:_processAllChanges() end + return driver:handleNextEvents(timeout) end end + return Application diff --git a/src/lwtk/Area.lua b/src/lwtk/Area.lua index bd29dcb..a7650c1 100644 --- a/src/lwtk/Area.lua +++ b/src/lwtk/Area.lua @@ -1,16 +1,35 @@ local lwtk = require"lwtk" local Rect = lwtk.Rect + + +--[[ + A list of rectangle coordinates forming an area. +]] local Area = lwtk.newClass("lwtk.Area") local rawget = rawget local areRectsIntersected = Rect.areRectsIntersected local doesRectContain = Rect.doesRectContain +Area:declare( + "count" -- number of rectangles in the area +) + +--[[ + Creates an empty area object. +]] function Area:new() self.count = 0 end +--[[ + Obtain coordinates of the i-th rectangle from the area. + + * *i* - index of the rectangle, *1 <= i <= area.count* + + Returns *x, y, w, h* rectangle coordinates +]] function Area:getRect(i) local i0 = (i - 1) * 4 return rawget(self, i0 + 1), @@ -29,10 +48,22 @@ local function iterator(self, i) end end +--[[ + Iterate through all rectangle coordinates. + + Returns an *iterator function*, *self* and *0*, so that the construction + ```lua + for i, x, y, w, h in area:iteration() do ... end + ``` + will iterate over all rectangle indices and coordinates. +]] function Area:iteration() return iterator, self, 0 end +--[[ + Adds the rectangle coordinates to the area. +]] function Area:addRect(x, y, w, h) if w > 0 and h > 0 then for i, x2, y2, w2, h2 in iterator, self, 0 do @@ -57,6 +88,10 @@ function Area:addRect(x, y, w, h) end end +--[[ + Returns *true* if the given rectangle coordinates intersect + the area. +]] function Area:intersects(x, y, w, h) for _, x2, y2, w2, h2 in iterator, self, 0 do if areRectsIntersected(x, y, w, h, x2, y2, w2, h2) then @@ -66,6 +101,10 @@ function Area:intersects(x, y, w, h) return false end +--[[ + Returns *true* if the given rectangle coordinates are + within the area. +]] function Area:isWithin(x, y, w, h) for _, x2, y2, w2, h2 in iterator, self, 0 do if not doesRectContain(x, y, w, h, x2, y2, w2, h2) then @@ -90,7 +129,10 @@ function Area:intersectsBorder(x, y, w, h, borderWidth) return false end - +--[[ + Clears all rectangle coordinates. After this the + area does not contain any rectangle, i.e. *area.count == 0*. +]] function Area:clear() self.count = 0 end diff --git a/src/lwtk/Bordered.lua b/src/lwtk/Bordered.lua deleted file mode 100644 index 50f30a4..0000000 --- a/src/lwtk/Bordered.lua +++ /dev/null @@ -1,3 +0,0 @@ -local lwtk = require"lwtk" - -return lwtk.WidgetWrapper("lwtk.Bordered", lwtk.Box) diff --git a/src/lwtk/Box.lua b/src/lwtk/Box.lua index fa56a4d..87ed06a 100644 --- a/src/lwtk/Box.lua +++ b/src/lwtk/Box.lua @@ -3,6 +3,6 @@ local lwtk = require"lwtk" local Super = lwtk.Control(lwtk.Group) local Box = lwtk.newClass("lwtk.Box", Super) -Box.getMeasures = lwtk.LayoutFrame.extra.getMeasures +Box.implement.getMeasures = lwtk.LayoutFrame.extra.getMeasures return Box diff --git a/src/lwtk/Callback.lua b/src/lwtk/Callback.lua index 95af540..9916d38 100644 --- a/src/lwtk/Callback.lua +++ b/src/lwtk/Callback.lua @@ -1,6 +1,10 @@ local lwtk = require("lwtk") -local Callback = lwtk.newClass("lwtk.Callback") +--[[ + Holds a function with arguments that can + be called. +]] +local Callback = lwtk.newMeta("lwtk.Callback") function Callback:new(func, ...) @@ -20,7 +24,7 @@ local function unpack(t, i, n, ...) end end -function Callback:call(...) +function Callback:__call(...) self.func(unpack(self, 1, self.n, ...)) end diff --git a/src/lwtk/ChildLookup.lua b/src/lwtk/ChildLookup.lua index 3158066..b8b5959 100644 --- a/src/lwtk/ChildLookup.lua +++ b/src/lwtk/ChildLookup.lua @@ -1,20 +1,19 @@ local lwtk = require"lwtk" -local getWrapper = lwtk.get.wrapper local getChildLookup = lwtk.get.childLookup -local ChildLookup = lwtk.newClass("lwtk.ChildLookup") +local ChildLookup = lwtk.newMeta("lwtk.ChildLookup") ChildLookup.__mode = "v" function ChildLookup:new(group) - self[0] = false + self[0] = false self[-1] = group end -function ChildLookup.__index(self, id) +function ChildLookup:__index(id) assert(type(id) == "string", "id must be string") - local group = self[-1] + local group = rawget(self, -1) local found = nil if group then for i = 1, #group do @@ -34,7 +33,6 @@ function ChildLookup.__index(self, id) end end if found ~= nil then - found = getWrapper[found] or found self[0] = true self[id] = found end diff --git a/src/lwtk/Class.lua b/src/lwtk/Class.lua index d2d5169..44c2b98 100644 --- a/src/lwtk/Class.lua +++ b/src/lwtk/Class.lua @@ -1,13 +1,248 @@ -local Class = { - __name = "lwtk.Class", - __call = function(class, ...) - local obj = setmetatable({}, class) - local new = class.new - if new then new(obj, ...) end - return obj - end, - __tostring = function(class) - return class.__name - end -} +local lwtk = require"lwtk" + +local rawget = rawget +local match = string.match + +local getObjectMeta = lwtk.get.objectMeta +local getSuperClass = lwtk.get.superClass +local getClass = lwtk.get.class + +local DO_CHECKS = not _G.LWTK_DISABLE_CHECKS + +--[[ + Metatable for objects created by lwtk.newClass(). + + See [lwtk.Class Usage](../../Class.md) for detailed documentation + and usage examples. +]] +local Class = {} + +Class.__name = "lwtk.Class" + +function Class:__tostring() + if self.__name then + return "lwtk.Class<"..self.__name..">" + else + return "lwtk.Class" + end +end + + +local metaCall = lwtk.Meta.__call + +function Class:__call(...) + local objMeta = getObjectMeta[self] + return metaCall(objMeta, ...) +end + +local staticMeta = {} +local overrideMeta = {} +local implementMeta = {} + +function Class:__index(k) + local objMeta = getObjectMeta[self] + local v = objMeta[k] + if v ~= nil then + return v + end + if k == "extra" then + local extra = {} + objMeta[k] = extra + return extra + elseif k == "static" then + local static = {} + getObjectMeta[static] = objMeta + objMeta[k] = static + return setmetatable(static, staticMeta) + elseif k == "override" then + local override = {} + getObjectMeta[override] = objMeta + objMeta[k] = override + return setmetatable(override, overrideMeta) + elseif k == "implement" then + local implement = {} + getObjectMeta[implement] = objMeta + objMeta[k] = implement + return setmetatable(implement, implementMeta) + end + if DO_CHECKS then + lwtk.errorf("no member %q in class %s", k, self:getClassPath()) + end +end + +local function raiseAlreadyDeclaredError(class, objMeta, k, msg) + local c = getSuperClass[class] + local m = getObjectMeta[c] + while c do + if m.declared[k] then + msg = msg or "" + if objMeta[k] == false then + lwtk.errorf("member %q from class %q is already declared%s in superclass %q in class path %s", k, objMeta.__name, msg, m.__name, class:getClassPath()) + else + lwtk.errorf("member %q from class %q is already defined%s in superclass %q in class path %s", k, objMeta.__name, msg, m.__name, class:getClassPath()) + end + end + c = getSuperClass[c] + m = getObjectMeta[c] + end +end + +function Class:__newindex(k, v) + if k == "declared" or k == "static" or k == "override" or k == "implement" then + lwtk.errorf("member name %q no allowed", k) + end + local objMeta = getObjectMeta[self] + local declared = objMeta.declared + if DO_CHECKS and declared[k] then + if objMeta[k] == false then + lwtk.errorf("member %q already declared in class %s ", k, self:getClassPath()) + else + lwtk.errorf("member %q already defined in class %s ", k, self:getClassPath()) + end + end + if DO_CHECKS and k ~= "extra" and objMeta[k] ~= nil then + raiseAlreadyDeclaredError(self, objMeta, k) + end + declared[k] = true + if match(k, "^__") or k == "extra" or k == "new" then + assert(k ~= "__index" and k ~= "__newindex" and k ~= "__name") + -- accessible only from class, not from object + objMeta[k] = v + else + local index = objMeta.__index + -- accessible from object and class + index[k] = v + objMeta[k] = v + end +end + +local function cnext(t, i) + local k, v = next(t, i) + if k == "__metatable" then + return next(t, k) + else + return k, v + end +end + +function Class:__pairs() + return cnext, getObjectMeta[self], nil +end + +function staticMeta:__index(k) + local objMeta = getObjectMeta[self] + local v = objMeta[k] + if v and rawget(objMeta.__index, k) == nil then + return v + end +end + +function staticMeta:__newindex(k, v) + local objMeta = getObjectMeta[self] + if k == "declared" or k == "static" or k == "override" or k == "implement" then + lwtk.errorf("member name %q no allowed", k) + end + local declared = objMeta.declared + if DO_CHECKS and declared[k] then + if objMeta[k] == false then + lwtk.errorf("member %q already declared in class %s ", k, getClass[objMeta]:getClassPath()) + else + lwtk.errorf("member %q already defined in class %s ", k, getClass[objMeta]:getClassPath()) + end + end + declared[k] = true + assert(k ~= "__index" and k ~= "__newindex" and k ~= "__name") + if DO_CHECKS and rawget(objMeta.__index, k) ~= nil then + raiseAlreadyDeclaredError(getClass[objMeta], objMeta, k, " as non static") + end + objMeta[k] = v +end + +function overrideMeta:__newindex(k, v) + if k == "declared" or k == "static" or k == "override" or k == "implement" then + lwtk.errorf("member name %q no allowed", k) + end + local objMeta = getObjectMeta[self] + local declared = objMeta.declared + if DO_CHECKS and declared[k] then + if objMeta[k] == false then + lwtk.errorf("member %q already declared in class %s ", k, getClass[objMeta]:getClassPath()) + else + lwtk.errorf("member %q already defined in class %s ", k, getClass[objMeta]:getClassPath()) + end + end + if objMeta[k] == nil then + lwtk.errorf("cannot override member %q in class %q because it is not declared in class path %s", k, objMeta.__name, getClass[objMeta]:getClassPath()) + end + declared[k] = true + if match(k, "^__") or k == "extra" or k == "new" then + assert(k ~= "__index" and k ~= "__newindex" and k ~= "__name") + -- accessible only from class, not from object + objMeta[k] = v + else + local index = objMeta.__index + if DO_CHECKS and rawget(index, k) == nil then + raiseAlreadyDeclaredError(getClass[objMeta], objMeta, k, " as static") + end + -- accessible from object and class + index[k] = v + objMeta[k] = v + end +end + +function overrideMeta:__index(k) + local objMeta = getObjectMeta[self] + local v = objMeta[k] + if v and objMeta.declared[k] then + return v + end +end + +function implementMeta:__index(k) + local objMeta = getObjectMeta[self] + local v = objMeta[k] + if v and objMeta.declared[k] then + local s = getSuperClass[getClass[objMeta]] + if not s or getObjectMeta[k] == nil then + return v + end + end +end + +function implementMeta:__newindex(k, v) + if k == "declared" or k == "static" or k == "override" or k == "implement" then + lwtk.errorf("member name %q no allowed", k) + end + local objMeta = getObjectMeta[self] + local declared = objMeta.declared + if DO_CHECKS and declared[k] then + if objMeta[k] == false then + lwtk.errorf("member %q already declared in class %s ", k, getClass[objMeta]:getClassPath()) + else + lwtk.errorf("member %q already defined in class %s ", k, getClass[objMeta]:getClassPath()) + end + end + if DO_CHECKS and objMeta[k] ~= false then + if objMeta[k] == nil then + lwtk.errorf("cannot implement member %q in class %q because it is not declared in class path %s", k, objMeta.__name, getClass[objMeta]:getClassPath()) + else + raiseAlreadyDeclaredError(getClass[objMeta], objMeta, k) + end + end + declared[k] = true + if match(k, "^__") or k == "extra" or k == "new" then + assert(k ~= "__index" and k ~= "__newindex" and k ~= "__name") + -- accessible only from class, not from object + objMeta[k] = v + else + local index = objMeta.__index + if rawget(index, k) == nil then + raiseAlreadyDeclaredError(getClass[objMeta], objMeta, k, " as static") + end + -- accessible from object and class + index[k] = v + objMeta[k] = v + end +end + return Class diff --git a/src/lwtk/Color.lua b/src/lwtk/Color.lua index aa8ff95..7896f19 100644 --- a/src/lwtk/Color.lua +++ b/src/lwtk/Color.lua @@ -2,8 +2,14 @@ local format = string.format local floor = math.floor local lwtk = require"lwtk" -local vivid = lwtk.vivid - +local vivid = lwtk.internal.vivid + +--[[ + RGBA Color value. + + Contains the float values *r (red)*, *g (green)*, *b (blue)* and optional + *a (alpha value)* in the range >= 0 and <= 1. +]] local Color = lwtk.newClass("lwtk.Color") local isInstanceOf = lwtk.isInstanceOf @@ -13,6 +19,41 @@ local hexBytePat = "("..hexCharPat..hexCharPat..")" local rgbPat = "^"..hexBytePat..hexBytePat..hexBytePat.."$" local rgbaPat = "^"..hexBytePat..hexBytePat..hexBytePat..hexBytePat.."$" +Color:declare( + "r", -- red color float value (0 <= r <= 1) + "g", -- green color float value (0 <= g <= 1) + "b", -- blue color float value (0 <= b <= 1) + "a" -- alpha float value (0 <= a <= 1) or nil +) + +--[[ + Creates a new RGBA color value. + + Possible invocations: + + * **`Color()`** + + If called without arguments, the color black is created, i.e. + *r = g = b = 0*. + + * **`Color(r,g,b,a)`** + + If more than one arg is given, arguments are the float color + values *r*, *g*, *b*, *a* with the alpha value *a* being optional. + + * **`Color(table)`** + + * *table* - a table with the entries for the keys *r*, *g*, *b* + with optional alpha value *a*. + Missing entries for *r*, *g*, *b* are treated as 0. + + * **`Color(string)`** + + * *string* - a string in hex encoding with length 6 or 8 + (format *"rrggbb"* or *"rrggbbaa"*). Each color value + consists of two hexadecimal digits and is in the range + *00 <= value <= ff*, alpha value is optional. +]] function Color:new(...) local nargs = select("#", ...) if nargs == 0 then @@ -122,11 +163,14 @@ function Color.__add(color1, color2) end function Color.__eq(color1, color2) - return floor(color1.r * 0xff) == floor(color2.r * 0xff) + return color1.r and color2.r + and color1.g and color2.g + and color1.b and color2.b + and floor(color1.r * 0xff) == floor(color2.r * 0xff) and floor(color1.g * 0xff) == floor(color2.g * 0xff) and floor(color1.b * 0xff) == floor(color2.b * 0xff) - and ( (color1.a == nil and color2.a == nil) - or (color1.a ~= nil and color2.a ~= nil + and ( (not color1.a and not color2.a) + or (color1.a and color2.a and floor(color1.a * 0xff) == floor(color2.a * 0xff))) end diff --git a/src/lwtk/Colored.lua b/src/lwtk/Colored.lua index ed56b04..48c1cb8 100644 --- a/src/lwtk/Colored.lua +++ b/src/lwtk/Colored.lua @@ -1,20 +1,21 @@ local lwtk = require("lwtk") -local Colored = lwtk.newMixin("lwtk.Colored", lwtk.Styleable.NO_STYLE_SELECTOR) +local Colored = lwtk.newMixin("lwtk.Colored", lwtk.Styleable.NO_STYLE_SELECTOR, -function Colored.initClass(Colored, Super) -- luacheck: ignore 431/Colored - - local Super_onDraw = Super.onDraw - - function Colored:onDraw(ctx, ...) - local background = self:getStyleParam("BackgroundColor") - if background then - ctx:fillRect(background, 0, 0, self.w, self.h) - end - if Super_onDraw then - Super_onDraw(self, ctx, ...) + function(Colored, Super) + + local Super_onDraw = Super.onDraw + + function Colored.implement:onDraw(ctx, ...) + local background = self:getStyleParam("BackgroundColor") + if background then + ctx:fillRect(background, 0, 0, self.w, self.h) + end + if Super_onDraw then + Super_onDraw(self, ctx, ...) + end end end -end +) return Colored diff --git a/src/lwtk/Column.lua b/src/lwtk/Column.lua index 9eaa636..3f207ed 100644 --- a/src/lwtk/Column.lua +++ b/src/lwtk/Column.lua @@ -5,7 +5,17 @@ local Column = lwtk.newClass("lwtk.Column", Super) ------------------------------------------------------------------------------------------------- -lwtk.internal.ColumnImpl.implementColumn(Column, false) +local impl = lwtk.internal.ColumnImpl.implementColumn(false) + +--[[ + @function(self) +]] +Column.implement.getMeasures = impl.getMeasures + +--[[ + @function(self, width, height, isLayoutTransition) +]] +Column.implement.onLayout = impl.onLayout ------------------------------------------------------------------------------------------------- diff --git a/src/lwtk/Component.lua b/src/lwtk/Component.lua index 911c482..9d168b3 100644 --- a/src/lwtk/Component.lua +++ b/src/lwtk/Component.lua @@ -21,21 +21,45 @@ local callOnLayout = lwtk.layout.callOnLayout local getFontInfos = lwtk.get.fontInfos local getChildLookup = lwtk.get.childLookup -local Super = lwtk.Actionable +local Super = lwtk.Drawable(lwtk.Node(lwtk.Actionable())) local Component = lwtk.newClass("lwtk.Component", Super) -function Component:new(initParams) - getApp[self] = false - getRoot[self] = self - self.visible = true +Component:declare( + "_animationActive", + "_animationTriggered", + "_handleFocusIn", + "_handleHasFocusHandler", + "_hasChanges", + "_isRelayouting", + "_needsRedraw", + "_needsRelayout", + "_positionsChanged", + "_frameTransition", + "_hidden", + "_ignored", + "initParams", + "oldX", "oldY", "oldW", "oldH", + "getMeasures", + "onDisabled", + "onDraw", + "onHotkeyEnabled", + "onEffectiveVisibilityChanged", + "onLayout", + "onRealize" +) + +function Component.override:new(initParams) self.x = 0 self.y = 0 self.w = 0 self.h = 0 + self.visible = true + getApp[self] = false + getRoot[self] = self Super.new(self, initParams) end -function Component:setInitParams(initParams) +function Component.override:setInitParams(initParams) if initParams then local id = initParams.id if id then @@ -57,7 +81,7 @@ function Component:setInitParams(initParams) end end -function Component:handleRemainingInitParams(initParams) +function Component.override:handleRemainingInitParams(initParams) local hasRemaining = false for k, v in pairs(initParams) do assert(type(k) == "string", "attribute names must be string") @@ -78,14 +102,11 @@ end function Component:setTimer(seconds, func, ...) local p = assert(getParent[self], "Component not connected to parent") p:setTimer(seconds, func, ...) - self.setTimer = p.setTimer end function Component:getCurrentTime() - local p = assert(getParent[self], "Component not connected to parent") - local rslt = p:getCurrentTime() - self.getCurrentTime = p.getCurrentTime - return rslt + local app = assert(getApp[self], "Component not connected to Application") + return app:getCurrentTime() end function Component:getFontInfo(family, slant, weight, size) @@ -141,7 +162,8 @@ local function setAppAndRoot(self, app, root) if app then self:_setApp(app) end - for _, child in ipairs(self) do + for i = 1, #self do + local child = rawget(self, i) setAppAndRoot(child, app, root) end if (self._handleFocusIn or self.onHotkeyEnabled) and not getFocusHandler[self] then @@ -180,7 +202,8 @@ end function Component:_setParent(parent) assert(not getParent[self], "Component was already added to parent") getParent[self] = parent - setAppAndRoot(self, getApp[parent], + local app = getApp[parent] + setAppAndRoot(self, app, getRoot[parent]) local _needsRelayout = self._needsRelayout if self._hasChanges then @@ -192,6 +215,9 @@ function Component:_setParent(parent) w._hasChanges = true w._needsRelayout = _needsRelayout w = getParent[w] + if not w and app then + app._hasChanges = true + end until not w end end @@ -259,6 +285,12 @@ function Component:_setFrame(newX, newY, newW, newH, fromFrameAnimation) end widget._hasChanges = true widget = getParent[widget] + if not widget then + local app = getApp[self] + if app then + app._hasChanges = true + end + end until not widget end self.x, self.y, self.w, self.h = newX, newY, newW, newH @@ -342,13 +374,17 @@ end function Component:triggerLayout() - if getApp[self] then + local app = getApp[self] + if app then self._needsRelayout = true local p = getParent[self] while p and not p._needsRelayout do p._hasChanges = true p._needsRelayout = true p = getParent[p] + if not p then + app._hasChanges = true + end end end end @@ -363,6 +399,12 @@ function Component:triggerRedraw() end w._hasChanges = true w = getParent[w] + if not w then + local app = getApp[self] + if app then + app._hasChanges = true + end + end until not w end end @@ -390,14 +432,6 @@ function Component:updateAnimation() getParent[self]:updateAnimation() end -function Component:getStyleParam(paramName) - return getParent[self]:getStyleParam(paramName) -end - -function Component:getMandatoryStyleParam(paramName) - return getParent[self]:getMandatoryStyleParam(paramName) -end - function Component:_processDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea) local onDraw = self.onDraw if onDraw then @@ -413,42 +447,4 @@ function Component:_processDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea) end end -function Component:_processMouseEnter(x, y) - call("onMouseEnter", self, x, y) -end - -function Component:_processMouseMove(mouseEntered, x, y) - call("onMouseMove", self, x, y) -end - -function Component:_processMouseLeave(x, y) - call("onMouseLeave", self, x, y) -end - -function Component:_processMouseScroll(dx, dy) - local comp = self - while true do - local onMouseScroll = comp.onMouseScroll - if onMouseScroll and onMouseScroll(comp, dx, dy) then - return true - end - comp = getParent[comp] - if not comp then - return false - end - end -end - -function Component:_processMouseDown(mx, my, button, modState) - local onMouseDown = self.onMouseDown - if onMouseDown then - onMouseDown(self, mx, my, button, modState) - return true, true - end -end - -function Component:_processMouseUp(mouseEntered, mx, my, button, modState) - call("onMouseUp", self, mx, my, button, modState) -end - return Component diff --git a/src/lwtk/Compound.lua b/src/lwtk/Compound.lua index 1defdbb..2a6af0b 100644 --- a/src/lwtk/Compound.lua +++ b/src/lwtk/Compound.lua @@ -2,35 +2,35 @@ local lwtk = require"lwtk" local Rect = lwtk.Rect local intersectRects = Rect.intersectRects -local getWrappingParent = lwtk.get.wrappingParent -local Compound = lwtk.newMixin("lwtk.Compound", lwtk.Styleable.NO_STYLE_SELECTOR) +local Compound = lwtk.newMixin("lwtk.Compound", lwtk.Styleable.NO_STYLE_SELECTOR, -function Compound.initClass(Compound, Super) -- luacheck: ignore 431/Compound + function(Compound, Super) - function Compound:_processChanges(x0, y0, cx, cy, cw, ch, damagedArea) - Super._processChanges(self, x0, y0, cx, cy, cw, ch, damagedArea) - local x, y, w, h = x0 + self.x, y0 + self.y, self.w, self.h - cx, cy, cw, ch = intersectRects(x, y, w, h, cx, cy, cw, ch) - for _, child in ipairs(self) do - if child._hasChanges then - child._hasChanges = false - child:_processChanges(x, y, cx, cy, cw, ch, damagedArea) + function Compound.override:_processChanges(x0, y0, cx, cy, cw, ch, damagedArea) + Super._processChanges(self, x0, y0, cx, cy, cw, ch, damagedArea) + local x, y, w, h = x0 + self.x, y0 + self.y, self.w, self.h + cx, cy, cw, ch = intersectRects(x, y, w, h, cx, cy, cw, ch) + for i = 1, #self do + local child = self[i] + if child._hasChanges then + child._hasChanges = false + child:_processChanges(x, y, cx, cy, cw, ch, damagedArea) + end end end + end - -end +) -function Compound:addChild(child) - local myChild = getWrappingParent[child] or child - self[#self + 1] = myChild - myChild:_setParent(self) +function Compound.implement:addChild(child) + rawset(self, #self + 1, child) + child:_setParent(self) return child end -function Compound:_processDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea) +function Compound.override:_processDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea) local opacity = self:getStyleParam("Opacity") or 1 if opacity < 1 then ctx:beginOpacity(opacity) @@ -45,7 +45,8 @@ function Compound:_processDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea) cx, cy, cw, ch = intersectRects(x0, y0, self.w, self.h, cx, cy, cw, ch) if cw > 0 and ch > 0 then - for _, child in ipairs(self) do + for i = 1, #self do + local child = self[i] if not child._ignored then local childX, childY = child.x, child.y local x, y, w, h = x0 + childX, y0 + childY, child.w, child.h diff --git a/src/lwtk/DefaultKeyBinding.lua b/src/lwtk/DefaultKeyBinding.lua index 2594ee7..afa7131 100644 --- a/src/lwtk/DefaultKeyBinding.lua +++ b/src/lwtk/DefaultKeyBinding.lua @@ -1,5 +1,8 @@ local lwtk = require"lwtk" +--[[ + Returns new lwtk.KeyBinding object with default settings. +]] return function() return lwtk.KeyBinding { diff --git a/src/lwtk/DefaultStyle.lua b/src/lwtk/DefaultStyle.lua index d16be90..2559235 100644 --- a/src/lwtk/DefaultStyle.lua +++ b/src/lwtk/DefaultStyle.lua @@ -7,7 +7,7 @@ local scale = lwtk.StyleRef.scale local Super = lwtk.Style local DefaultStyle = lwtk.newClass("lwtk.DefaultStyle", Super) -function DefaultStyle:new(initParams) +function DefaultStyle.override:new(initParams) local function par(name) local rslt = initParams and initParams[name] @@ -37,6 +37,7 @@ function DefaultStyle:new(initParams) { "TextSize", 12 }, { "FontFamily", "sans-serif" }, + { "ScrollBarSize", 12 }, { "BackgroundColor", backgroundColor }, { "TextColor", textColor }, @@ -48,10 +49,11 @@ function DefaultStyle:new(initParams) { "CursorColor:focused", Color"000000" }, { "CursorWidth", 2 }, - { "*Margin@Control", 8 }, - { "Height@Control", 24 }, - { "BorderPadding@Control", 3 }, - { "TextFullVisible@Control", true }, + { "Margin@Control", 8 }, + { "*Margin@Control", get"Margin" }, + { "Height@Control", 24 }, + { "BorderPadding@Control", 3 }, + { "TextFullVisible@Control", true }, { "BorderSize@Box", 1 }, { "BorderPadding@Box", 3 }, diff --git a/src/lwtk/Drawable.lua b/src/lwtk/Drawable.lua new file mode 100644 index 0000000..1a1c963 --- /dev/null +++ b/src/lwtk/Drawable.lua @@ -0,0 +1,67 @@ +local lwtk = require"lwtk" + +local call = lwtk.call +local getParent = lwtk.get.parent + +local Drawable = lwtk.newMixin("lwtk.Drawable") + +Drawable:declare( + "visible", + "x", "y", "w", "h", + "id", + "addChild", + "_setStyleFromParent" +) + +function Drawable:getStyleParam(paramName) + return getParent[self]:getStyleParam(paramName) +end + +function Drawable:getMandatoryStyleParam(paramName) + local p = self:getStyleParam(paramName) + if not p then + lwtk.errorf("Missing StyleParam %q", paramName) + end + return p +end + +function Drawable.implement:_processMouseEnter(x, y) + call("onMouseEnter", self, x, y) +end + +function Drawable.implement:_processMouseLeave(x, y) + call("onMouseLeave", self, x, y) +end + +function Drawable.implement:_processMouseMove(mouseEntered, x, y) + call("onMouseMove", self, x, y) +end + + +function Drawable.implement:_processMouseScroll(dx, dy) + local comp = self + while true do + local onMouseScroll = comp.onMouseScroll + if onMouseScroll and onMouseScroll(comp, dx, dy) then + return true + end + comp = getParent[comp] + if not comp then + return false + end + end +end + +function Drawable.implement:_processMouseDown(mx, my, button, modState) + local onMouseDown = self.onMouseDown + if onMouseDown then + onMouseDown(self, mx, my, button, modState) + return true, true + end +end + +function Drawable.implement:_processMouseUp(mouseEntered, mx, my, button, modState) + call("onMouseUp", self, mx, my, button, modState) +end + +return Drawable diff --git a/src/lwtk/FocusGroup.lua b/src/lwtk/FocusGroup.lua index 358a0bd..7c13ef0 100644 --- a/src/lwtk/FocusGroup.lua +++ b/src/lwtk/FocusGroup.lua @@ -10,12 +10,16 @@ local FocusHandler = lwtk.FocusHandler local Super = lwtk.Focusable(lwtk.Box) local FocusGroup = lwtk.newClass("lwtk.FocusGroup", Super) -function FocusGroup:new(...) +FocusGroup:declare( + "entered" +) + +function FocusGroup.override:new(...) Super.new(self, ...) getFocusHandler[self] = FocusHandler(self) end -function FocusGroup:_setApp(app) +function FocusGroup.override:_setApp(app) getApp[getFocusHandler[self]] = app Super._setApp(self, app) local parentHandler = getParent[self]:getFocusHandler() @@ -29,14 +33,14 @@ function FocusGroup:_setApp(app) end end -function FocusGroup:_handleFocusIn() +function FocusGroup.override:_handleFocusIn() Super._handleFocusIn(self) if self.entered then getFocusHandler[self]:_handleFocusIn() end end -function FocusGroup:_handleFocusOut(reallyLostFocus) +function FocusGroup.override:_handleFocusOut(reallyLostFocus) Super._handleFocusOut(self) getFocusHandler[self]:_handleFocusOut() if reallyLostFocus then @@ -45,14 +49,14 @@ function FocusGroup:_handleFocusOut(reallyLostFocus) end end -function FocusGroup:_processMouseDown(mx, my, button, modState) +function FocusGroup.override:_processMouseDown(mx, my, button, modState) if button == 1 and not self.disabled then getParentFocusHandler[self]:setFocusTo(self) end return Super._processMouseDown(self, mx, my, button, modState) end -function FocusGroup:_handleChildRequestsFocus() +function FocusGroup.implement:_handleChildRequestsFocus() if not self.entered then self.entered = true self:setState("entered", true) @@ -69,7 +73,7 @@ function FocusGroup:_handleChildRequestsFocus() end end -function FocusGroup:setFocus(flag) +function FocusGroup.override:setFocus(flag) if not self.disabled and (flag == nil or flag) then local focusHandler = getParentFocusHandler[self] if focusHandler then @@ -80,7 +84,7 @@ function FocusGroup:setFocus(flag) end end -function FocusGroup:onKeyDown(key, modifier, ...) +function FocusGroup.override:onKeyDown(key, modifier, ...) local handled if self.entered then handled = getFocusHandler[self]:onKeyDown(key, modifier, ...) @@ -88,7 +92,7 @@ function FocusGroup:onKeyDown(key, modifier, ...) return handled end -function FocusGroup:handleHotkey(key, modifier, ...) +function FocusGroup.implement:handleHotkey(key, modifier, ...) local handled if self.entered then handled = getFocusHandler[self]:handleHotkey(key, modifier, ...) @@ -96,7 +100,7 @@ function FocusGroup:handleHotkey(key, modifier, ...) return handled end -function FocusGroup:invokeActionMethod(actionMethodName) +function FocusGroup.override:invokeActionMethod(actionMethodName) local handled if self.entered then handled = getFocusHandler[self]:invokeActionMethod(actionMethodName) diff --git a/src/lwtk/FocusHandler.lua b/src/lwtk/FocusHandler.lua index a59b555..d50de7e 100644 --- a/src/lwtk/FocusHandler.lua +++ b/src/lwtk/FocusHandler.lua @@ -14,10 +14,16 @@ local getDefault = lwtk.WeakKeysTable() local getHotkeys = lwtk.WeakKeysTable() local registeredWidgets = lwtk.WeakKeysTable() -local Super = lwtk.Actionable +local Super = lwtk.Actionable() local FocusHandler = lwtk.newClass("lwtk.FocusHandler", Super) -function FocusHandler:new(baseWidget) +FocusHandler:declare( + "baseWidget", + "_hasFocus", + "defaultPostponed" +) + +function FocusHandler.override:new(baseWidget) Super.new(self) self.baseWidget = baseWidget getFocusableChildren[self] = {} @@ -459,7 +465,7 @@ function FocusHandler:setFocusTo(newFocusChild) end end -function FocusHandler:hasActionMethod(actionMethodName) +function FocusHandler.override:hasActionMethod(actionMethodName) local focusedChild = getFocusedChild[self] if focusedChild then local childHasActionMethod = focusedChild.hasActionMethod @@ -470,7 +476,7 @@ function FocusHandler:hasActionMethod(actionMethodName) return Super.hasActionMethod(self, actionMethodName) end -function FocusHandler:invokeActionMethod(actionMethodName) +function FocusHandler.override:invokeActionMethod(actionMethodName) local focusedChild = getFocusedChild[self] if focusedChild then local childInvokeActionMethod = focusedChild.invokeActionMethod diff --git a/src/lwtk/Focusable.lua b/src/lwtk/Focusable.lua index 5412b05..27b45c6 100644 --- a/src/lwtk/Focusable.lua +++ b/src/lwtk/Focusable.lua @@ -3,62 +3,75 @@ local lwtk = require"lwtk" local call = lwtk.call local getFocusHandler = lwtk.get.focusHandler -local Focusable = lwtk.newMixin("lwtk.Focusable") - -Focusable.extra = {} - local handlePostponedStates -function Focusable.initClass(Focusable, Super) -- luacheck: ignore 431/Focusable +local Focusable = lwtk.newMixin("lwtk.Focusable", - function Focusable:_handleHasFocusHandler(focusHandler) - if Super._handleHasFocusHandler then - Super._handleHasFocusHandler(self, focusHandler) - end - if not self._hidden then - handlePostponedStates(self, focusHandler) - end - end + function(Focusable, Super) - function Focusable:onEffectiveVisibilityChanged(hidden) - local superCall = Super.onEffectiveVisibilityChanged - if superCall then - superCall(self, hidden) - end - if not hidden then - local focusHandler = getFocusHandler[self] - if focusHandler then + Focusable:declare( + "_focusDisabled", + "_wantsDefault", + "_wantsFocus", + "_wantsFocusDisabled", + "disabled", + "onHotkeyDown", + "onKeyDown", + "hasFocus", + "onFocusIn", + "onFocusOut", + "handleHotkey" + ) + + function Focusable.override:_handleHasFocusHandler(focusHandler) + if Super._handleHasFocusHandler then + Super._handleHasFocusHandler(self, focusHandler) + end + if not self._hidden then handlePostponedStates(self, focusHandler) end - else - local focusHandler = getFocusHandler[self] - if focusHandler then - if self.hasFocus then - focusHandler:releaseFocus(self) + end + + function Focusable.override:onEffectiveVisibilityChanged(hidden) + local superCall = Super.onEffectiveVisibilityChanged + if superCall then + superCall(self, hidden) + end + if not hidden then + local focusHandler = getFocusHandler[self] + if focusHandler then + handlePostponedStates(self, focusHandler) end - local isCurrentDefault, isPrincipalDefault = focusHandler:isDefault(self) - if isCurrentDefault or isPrincipalDefault then - focusHandler:setDefault(self, false) + else + local focusHandler = getFocusHandler[self] + if focusHandler then + if self.hasFocus then + focusHandler:releaseFocus(self) + end + local isCurrentDefault, isPrincipalDefault = focusHandler:isDefault(self) + if isCurrentDefault or isPrincipalDefault then + focusHandler:setDefault(self, false) + end end end end - end - - local Super_onDisabled = Super.onDisabled - - function Focusable:onDisabled(disableFlag) - local focusHandler = getFocusHandler[self] - if focusHandler then - focusHandler:setFocusDisabled(self, disableFlag) - else - self._wantsFocusDisabled = true - end - if Super_onDisabled then - Super_onDisabled(self, disableFlag) + + local Super_onDisabled = Super.onDisabled + + function Focusable.override:onDisabled(disableFlag) + local focusHandler = getFocusHandler[self] + if focusHandler then + focusHandler:setFocusDisabled(self, disableFlag) + else + self._wantsFocusDisabled = true + end + if Super_onDisabled then + Super_onDisabled(self, disableFlag) + end end + end - -end +) handlePostponedStates = function(self, focusHandler) if self._wantsFocus then @@ -74,7 +87,7 @@ handlePostponedStates = function(self, focusHandler) end end -function Focusable:_handleFocusIn() +function Focusable.implement:_handleFocusIn() self.hasFocus = true call("onFocusIn", self) self:setState("focused", true) diff --git a/src/lwtk/FontInfo.lua b/src/lwtk/FontInfo.lua index 92a2592..dc98f88 100644 --- a/src/lwtk/FontInfo.lua +++ b/src/lwtk/FontInfo.lua @@ -2,6 +2,17 @@ local lwtk = require"lwtk" local FontInfo = lwtk.newClass("lwtk.FontInfo") +FontInfo:declare( + "ascent", + "descent", + "family", + "height", + "layoutContext", + "size", + "slant", + "weight" +) + function FontInfo:new(layoutContext, family, slant, weight, size) self.layoutContext = layoutContext self.family = family diff --git a/src/lwtk/FontInfos.lua b/src/lwtk/FontInfos.lua index 81ae91d..8be60de 100644 --- a/src/lwtk/FontInfos.lua +++ b/src/lwtk/FontInfos.lua @@ -4,6 +4,11 @@ local FontInfo = lwtk.FontInfo local FontInfos = lwtk.newClass("lwtk.FontInfos") +FontInfos:declare( + "layoutContext", + "cache" +) + function FontInfos:new(layoutContext) self.layoutContext = layoutContext self.cache = {} diff --git a/src/lwtk/Group.lua b/src/lwtk/Group.lua index f56ac19..52bb5e0 100644 --- a/src/lwtk/Group.lua +++ b/src/lwtk/Group.lua @@ -7,13 +7,16 @@ local getParent = lwtk.get.parent local getChildLookup = lwtk.get.childLookup local getStyle = lwtk.get.style - local Super = lwtk.MouseDispatcher(lwtk.Compound(lwtk.Widget)) local Group = lwtk.newClass("lwtk.Group", Super) +Group:declare( + "_handleChildRequestsFocus" +) + local Super_addChild = Super.addChild -function Group:new(initParams) +function Group.override:new(initParams) Super.new(self) getChildLookup[self] = ChildLookup(self) local childList = {} @@ -49,7 +52,7 @@ function Group:childById(id) end end -function Group:addChild(child) +function Group.override:addChild(child) Super_addChild(self, child) self:_clearChildLookup() local style = getStyle[self] diff --git a/src/lwtk/HotkeyHandler.lua b/src/lwtk/HotkeyHandler.lua deleted file mode 100644 index 5655730..0000000 --- a/src/lwtk/HotkeyHandler.lua +++ /dev/null @@ -1,11 +0,0 @@ -local lwtk = require"lwtk" - -local HotkeyHandler = lwtk.newClass("lwtk.HotkeyHandler") - -local getRegistry = setmetatable({}, { __mode = "k" }) - -function HotkeyHandler:new() - getRegistry[self] = {} -end - -return HotkeyHandler diff --git a/src/lwtk/HotkeyListener.lua b/src/lwtk/HotkeyListener.lua index a1b3346..788edb5 100644 --- a/src/lwtk/HotkeyListener.lua +++ b/src/lwtk/HotkeyListener.lua @@ -4,43 +4,44 @@ local getFocusHandler = lwtk.get.focusHandler local getHotkeys = lwtk.WeakKeysTable() local registeredHotkeys = lwtk.WeakKeysTable() -local HotkeyListener = lwtk.newMixin("lwtk.HotkeyListener", lwtk.Styleable.NO_STYLE_SELECTOR) - local processHotKeyRegistration -function HotkeyListener.initClass(HotkeyListener, Super) -- luacheck: ignore 431/HotkeyListener +local HotkeyListener = lwtk.newMixin("lwtk.HotkeyListener", lwtk.Styleable.NO_STYLE_SELECTOR, - local Super_onEffectiveVisibilityChanged = Super.onEffectiveVisibilityChanged - - function HotkeyListener:onEffectiveVisibilityChanged(hidden) - if Super_onEffectiveVisibilityChanged then - Super_onEffectiveVisibilityChanged(self, hidden) - end - processHotKeyRegistration(self, not hidden) - end + function(HotkeyListener, Super) - function HotkeyListener:_handleHasFocusHandler(focusHandler) - local superCall = Super._handleHasFocusHandler - if superCall then - superCall(self, focusHandler) + local Super_onEffectiveVisibilityChanged = Super.onEffectiveVisibilityChanged + + function HotkeyListener.implement:onEffectiveVisibilityChanged(hidden) + if Super_onEffectiveVisibilityChanged then + Super_onEffectiveVisibilityChanged(self, hidden) + end + processHotKeyRegistration(self, not hidden) end - local hotkeys = getHotkeys[self] - if hotkeys and not self._hidden then - focusHandler:registerHotkeys(self, hotkeys) - registeredHotkeys[self] = hotkeys + + function HotkeyListener.implement:_handleHasFocusHandler(focusHandler) + local superCall = Super._handleHasFocusHandler + if superCall then + superCall(self, focusHandler) + end + local hotkeys = getHotkeys[self] + if hotkeys and not self._hidden then + focusHandler:registerHotkeys(self, hotkeys) + registeredHotkeys[self] = hotkeys + end end - end + + local Super_onDisabled = Super.onDisabled - local Super_onDisabled = Super.onDisabled - - function HotkeyListener:onDisabled(disableFlag) - processHotKeyRegistration(self, not disableFlag) - if Super_onDisabled then - Super_onDisabled(self, disableFlag) + function HotkeyListener.implement:onDisabled(disableFlag) + processHotKeyRegistration(self, not disableFlag) + if Super_onDisabled then + Super_onDisabled(self, disableFlag) + end end + end - -end +) function processHotKeyRegistration(self, registrateFlag) if registrateFlag then @@ -104,7 +105,7 @@ function HotkeyListener:isHotkeyEnabled(hotkey) return hotkeys and hotkeys[hotkey] end -function HotkeyListener:onHotkeyEnabled(hotkey) +function HotkeyListener.implement:onHotkeyEnabled(hotkey) local hotkeys = getHotkeys[self] if not hotkeys[hotkey] then hotkeys[hotkey] = true diff --git a/src/lwtk/KeyBinding.lua b/src/lwtk/KeyBinding.lua index 822b8ae..4cbcf27 100644 --- a/src/lwtk/KeyBinding.lua +++ b/src/lwtk/KeyBinding.lua @@ -5,7 +5,7 @@ local utf8 = lwtk.utf8 local upper = utf8.upper local lower = utf8.lower -local KeyBinding = lwtk.newClass("lwtk.KeyBinding") +local KeyBinding = lwtk.newMeta("lwtk.KeyBinding") local function normalizeKeyName(key) key = string.gsub(key, "^ *(.-) *$", "%1") diff --git a/src/lwtk/KeyHandler.lua b/src/lwtk/KeyHandler.lua index 9562dd7..8bb702f 100644 --- a/src/lwtk/KeyHandler.lua +++ b/src/lwtk/KeyHandler.lua @@ -11,8 +11,6 @@ local len = utf8.len local getKeyBinding = lwtk.get.keyBinding local getFocusHandler = lwtk.get.focusHandler -local KeyHandler = lwtk.newMixin("lwtk.KeyHandler") - local modMap = {} local caches = {} local keyMap = {} @@ -31,16 +29,23 @@ local isModifier = { Super_R = "Super" } -local getState = setmetatable({}, { __mode = "k" }) +local getState = lwtk.WeakKeysTable() -function KeyHandler.initClass(KeyHandler, Super) -- luacheck: ignore 431/KeyHandler +local KeyHandler = lwtk.newMixin("lwtk.KeyHandler", - function KeyHandler:new(...) - Super.new(self, ...) - getState[self] = { current = false, mod = false } - end + function(KeyHandler, Super) -end + KeyHandler:declare( + "interceptKeyDown" + ) + + function KeyHandler.override:new(...) + Super.new(self, ...) + getState[self] = { current = false, mod = false } + end + + end +) function KeyHandler:resetKeyHandling() local state = getState[self] @@ -177,7 +182,7 @@ function KeyHandler:_handleKeyUp(keyName, keyState, keyText) state.mod = false keyName = toModKeyString(keyName, keyState) local keyBinding = getKeyBinding[self] - local actions = keyBinding[keyName] + local actions = keyBinding[keyName] if actions then local child = getVisibleChild(self) if child then diff --git a/src/lwtk/LayoutFrame.lua b/src/lwtk/LayoutFrame.lua index 09cf60d..d26cca4 100644 --- a/src/lwtk/LayoutFrame.lua +++ b/src/lwtk/LayoutFrame.lua @@ -4,21 +4,20 @@ local getMeasures = lwtk.layout.getMeasures local setOuterMargins = lwtk.layout.setOuterMargins -local LayoutFrame = lwtk.newMixin("lwtk.LayoutFrame", lwtk.Styleable.NO_STYLE_SELECTOR) - LayoutFrame.extra = {} +local LayoutFrame = lwtk.newMixin("lwtk.LayoutFrame", lwtk.Styleable.NO_STYLE_SELECTOR, -function LayoutFrame.initClass(LayoutFrame, Super) -- luacheck: ignore 431/LayoutFrame + function(LayoutFrame, Super) - local Super_addChild = Super.addChild - - function LayoutFrame:addChild(child) - if self[1] then - lwtk.errorf("object of type %s can only have one child", lwtk.type(self)) + local Super_addChild = Super.addChild + + function LayoutFrame.override:addChild(child) + if rawget(self, 1) then + lwtk.errorf("object of type %s can only have one child", lwtk.type(self)) + end + return Super_addChild(self, child) end - return Super_addChild(self, child) end - -end +) function LayoutFrame.extra:getMeasures() local child = self[1] @@ -55,7 +54,7 @@ function LayoutFrame.extra:getMeasures() end end -function LayoutFrame:onLayout(w, h) +function LayoutFrame.implement:onLayout(w, h) local child = self[1] if child then local p = self:getStyleParam("BorderPadding") or 0 @@ -102,7 +101,7 @@ function LayoutFrame:onLayout(w, h) end end -function LayoutFrame:onDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea) +function LayoutFrame.implement:onDraw(ctx, x0, y0, cx, cy, cw, ch, exposedArea) local background = self:getStyleParam("BackgroundColor") local color = self:getStyleParam("BorderColor") local b = self:getStyleParam("BorderSize") or 0 diff --git a/src/lwtk/Matrix.lua b/src/lwtk/Matrix.lua index 6dd141a..468fbea 100644 --- a/src/lwtk/Matrix.lua +++ b/src/lwtk/Matrix.lua @@ -12,17 +12,21 @@ local calculateLRMeasures = lwtk.internal.LayoutImpl.calculateLRMeasures local calculateTBMeasures = lwtk.internal.LayoutImpl.calculateTBMeasures local applyTBLayout = lwtk.internal.LayoutImpl.applyTBLayout -local getRowAdapters = setmetatable({}, { __mode = "k" }) -local getColumnAdapters = setmetatable({}, { __mode = "k" }) +local getRowAdapters = lwtk.WeakKeysTable() +local getColumnAdapters = lwtk.WeakKeysTable() -local col4Caches = setmetatable({}, { __mode = "k" }) -local row4Caches = setmetatable({}, { __mode = "k" }) +local col4Caches = lwtk.WeakKeysTable() +local row4Caches = lwtk.WeakKeysTable() local ColumnAdapter = lwtk.newClass("lwtk.Matrix.ColumnAdapter") local RowAdapter = lwtk.newClass("lwtk.Matrix.RowAdapter") ------------------------------------------------------------------------------------------------- +ColumnAdapter:declare("visible") + +RowAdapter:declare("visible") + function ColumnAdapter:new() self.visible = true end @@ -40,7 +44,10 @@ end ------------------------------------------------------------------------------------------------- -function Matrix:new(initParams) +Matrix:declare("columnCount", + "rowCount") + +function Matrix.override:new(initParams) local columnCount = 0 local rows = {} for i = 1, #initParams do @@ -103,7 +110,7 @@ end ------------------------------------------------------------------------------------------------- -function Matrix:getMeasures() +function Matrix.implement:getMeasures() local rowAdapters = getRowAdapters[self] local columnAdapters = getColumnAdapters[self] @@ -127,7 +134,7 @@ end ------------------------------------------------------------------------------------------------- -function Matrix:onLayout(width, height, isLayoutTransition) +function Matrix.implement:onLayout(width, height, isLayoutTransition) if not isLayoutTransition then local topMargin, rightMargin, bottomMargin, leftMargin = getOuterMargins(self) local rowAdapters = getRowAdapters[self] diff --git a/src/lwtk/Meta.lua b/src/lwtk/Meta.lua new file mode 100644 index 0000000..d21173b --- /dev/null +++ b/src/lwtk/Meta.lua @@ -0,0 +1,51 @@ +local lwtk = require("lwtk") + +--[[ + Metatable for objects created by lwtk.newMeta(). + + See [lwtk,Meta Usage](../../Meta.md) for detailed documentation + and usage examples. +]] +local Meta = {} + +Meta.__name = "lwtk.Meta" + +function Meta:__tostring() + if self.__name then + return string.format("lwtk.Meta<%s>", self.__name) + else + return "lwtk.Meta" + end +end + +local lua_version = _VERSION:match("[%d%.]*$") +local isOldLua = (#lua_version == 3 and lua_version < "5.3") + +if isOldLua then + if pcall(function() string.format("%p", {}) end) then + + Meta.fallbackToString = function(self) + local mt = getmetatable(self) + return string.format("%s: %p", mt.__name, self) -- luajit + end + else + Meta.fallbackToString = function(self) + local mt = debug.getmetatable(self) + local tmp = rawget(mt, "__tostring") + rawset(mt, "__tostring", nil) + local hash = tostring(self):match("([^ :]*)$") + rawset(mt, "__tostring", tmp) + return string.format("%s: %s", rawget(mt, "__name"), hash) -- lua5.1, lua5.2 + end + end +end + +function Meta:__call(...) + local obj = {} + setmetatable(obj, self) + local new = self.new + if new then new(obj, ...) end + return obj +end + +return Meta diff --git a/src/lwtk/Mixin.lua b/src/lwtk/Mixin.lua index dd22971..d8cc862 100644 --- a/src/lwtk/Mixin.lua +++ b/src/lwtk/Mixin.lua @@ -1,6 +1,12 @@ -local Mixin = { - __name = "lwtk.Mixin", - __index = {} -} -return Mixin +--[[ + Metatable for objects created by lwtk.newMixin(). + + See [lwtk.Mixin Usage](../../Mixin.md) for detailed documentation + and usage examples. +]] +local Mixin = {} + +Mixin.__name = "lwtk.Mixin" + +return Mixin diff --git a/src/lwtk/MouseDispatcher.lua b/src/lwtk/MouseDispatcher.lua index e8f1f1a..d0f6b4b 100644 --- a/src/lwtk/MouseDispatcher.lua +++ b/src/lwtk/MouseDispatcher.lua @@ -2,16 +2,24 @@ local lwtk = require("lwtk") local call = lwtk.call -local MouseDispatcher = lwtk.newMixin("lwtk.MouseDispatcher", lwtk.Styleable.NO_STYLE_SELECTOR) - -function MouseDispatcher.initClass(MouseDispatcher, Super) -- luacheck: ignore 431/MouseDispatcher - - function MouseDispatcher:new(initParams) - self.mouseChildButtons = {} - Super.new(self, initParams) +local MouseDispatcher = lwtk.newMixin("lwtk.MouseDispatcher", lwtk.Styleable.NO_STYLE_SELECTOR, + + function(MouseDispatcher, Super) + + MouseDispatcher:declare( + "mouseButtonChild", + "mouseChildButtons", + "mouseHoverChild", + "mouseX", + "mouseY" + ) + + function MouseDispatcher.override:new(initParams) + self.mouseChildButtons = {} + Super.new(self, initParams) + end end - -end +) local function findChildAt(self, mx, my) @@ -118,22 +126,22 @@ local function processMouseMove(self, entered, mx, my) end end -function MouseDispatcher:_processMouseEnter(mx, my) +function MouseDispatcher.override:_processMouseEnter(mx, my) processMouseMove(self, true, mx, my) end -function MouseDispatcher:_processMouseMove(mouseEntered, mx, my) +function MouseDispatcher.override:_processMouseMove(mouseEntered, mx, my) processMouseMove(self, mouseEntered, mx, my) end -function MouseDispatcher:_processMouseScroll(dx, dy) +function MouseDispatcher.override:_processMouseScroll(dx, dy) local hChild = self.mouseHoverChild if hChild and hChild ~= self then hChild:_processMouseScroll(dx, dy) end end -function MouseDispatcher:_processMouseLeave(mx, my) +function MouseDispatcher.override:_processMouseLeave(mx, my) self.mouseX = mx self.mouseY = my local bChild = self.mouseButtonChild @@ -156,7 +164,7 @@ function MouseDispatcher:_processMouseLeave(mx, my) end end -function MouseDispatcher:_processMouseDown(mx, my, button, modState) +function MouseDispatcher.override:_processMouseDown(mx, my, button, modState) self.mouseX = mx self.mouseY = my local bChild = self.mouseButtonChild @@ -194,7 +202,7 @@ local function hasButtons(buttons) end end -function MouseDispatcher:_processMouseUp(mouseEntered, mx, my, button, modState) +function MouseDispatcher.override:_processMouseUp(mouseEntered, mx, my, button, modState) self.mouseX = mx self.mouseY = my local bChild = self.mouseButtonChild diff --git a/src/lwtk/Node.lua b/src/lwtk/Node.lua new file mode 100644 index 0000000..d09e59b --- /dev/null +++ b/src/lwtk/Node.lua @@ -0,0 +1,23 @@ +local lwtk = require"lwtk" + + +local Node = lwtk.newMixin("lwtk.Node") + +Node:declare( + "_processMouseEnter", + "onMouseEnter", + "_processMouseLeave", + "onMouseLeave", + "_processMouseMove", + "onMouseMove", + "_processMouseScroll", + "onMouseScroll", + "_processMouseDown", + "onMouseDown", + "_processMouseUp", + "onMouseUp", + "onInputChanged" +) + + +return Node diff --git a/src/lwtk/Object.lua b/src/lwtk/Object.lua index 814ff04..8df3ca1 100644 --- a/src/lwtk/Object.lua +++ b/src/lwtk/Object.lua @@ -1,64 +1,191 @@ -- --- classic --- --- Copyright (c) 2014, rxi --- --- This module is free software; you can redistribute it and/or modify it under --- the terms of the MIT license. See LICENSE for details. --- --- copied from also https://github.com/rxi/classic --- - -local lua_version = _VERSION:match("[%d%.]*$") -local isOldLua = (#lua_version == 3 and lua_version < "5.3") +-- This code was inspired by: +-- +-- classic +-- +-- Copyright (c) 2014, rxi +-- +-- This module is free software; you can redistribute it and/or modify it under +-- the terms of the MIT license. See LICENSE for details. +-- +-- see also https://github.com/rxi/classic +-- -local upper = string.upper -local sub = string.sub +local rawset = rawset +local rawget = rawget +local getmetatable = getmetatable +local upper = string.upper +local sub = string.sub local lwtk = require("lwtk") local Class = lwtk.Class +local type = lwtk.type local getSuperClass = lwtk.get.superClass +local getClass = lwtk.get.class +local getObjectMeta = lwtk.get.objectMeta +local getMixinBase = lwtk.get.mixinBase +local indexMeta = {} -local Object = {} -Object.__index = Object -Object.__name = "lwtk.Object" -setmetatable(Object, Class) +local createObjMetaNewIndex -function Object:new() +if _G.LWTK_DISABLE_CHECKS then + function createObjMetaNewIndex(newObjMeta, index) + end +else + function createObjMetaNewIndex(newObjMeta, index) + function newObjMeta:__newindex(k, v) + if type(k) ~= "string" or index[k] ~= nil then + rawset(self, k, v) + else + lwtk.errorf("no object member %q declared in class %s", k, self:getClassPath()) + end + end + end + function indexMeta:__index(k) + if type(k) == "string" then + lwtk.errorf("member %q not declared in class %s", k, getClass[getObjectMeta[self]]:getClassPath()) + end + end end -local fallbackToString -if isOldLua then - fallbackToString = function(self) - local mt = getmetatable(self) - setmetatable(self, nil) - local s = tostring(self) - setmetatable(self, mt) - return mt.__name..": "..s:match("([^ :]*)$") +local function onext(obj, k) + local index = getObjectMeta[getmetatable(obj)].__index + while true do + k = next(index, k) + local rslt = (k ~= nil and obj[k]) + if rslt ~= nil then + return k, rslt + end end end -function Object.newSubClass(className, superClass) +local function objPairs(obj) + return onext, obj, nil +end + +local function createClass(newObjMeta, className, index, baseClass) + newObjMeta.__name = className + if newObjMeta.__tostring == nil then + newObjMeta.__tostring = lwtk.Meta.fallbackToString + end + createObjMetaNewIndex(newObjMeta, index) local newClass = {} - for k, v in pairs(superClass) do - if k ~= "extra" then - newClass[k] = v + newObjMeta.declared = {} + newObjMeta.__index = setmetatable(index, indexMeta) + newObjMeta.__metatable = newClass + newObjMeta.__pairs = objPairs + + getObjectMeta[newClass] = newObjMeta + getObjectMeta[index] = newObjMeta + getSuperClass[newClass] = baseClass + getClass[newObjMeta] = newClass + setmetatable(newClass, Class) + + return newClass +end + +--[[ + Superclass for all classes created by lwtk.newClass(). +]] +local Object = createClass({}, "lwtk.Object", {}) + +function Object.static.newSubClass(baseClass, className, ...) + assert(type(baseClass) == "lwtk.Class", "arg 1 must be of type lwtk.Class") + assert(type(className) == "string", "arg 2: exptected class name string") + local baseObjMeta = getObjectMeta[baseClass] + local newObjMeta = {} + for k, v in pairs(baseObjMeta) do + if type(k) == "string" and k ~= "extra" and k ~= "static" and k ~= "declared" + and k ~= "__index" and k ~= "override" and k ~= "__newindex" and k ~= "__name" + and k ~= "implement" + then + newObjMeta[k] = v end end - newClass.__index = newClass - newClass.__name = className - if isOldLua and not newClass.__tostring then - newClass.__tostring = fallbackToString + local index = {} + for k, v in pairs(baseObjMeta.__index) do + index[k] = v end - setmetatable(newClass, Class) - getSuperClass[newClass] = superClass + local newClass = createClass(newObjMeta, className, index, baseClass) return newClass end - Object.isInstanceOf = lwtk.isInstanceOf +local function getClassPath(self) + local s = getSuperClass[self] + local p = s and "("..getClassPath(s)..")" or "" + local mixinBase = getMixinBase[self] + if mixinBase then + return "#"..mixinBase.__name..p + else + return self.__name..p + end +end + +function Object:getClassPath() + local mt = getmetatable(self) + if mt == Class then + return getClassPath(self) + else + return getClassPath(mt) + end +end + +--[[ + Returns the superclass of this object. + + This method can also be called on a class. In this + case the superclass of the given class is returned. +]] +function Object:getSuperClass() + local mt = getmetatable(self) + if mt == Class then + return getSuperClass[self] + else + return getSuperClass[mt] + end +end + +function Object:getMember(name) + local mt = getmetatable(self) + if mt == Class then + local objMeta = getObjectMeta[self] + return rawget(objMeta.__index, name) + else + local m = rawget(self, name) + if m == nil then + m = rawget(getmetatable(self).__index, name) + end + return m + end +end + +local function getReverseClassPath(self) + local s = getSuperClass[self] + local p = s and getReverseClassPath(s).."/" or "/" + local mixinBase = getMixinBase[self] + if mixinBase then + return p.."#"..mixinBase.__name + else + return p..self.__name + end +end + +function Object:getReverseClassPath() + local mt = getmetatable(self) + if mt == Class then + return getReverseClassPath(self) + else + return getReverseClassPath(mt) + end +end + +function Object:getClass() + return getmetatable(self) +end + function Object:setAttributes(attr) if attr ~= nil then assert(type(attr) == "table", "table expected") @@ -72,4 +199,45 @@ function Object:setAttributes(attr) end end +function Object.static:getMixinBase() + return getMixinBase[self] +end + +if _G.LWTK_DISABLE_CHECKS then + function Object.static:declare(...) + for i = 1, select("#", ...) do + local var = select(i, ...) + self[var] = false + end + end +else + function Object.static:declare(...) + for i = 1, select("#", ...) do + local var = select(i, ...) + if var:match("^[a-zA-Z_][a-zA-Z_0-9]*$") then + local objMeta = getObjectMeta[self] + if objMeta[var] == nil then + self[var] = false + else + local c = self + local m = objMeta + while true do + if m.declared[var] then + if c[var] ~= false then + lwtk.errorf("member %q from class %q is already defined in superclass %q in class path %s", var, objMeta.__name, m.__name, self:getClassPath()) + else + lwtk.errorf("member %q from class %q is already declared in superclass %q in class path %s", var, objMeta.__name, m.__name, self:getClassPath()) + end + end + c = getSuperClass[c] + m = getObjectMeta[c] + end + end + else + lwtk.errorf("invalid member name %q", var) + end + end + end +end + return Object diff --git a/src/lwtk/PushButton.lua b/src/lwtk/PushButton.lua index 66b91ee..4de805c 100644 --- a/src/lwtk/PushButton.lua +++ b/src/lwtk/PushButton.lua @@ -4,10 +4,19 @@ local TextFragment = lwtk.TextFragment local Super = lwtk.Focusable(lwtk.Button) local PushButton = lwtk.newClass("lwtk.PushButton", Super) -PushButton.getMeasures = lwtk.TextLabel.getMeasures +PushButton.implement.getMeasures = lwtk.TextLabel.getMeasures PushButton.setDefault = lwtk.Focusable.extra.setDefault -function PushButton:new(initParams) +PushButton:declare( + "textFragment", + "text", + "onClicked", + "mousePressed", + "mouseEntered", + "_mouseDownTime" +) + +function PushButton.override:new(initParams) Super.new(self) self.textFragment = self:addChild(TextFragment { considerHotkey = true }) self:setInitParams(initParams) @@ -44,19 +53,19 @@ function PushButton:setText(text) self:triggerLayout() end end -function PushButton:onMouseEnter(x, y) +function PushButton.implement:onMouseEnter(x, y) self.mouseEntered = true if not self.disabled then self:setState("hover", true) end end -function PushButton:onMouseLeave(x, y) +function PushButton.implement:onMouseLeave(x, y) self.mouseEntered = false if not self.disabled then self:setState("hover", false) end end -function PushButton:onMouseDown(x, y, button, modState) +function PushButton.implement:onMouseDown(x, y, button, modState) if button == 1 and not self.disabled then self.mousePressed = true self:setState("pressed", true) @@ -72,7 +81,7 @@ local function onMouseUp2(self) end end -function PushButton:onMouseUp(x, y, button, modState) +function PushButton.implement:onMouseUp(x, y, button, modState) if button == 1 and not self.disabled and self.mousePressed then local simulateSeconds = self:getStyleParam("SimulateButtonClickSeconds") or 0.1 local mouseDownSeconds = self:getCurrentTime() - self._mouseDownTime @@ -106,7 +115,7 @@ local function simulateButtonClick1(self) simulateButtonClick2, self) end -function PushButton:onHotkeyDown() +function PushButton.implement:onHotkeyDown() simulateButtonClick1(self) end @@ -115,14 +124,14 @@ function PushButton:onActionFocusedButtonClick() end -function PushButton:onHotkeyEnabled(hotkey) +function PushButton.override:onHotkeyEnabled(hotkey) Super.onHotkeyEnabled(self, hotkey) if self.textFragment.hotkey == hotkey then self.textFragment:setShowHotkey(true) end end -function PushButton:onHotkeyDisabled(hotkey) +function PushButton.override:onHotkeyDisabled(hotkey) Super.onHotkeyDisabled(self, hotkey) if self.textFragment.hotkey == hotkey then self.textFragment:setShowHotkey(false) @@ -130,7 +139,7 @@ function PushButton:onHotkeyDisabled(hotkey) end -function PushButton:onLayout(width, height) +function PushButton.override:onLayout(width, height) Super.onLayout(self, width, height) local iw, ih = self.textFragment:getSize() local tw, th, ascent = self.textFragment:getTextMeasures() diff --git a/src/lwtk/Rect.lua b/src/lwtk/Rect.lua index c34fe4f..d336fe1 100644 --- a/src/lwtk/Rect.lua +++ b/src/lwtk/Rect.lua @@ -26,7 +26,7 @@ function Rect:toXYWH() return self.x, self.y, self.width, self.height end -local function areRectsIntersected(x1, y1, w1, h1, x2, y2, w2, h2) +function Rect.areRectsIntersected(x1, y1, w1, h1, x2, y2, w2, h2) if x1 >= x2 + w2 or x1 + w1 <= x2 then return false; -- one rectangle is on left side of other end @@ -37,14 +37,14 @@ local function areRectsIntersected(x1, y1, w1, h1, x2, y2, w2, h2) end -Rect.areRectsIntersected = areRectsIntersected +local areRectsIntersected = Rect.areRectsIntersected function Rect:intersects(x, y, w, h) return areRectsIntersected(self.x, self.y, self.width, self.height, x, y, w, h) end -local function doesRectContain(x1, y1, w1, h1, x2, y2, w2, h2) +function Rect.doesRectContain(x1, y1, w1, h1, x2, y2, w2, h2) local myX0, myY0 = x1, y1 local myX1, myY1 = myX0 + w1, myY0 + h1 @@ -58,7 +58,7 @@ local function doesRectContain(x1, y1, w1, h1, x2, y2, w2, h2) and myY0 < otherY1 and otherY1 <= myY1 end -Rect.doesRectContain = doesRectContain +local doesRectContain = Rect.doesRectContain function Rect:contains(x, y, w, h) return doesRectContain(self.x, self.y, self.width, self.height, @@ -76,7 +76,7 @@ function Rect:__tostring() return format("lwtk.Rect(%d,%d,%d,%d)", self:toXYWH()) end -local function intersectRects(x1, y1, w1, h1, x2, y2, w2, h2) +function Rect.intersectRects(x1, y1, w1, h1, x2, y2, w2, h2) if areRectsIntersected(x1, y1, w1, h1, x2, y2, w2, h2) then local x = (x1 >= x2) and x1 or x2 local y = (y1 >= y2) and y1 or y2 @@ -88,6 +88,5 @@ local function intersectRects(x1, y1, w1, h1, x2, y2, w2, h2) end end -Rect.intersectRects = intersectRects return Rect diff --git a/src/lwtk/Row.lua b/src/lwtk/Row.lua index 74beab5..60b8154 100644 --- a/src/lwtk/Row.lua +++ b/src/lwtk/Row.lua @@ -5,7 +5,17 @@ local Row = lwtk.newClass("lwtk.Row", Super) ------------------------------------------------------------------------------------------------- -lwtk.internal.ColumnImpl.implementColumn(Row, true) +local impl = lwtk.internal.ColumnImpl.implementColumn(true) + +--[[ + @function(self) +]] +Row.implement.getMeasures = impl.getMeasures + +--[[ + @function(self, width, height, isLayoutTransition) +]] +Row.implement.onLayout = impl.onLayout ------------------------------------------------------------------------------------------------- diff --git a/src/lwtk/Space.lua b/src/lwtk/Space.lua index c3d17bd..ae40033 100644 --- a/src/lwtk/Space.lua +++ b/src/lwtk/Space.lua @@ -1,5 +1,7 @@ local lwtk = require("lwtk") +local rawget = rawget + local getMeasures = lwtk.layout.getMeasures local getOuterMargins = lwtk.layout.getOuterMargins local setOuterMargins = lwtk.layout.setOuterMargins @@ -7,19 +9,23 @@ local setOuterMargins = lwtk.layout.setOuterMargins local Super = lwtk.Group local Space = lwtk.newClass("lwtk.Space", Super) +Space:declare( + "unlimited" +) + function Space:setUnlimited(unlimited) self.unlimited = unlimited end -function Space:addChild(child) - if self[1] then +function Space.override:addChild(child) + if rawget(self, 1) then lwtk.errorf("object of type %s can only have one child", lwtk.type(self)) end return Super.addChild(self, child) end -function Space:getMeasures() - local child = self[1] +function Space.implement:getMeasures() + local child = rawget(self, 1) local unlimited = self.unlimited and -1 or -2 if child then local minW, minH, bestW, bestH, _, _, @@ -31,8 +37,8 @@ function Space:getMeasures() end end -function Space:onLayout(w, h) - local child = self[1] +function Space.implement:onLayout(w, h) + local child = rawget(self, 1) if child then local tM, rM, bM, lM = getOuterMargins(self) if child.getMeasures then diff --git a/src/lwtk/Square.lua b/src/lwtk/Square.lua index 8500be7..7c8c2f7 100644 --- a/src/lwtk/Square.lua +++ b/src/lwtk/Square.lua @@ -6,14 +6,14 @@ local setOuterMargins = lwtk.layout.setOuterMargins local Super = lwtk.Group local Square = lwtk.newClass("lwtk.Square", Super) -function Square:addChild(child) +function Square.override:addChild(child) if self[1] then lwtk.errorf("object of type %s can only have one child", lwtk.type(self)) end return Super.addChild(self, child) end -function Square:getMeasures() +function Square.implement:getMeasures() local child = self[1] local topMargin, rightMargin, bottomMargin, leftMargin if child then @@ -34,7 +34,7 @@ function Square:getMeasures() return 0, 0, 0, 0, 0, 0 end -function Square:onLayout(w, h) +function Square.implement:onLayout(w, h) local child = self[1] if child then local tM, rM, bM, lM = getOuterMargins(self) diff --git a/src/lwtk/Style.lua b/src/lwtk/Style.lua index 0683d7c..11980f6 100644 --- a/src/lwtk/Style.lua +++ b/src/lwtk/Style.lua @@ -18,11 +18,25 @@ local childStyles = WeakKeysTable() local toTypePattern = TypeRule.toPattern local toStylePattern = StyleRule.toPattern +Style:declare( + "typeList", + "myScaleFactor", + "ruleList", + "cache", + "animatable", + "scalable", + "scaleFactor", + "localParams", + "parent" +) + function Style:new(ruleList) self:setRules(ruleList) end -local function clearCache(self) +local clearCache + +function Style:clearCache() self.cache = {} self.animatable = {} self.scalable = {} @@ -35,7 +49,7 @@ local function clearCache(self) end end -Style.clearCache = clearCache +clearCache = Style.clearCache function Style:setScaleFactor(scaleFactor) self.myScaleFactor = scaleFactor @@ -195,7 +209,7 @@ function Style:isScalable(parName) end end -local function _getStyleParam3(self, selector, parName, classSelectorPath, stateSelectorPath, localStyle, ctxRules, localParams) +local function _getStyleParam3(self, selector, parName, classSelectorPath, stateSelectorPath, localStyle, ctxRules, localParams, extraParentStyle) local typeRule local context local function evalRule(rule) @@ -243,7 +257,7 @@ local function _getStyleParam3(self, selector, parName, classSelectorPath, state return rslt, typeRule, (context and context.localInvolved) end end - local parent = self.parent + local parent = extraParentStyle or self.parent if parent then return _getStyleParam3(parent, selector, parName, classSelectorPath, stateSelectorPath, localStyle, ctxRules, localParams) end @@ -254,7 +268,7 @@ function Style:_getStyleParam2(parName, classSelectorPath, stateSelectorPath, ct return _getStyleParam3(self, selector, parName, classSelectorPath, stateSelectorPath, self, ctxRules) end -function Style:_getStyleParam(parName, classSelectorPath, stateSelectorPath, considerLocal) +function Style:_getStyleParam(parName, classSelectorPath, stateSelectorPath, considerLocal, extraParentStyle) local cache = self.cache local lowerParName = lower(parName) local selector = lowerParName.."@"..classSelectorPath..":"..lower(stateSelectorPath) @@ -276,10 +290,14 @@ function Style:_getStyleParam(parName, classSelectorPath, stateSelectorPath, con if not typeRule then errorf("Cannot deduce type for style parameter name %q", parName) end + if type(rslt) == "function" then + local context = StyleRuleContext(nil, extraParentStyle or self.parent, classSelectorPath, stateSelectorPath) + rslt = rslt(context) + end end end if not rslt then - rslt, typeRule, localInvolved = _getStyleParam3(self, selector, parName, classSelectorPath, stateSelectorPath, self, nil, localParams) + rslt, typeRule, localInvolved = _getStyleParam3(self, selector, parName, classSelectorPath, stateSelectorPath, self, nil, localParams, extraParentStyle) end if rslt then diff --git a/src/lwtk/StyleTypeAttributes.lua b/src/lwtk/StyleTypeAttributes.lua index 5d74046..dbb66fb 100644 --- a/src/lwtk/StyleTypeAttributes.lua +++ b/src/lwtk/StyleTypeAttributes.lua @@ -1,14 +1,8 @@ local StyleTypeAttributes = {} -local attributeNames = { "SCALABLE", "ANIMATABLE" } -StyleTypeAttributes.toAttrName = {} - -for _, n in ipairs(attributeNames) do - local a = {} - StyleTypeAttributes[n] = a - StyleTypeAttributes.toAttrName[a] = n -end +StyleTypeAttributes.SCALABLE = "SCALABLE" +StyleTypeAttributes.ANIMATABLE = "ANIMATABLE" return StyleTypeAttributes diff --git a/src/lwtk/Styleable.lua b/src/lwtk/Styleable.lua index b8d8922..d11247d 100644 --- a/src/lwtk/Styleable.lua +++ b/src/lwtk/Styleable.lua @@ -11,45 +11,52 @@ local getStylePath = lwtk.get.stylePath local getSuperClass = lwtk.get.superClass local isInstanceOf = lwtk.isInstanceOf -local getStateStylePath = setmetatable({}, { __mode = "k" }) - -local Styleable = lwtk.newMixin("lwtk.Styleable") +local getStateStylePath = lwtk.WeakKeysTable() local NO_STYLE_SELECTOR = {} -Styleable.NO_STYLE_SELECTOR = NO_STYLE_SELECTOR local function addToStyleSelectorClassPath(path, name) return (path or "").."<"..lower(name)..">" end -function Styleable.initClass(Styleable, Super) -- luacheck: ignore 431/Styleable - - function Styleable.newSubClass(className, baseClass, ...) - local newClass = Super.newSubClass(className, baseClass, ...) - local path = getStylePath[getSuperClass[newClass]] - local addToStyleSelector = true - for i = 1, select("#", ...) do - if select(i, ...) == NO_STYLE_SELECTOR then - addToStyleSelector = false - break +local Styleable = lwtk.newMixin("lwtk.Styleable", + + function(Styleable, Super) + + Styleable:declare( + "_hasOwnStyle", + "state" + ) + + function Styleable.static.newSubClass(baseClass, className, ...) + local newClass = Super.newSubClass(baseClass, className, ...) + local path = getStylePath[getSuperClass[newClass]] + local addToStyleSelector = true + for i = 1, select("#", ...) do + if select(i, ...) == NO_STYLE_SELECTOR then + addToStyleSelector = false + break + end end + if addToStyleSelector then + path = addToStyleSelectorClassPath(path, className:match("^[^(]*"), ...) + end + getStylePath[newClass] = path + return newClass end - if addToStyleSelector then - path = addToStyleSelectorClassPath(path, className, ...) + + function Styleable.override:new(initParams) + local stylePath = getStylePath[self:getClass()] + if stylePath then + getStylePath[self] = stylePath + self.state = {} + end + Super.new(self, initParams) end - getStylePath[newClass] = path - return newClass end +) - function Styleable:new(initParams) - local stylePath = getStylePath[getmetatable(self)] - if stylePath then - getStylePath[self] = stylePath - self.state = {} - end - Super.new(self, initParams) - end -end +Styleable.NO_STYLE_SELECTOR = NO_STYLE_SELECTOR function Styleable:setState(name, flag) flag = flag and true or false @@ -58,7 +65,7 @@ function Styleable:setState(name, flag) getStateStylePath[state] = false end -function Styleable:_setStyleFromParent(parentStyle) +function Styleable.implement:_setStyleFromParent(parentStyle) self:triggerLayout() local style if self._hasOwnStyle then @@ -68,8 +75,8 @@ function Styleable:_setStyleFromParent(parentStyle) style = parentStyle getStyle[self] = style end - for _, child in ipairs(self) do - call("_setStyleFromParent", child, style) + for i = 1, #self do + call("_setStyleFromParent", self[i], style) end end @@ -86,7 +93,8 @@ function Styleable:setStyle(style) style:_setParentStyle(getStyle[self]) end getStyle[self] = style - for _, child in ipairs(self) do + for i = 1, #self do + local child = rawget(self, i) call("_setStyleFromParent", child, style) end end @@ -132,7 +140,7 @@ end local getStateString = Styleable.getStateString -local function _getStyleParam(self, style, paramName) +local function _getStyleParam2(self, paramName, style, extraParentStyle) local stylePath = getStylePath[self] if not stylePath then local p = getParent[self] @@ -149,22 +157,29 @@ local function _getStyleParam(self, style, paramName) end assert(stylePath, "Widget not connected to parent") local statePath = getStateString(self) - local rslt = style:_getStyleParam(paramName, stylePath, statePath, self._hasOwnStyle) + local rslt = style:_getStyleParam(paramName, stylePath, statePath, self._hasOwnStyle, extraParentStyle) if not rslt and paramName:match("^.*Opacity$") then return 1 else return rslt end end -Styleable._getStyleParam = _getStyleParam +function Styleable:_getStyleParam(style, paramName) + local myStyle = getStyle[self] + if myStyle then + return _getStyleParam2(self, paramName, myStyle, style) + else + return _getStyleParam2(self, paramName, style) + end +end -function Styleable:getStyleParam(paramName) +function Styleable.override:getStyleParam(paramName) if not self.visible and paramName == "Opacity" then return 0 end local style = getStyle[self] if style then - return _getStyleParam(self, style, paramName) + return _getStyleParam2(self, paramName, style) end end diff --git a/src/lwtk/TextCursor.lua b/src/lwtk/TextCursor.lua index fccb6d1..c7288c8 100644 --- a/src/lwtk/TextCursor.lua +++ b/src/lwtk/TextCursor.lua @@ -4,7 +4,7 @@ local Color = lwtk.Color local Super = lwtk.Component local TextCursor = lwtk.newClass("lwtk.TextCursor", Super) -function TextCursor:onDraw(ctx) +function TextCursor.implement:onDraw(ctx) local color = self:getStyleParam("CursorColor") or Color("000000") ctx:fillRect(color, 0, 0, self.w, self.h) end diff --git a/src/lwtk/TextFragment.lua b/src/lwtk/TextFragment.lua index 4987dc9..edd1def 100644 --- a/src/lwtk/TextFragment.lua +++ b/src/lwtk/TextFragment.lua @@ -4,10 +4,24 @@ local utf8 = lwtk.utf8 local Super = lwtk.Component local TextFragment = lwtk.newClass("lwtk.TextFragment", Super) -function TextFragment:new(initParams) - self.tx = false - self.ty = false - self.label = "" +TextFragment:declare( + "tx", + "ty", + "label", + "labelLeft", + "labelKey", + "labelRight", + "text", + "textWidth", + "considerHotkey", + "hotkey", + "fontInfo", + "textSize", + "fontFamily", + "showHotKey" +) + +function TextFragment.override:new(initParams) Super.new(self, initParams) end @@ -78,13 +92,20 @@ local function getFontInfo(self) end end -TextFragment.getFontInfo = getFontInfo +function TextFragment.override:getFontInfo(family, slant, weight, size) + if family then + return Super_getFontInfo(self, family, slant, weight, size) + else + return getFontInfo(self) + end +end function TextFragment:getTextMeasures() local fontInfo, changed = getFontInfo(self) local textWidth = self.textWidth if changed or not textWidth then - textWidth = fontInfo:getTextWidth(self.label) + local label = self.label + textWidth = label and fontInfo:getTextWidth(label) or 0 self.textWidth = textWidth end return textWidth, fontInfo.height, fontInfo.ascent @@ -98,7 +119,7 @@ function TextFragment:setTextPos(tx, ty) end end -function TextFragment:onDraw(ctx, ...) +function TextFragment.implement:onDraw(ctx, ...) local label = self.label if label then local fontInfo = getFontInfo(self) @@ -118,7 +139,7 @@ function TextFragment:onDraw(ctx, ...) if self.hotkey and self.showHotKey then local x1 = tx + fontInfo:getTextWidth(self.labelLeft) local x2 = x1 + fontInfo:getTextWidth(self.labelKey) - local y1 = ty + math.floor(fontInfo.descent / 2 + 0.5) - 0.5 + local y1 = ty + 1.5 ctx:setLineWidth(1) ctx:drawLine(x1, y1, x2, y1) end diff --git a/src/lwtk/TextInput.lua b/src/lwtk/TextInput.lua index 59bee83..30df886 100644 --- a/src/lwtk/TextInput.lua +++ b/src/lwtk/TextInput.lua @@ -15,12 +15,24 @@ local getApp = lwtk.get.app local Super = lwtk.Focusable(lwtk.Control(lwtk.Compound(lwtk.Widget))) local TextInput = lwtk.newClass("lwtk.TextInput", Super) -TextInput.getMeasures = lwtk.TextLabel.getMeasures -TextInput._isInput = true +TextInput:declare( + "initActions", + "inner", + "cursor", + "textFragment", + "cursorPos", + "tx", + "text", + "filterInput" +) -function TextInput:new(initParams) +TextInput.implement.getMeasures = lwtk.TextLabel.getMeasures + +TextInput.implement._isInput = true + +function TextInput.override:new(initParams) Super.new(self) - self.initActions = extract(initParams, "initActions") + self.initActions = extract(initParams, "initActions") self.inner = self:addChild(InnerCompound()) self.cursor = self.inner:addChild(TextCursor()) self.textFragment = self.inner:addChild(TextFragment()) @@ -32,7 +44,7 @@ function TextInput:new(initParams) end end -function TextInput:onRealize() +function TextInput.implement:onRealize() if Super.onRealize then Super.onRealize(self) end @@ -116,12 +128,12 @@ function TextInput:setDefault(buttonId) end end -function TextInput:onLayout(width, height) +function TextInput.override:onLayout(width, height) Super.onLayout(self, width, height) innerLayout(self) end -function TextInput:onFocusIn() +function TextInput.implement:onFocusIn() self:setState("focused", true) if self.default then local focusHandler = getFocusHandler[self] @@ -130,7 +142,7 @@ function TextInput:onFocusIn() end end end -function TextInput:onFocusOut() +function TextInput.implement:onFocusOut() self:setState("focused", false) if self.default then local focusHandler = getFocusHandler[self] @@ -140,7 +152,7 @@ function TextInput:onFocusOut() end end -function TextInput:onMouseDown(mx, my, button, modState) +function TextInput.implement:onMouseDown(mx, my, button, modState) if button == 1 then self:setFocus(true) local fontInfo = self.textFragment:getFontInfo() @@ -255,7 +267,7 @@ function TextInput:setFilterInput(filterInput) self.filterInput = filterInput end -function TextInput:onKeyDown(keyName, keyState, keyText) +function TextInput.implement:onKeyDown(keyName, keyState, keyText) if keyText and keyText ~= "" then local filterInput = self.filterInput if filterInput then diff --git a/src/lwtk/TextLabel.lua b/src/lwtk/TextLabel.lua index 69985f1..491fe6f 100644 --- a/src/lwtk/TextLabel.lua +++ b/src/lwtk/TextLabel.lua @@ -6,7 +6,13 @@ local TextFragment = lwtk.TextFragment local Super = lwtk.Button local TextLabel = lwtk.newClass("lwtk.TextLabel", Super) -function TextLabel:new(initParams) +TextLabel:declare( + "textFragment", + "text", + "input" +) + +function TextLabel.override:new(initParams) Super.new(self) self.textFragment = self:addChild(TextFragment { considerHotkey = true }) self:setInitParams(initParams) @@ -23,14 +29,14 @@ function TextLabel:setInput(inputId) self.input = inputId end -function TextLabel:onHotkeyEnabled(hotkey) +function TextLabel.override:onHotkeyEnabled(hotkey) Super.onHotkeyEnabled(self, hotkey) if self.textFragment.hotkey == hotkey then self.textFragment:setShowHotkey(true) end end -function TextLabel:onHotkeyDisabled(hotkey) +function TextLabel.override:onHotkeyDisabled(hotkey) Super.onHotkeyDisabled(self, hotkey) if self.textFragment.hotkey == hotkey then self.textFragment:setShowHotkey(false) @@ -46,13 +52,13 @@ function TextLabel:onHotkeyDown() end end end -function TextLabel:onMouseDown(x, y, button, modState) +function TextLabel.implement:onMouseDown(x, y, button, modState) if button == 1 then self:onHotkeyDown() end end -function TextLabel:getMeasures() +function TextLabel.implement:getMeasures() local addW = (self:getStyleParam("LeftPadding") or 0) + (self:getStyleParam("RightPadding") or 0) + 2 * (self:getStyleParam("BorderPadding") or 0) @@ -123,7 +129,7 @@ function TextLabel:getMeasures() end -function TextLabel:onLayout(width, height) +function TextLabel.override:onLayout(width, height) Super.onLayout(self, width, height) local iw, ih = self.textFragment:getSize() local tw, th, ascent = self.textFragment:getTextMeasures() diff --git a/src/lwtk/Timer.lua b/src/lwtk/Timer.lua index d66097a..a3a497f 100644 --- a/src/lwtk/Timer.lua +++ b/src/lwtk/Timer.lua @@ -2,11 +2,16 @@ local lwtk = require"lwtk" local Timer = lwtk.newClass("lwtk.Timer") +Timer:declare( + "n", + "func", + "time" +) function Timer:new(func, ...) local n = select("#", ...) for i = 1, n do - self[i] = select(i, ...) + rawset(self, i, select(i, ...)) end self.n = n self.func = func diff --git a/src/lwtk/ViewSwitcher.lua b/src/lwtk/ViewSwitcher.lua index ed6daba..2aa273f 100644 --- a/src/lwtk/ViewSwitcher.lua +++ b/src/lwtk/ViewSwitcher.lua @@ -7,7 +7,7 @@ local setOuterMargins = lwtk.layout.setOuterMargins local Super = lwtk.Colored(lwtk.Group) local ViewSwitcher = lwtk.newClass("lwtk.ViewSwitcher", Super) -function ViewSwitcher:onLayout(w, h) +function ViewSwitcher.implement:onLayout(w, h) local topMargin, rightMargin, bottomMargin, leftMargin = getOuterMargins(self) for i = 1, #self do local child = self[i] @@ -16,7 +16,7 @@ function ViewSwitcher:onLayout(w, h) end end -function ViewSwitcher:getMeasures() +function ViewSwitcher.implement:getMeasures() local minW, minH, bestW, bestH, maxW, maxH, childTop, childRight, childBottom, childLeft @@ -62,7 +62,7 @@ function ViewSwitcher:getMeasures() end end -function ViewSwitcher:addChild(child) +function ViewSwitcher.override:addChild(child) local childVisible = child.visible if childVisible then for i = 1, #self do diff --git a/src/lwtk/WeakKeysTable.lua b/src/lwtk/WeakKeysTable.lua index 04d7fb4..97cc5d6 100644 --- a/src/lwtk/WeakKeysTable.lua +++ b/src/lwtk/WeakKeysTable.lua @@ -1,8 +1,7 @@ -local weakKeysMeta = { __name = "lwtk.WeakKeysTable", - __mode = "k" } +local lwtk = require("lwtk") -local function WeakKeysTable() - return setmetatable({}, weakKeysMeta) -end +local WeakKeysTable = lwtk.newMeta("lwtk.WeakKeysTable") + +WeakKeysTable.__mode = "k" return WeakKeysTable diff --git a/src/lwtk/Widget.lua b/src/lwtk/Widget.lua index afac519..ec5946d 100644 --- a/src/lwtk/Widget.lua +++ b/src/lwtk/Widget.lua @@ -7,17 +7,18 @@ local Callback = lwtk.Callback local Super = lwtk.Animatable(lwtk.Component) local Widget = lwtk.newClass("lwtk.Widget", Super) -function Widget:new(initParams) +Widget:declare( + "default", + "_isInput" +) + +function Widget.override:new(initParams) Super.new(self) if initParams then self:setInitParams(initParams) end end -function Widget:setInitParams(initParams) - Super.setInitParams(self, initParams) -end - function Widget:setOnInputChanged(onInputChanged) self.onInputChanged = onInputChanged end @@ -37,7 +38,7 @@ function Widget:notifyInputChanged() until w == nil end -function Widget:_setApp(app) +function Widget.override:_setApp(app) if self._hasOwnStyle then local ownStyle = getStyle[self] if not ownStyle.parent then @@ -53,7 +54,7 @@ function Widget:_setApp(app) end end -function Widget:_setParent(parent) +function Widget.override:_setParent(parent) local pstyle = getStyle[parent] if pstyle then self:_setStyleFromParent(pstyle) diff --git a/src/lwtk/WidgetWrapper.lua b/src/lwtk/WidgetWrapper.lua deleted file mode 100644 index f73d0b4..0000000 --- a/src/lwtk/WidgetWrapper.lua +++ /dev/null @@ -1,127 +0,0 @@ -local lwtk = require"lwtk" - -local upper = string.upper -local lower = string.lower -local sub = string.sub -local format = string.format -local match = string.match - -local newClass = lwtk.newClass -local getWrapper = lwtk.get.wrapper -local getWrappedChild = lwtk.get.wrappedChild -local getWrappingParent = lwtk.get.wrappingParent -local getStylePath = lwtk.get.stylePath - -local function cloneClass(class, selectorFrag) - local cloned = {} - for k, v in pairs(class) do - cloned[k] = v - end - cloned.__index = cloned - local selector = getStylePath[class] - if selector and selectorFrag then - getStylePath[cloned] = selector.."<"..lower(selectorFrag)..">" - end - setmetatable(cloned, getmetatable(class)) - return cloned -end - -local function shortName(className) - return match(className, "^.*%.([^.]*)$") or className -end - -local function newWrapperClass(className, WrappedChildClass, WrappingParentClass, parentAttributes, parentMethods) - - - local shortWrapperName = shortName(className) - local shortWrappedName = shortName(WrappedChildClass.__name) - local selectorFrag = format("%s(%s)", shortWrapperName, shortWrappedName) - - local WrapperClass = newClass(format("%s(%s)", className, tostring(WrappedChildClass))) - - WrappedChildClass = cloneClass(WrappedChildClass, selectorFrag) - WrappingParentClass = cloneClass(WrappingParentClass, selectorFrag) - - for k, v in pairs(WrappedChildClass) do - if type(v) == "function" and type(k) == "string" and not k:match("^__") then - WrapperClass[k] = function(self, ...) - return v(getWrappedChild[self], ...) - end - end - end - - for _, a in ipairs(parentAttributes) do - local setterName = "set"..upper(sub(a, 1, 1))..sub(a, 2) - local getterName = "get"..upper(sub(a, 1, 1))..sub(a, 2) - local setter = WrappingParentClass[setterName] - local getter = WrappingParentClass[getterName] - if setter then - WrapperClass[setterName] = function(self, ...) - return setter(getWrappingParent[self], ...) - end - end - if getter then - WrapperClass[getterName] = function(self, ...) - return getter(getWrappingParent[self], ...) - end - end - end - for _, methodName in ipairs(parentMethods) do - local method = WrappingParentClass[methodName] - if method then - WrapperClass[methodName] = function(self, ...) - return method(getWrappingParent[self], ...) - end - end - end - - function WrapperClass:new(initParams) - local parentParams - if initParams then - self.id = initParams.id - parentParams = {} - for _, a in ipairs(parentAttributes) do - local p = initParams[a] - if p then - parentParams[a] = p - initParams[a] = nil - end - end - end - local wrappingParent = WrappingParentClass(parentParams) - local wrappedChild = WrappedChildClass(initParams) - wrappingParent:addChild(wrappedChild) - getWrappingParent[self] = wrappingParent - getWrappedChild[self] = wrappedChild - getWrapper[wrappedChild] = self - end - - function WrapperClass:getWrappingParent() - return getWrappingParent[self] - end - function WrapperClass:getWrappedChild() - return getWrappedChild[self] - end - - return WrapperClass -end - -local function WidgetWrapper(className, WrappingParentClass) - - local wrappedClasses = {} - - local function wrap(WrappedChildClass) - local c = wrappedClasses[WrappedChildClass] - if not c then - c = newWrapperClass(className, - WrappedChildClass, - WrappingParentClass, - { "frame" }, { "animateFrame", "setVisible", "isVisible", "triggerLayout" }) - wrappedClasses[WrappedChildClass] = c - end - return c - end - return wrap -end - -return WidgetWrapper diff --git a/src/lwtk/Window.lua b/src/lwtk/Window.lua index 75a018f..f5cd865 100644 --- a/src/lwtk/Window.lua +++ b/src/lwtk/Window.lua @@ -1,6 +1,7 @@ local lwtk = require"lwtk" local floor = math.floor +local rawset = rawset local Area = lwtk.Area local ChildLookup = lwtk.ChildLookup @@ -11,7 +12,7 @@ local getMeasures = lwtk.layout.getMeasures local callRelayout = lwtk.layout.callRelayout local setOuterMargins = lwtk.layout.setOuterMargins -local Super = lwtk.MouseDispatcher(lwtk.KeyHandler(lwtk.Styleable(lwtk.Object))) +local Super = lwtk.MouseDispatcher(lwtk.KeyHandler(lwtk.Styleable(lwtk.Drawable(lwtk.Node(lwtk.Actionable()))))) local Window = lwtk.newClass("lwtk.Window", Super) Window.triggerLayout = lwtk.Component.triggerLayout @@ -19,9 +20,31 @@ Window.triggerRedraw = lwtk.Component.triggerRedraw Window.getRoot = lwtk.Component.getRoot Window.childById = lwtk.Group.childById -Window.color = true +Window:declare( + "_hasChanges", + "_needsRelayout", + "_positionsChanged", + "_handleChildRequestsFocus", + "_grabFocus", + "color", + "damagedArea", + "driver", + "exposedArea", + "fullRedisplayOutstanding", + "hasFocus", + "initParams", + "mapped", + "maxH", + "maxSizeFixed", + "maxW", + "mouseEntered", + "onClose", + "view", + "onSizeRequest", + "onMinSizeChanged", + "interceptMouseDown" +) -local getParent = lwtk.get.parent local getStyle = lwtk.get.style local getApp = lwtk.get.app local getRoot = lwtk.get.root @@ -32,9 +55,10 @@ local extract = lwtk.extract local childSizes = lwtk.WeakKeysTable() -function Window:new(app, initParams) +function Window.override:new(app, initParams) Super.new(self) self.fullRedisplayOutstanding = true + self.color = true getApp[self] = app getRoot[self] = self getFontInfos[self] = getFontInfos[app] @@ -43,9 +67,6 @@ function Window:new(app, initParams) self.y = 0 self.w = 0 self.h = 0 - self.getCurrentTime = app.getCurrentTime - self.setTimer = app.setTimer - getParent[self] = app getKeyBinding[self] = getKeyBinding[app] getStyle[self] = getStyle[app] Super.new(self) @@ -82,6 +103,10 @@ function Window:new(app, initParams) end end +function Window:getCurrentTime() + getApp[self]:getCurrentTime() +end + local adjustMinMaxSize local function realize(self) @@ -236,14 +261,16 @@ adjustMinMaxSize = function(self, forceMaxSize) bestW, bestH, self.maxW, self.maxH) else - self:setMinSize(minW, minH) - self:setSize(bestW, bestH) - self:setMaxSize(maxW, maxH) + if bestW > 0 and bestH > 0 then + self:setMinSize(minW, minH) + self:setSize(bestW, bestH) + self:setMaxSize(maxW, maxH) + end end end -function Window:addChild(child) - self[#self + 1] = child +function Window.implement:addChild(child) + rawset(self, #self + 1, child) local focusHandler = FocusHandler(child) getApp[focusHandler] = getApp[self] getFocusHandler[child] = focusHandler @@ -280,6 +307,7 @@ function Window:setFrame(x, y, w, h) y = floor(y + 0.5) w = floor(w + 0.5) h = floor(h + 0.5) + assert(w > 0 and h > 0, "width and height must be > 0") if self.view then self.view:setFrame(x, y, w, h) else @@ -294,6 +322,7 @@ function Window:setSize(w, h) end w = floor(w + 0.5) h = floor(h + 0.5) + assert(w > 0 and h > 0, "width and height must be > 0") if self.view then self.view:setSize(w, h) else @@ -356,7 +385,7 @@ function Window:setColor(color) if self.color ~= color then self.color = color self._hasChanges = true - local p = getParent[self] + local p = getApp[self] if p then p._hasChanges = true end end end @@ -404,7 +433,7 @@ end function Window:close() if self.view and not self.view:isClosed() then self.view:close() - getParent[self]:_removeWindow(self) + getApp[self]:_removeWindow(self) end end @@ -553,8 +582,6 @@ function Window:requestClose() end end -Window._handleClose = Window.requestClose - function Window:requestFocus() if self.view and self.mapped then self.driver:grabFocus(self) @@ -627,4 +654,8 @@ function Window:_postProcessChanges() adjustMinMaxSize(self) end +function Window:setTimer(seconds, func, ...) + getApp[self]:setTimer(seconds, func, ...) +end + return Window diff --git a/src/lwtk/btest.lua b/src/lwtk/btest.lua index 4c24928..71985e6 100644 --- a/src/lwtk/btest.lua +++ b/src/lwtk/btest.lua @@ -2,7 +2,13 @@ local tryrequire = require("lwtk.tryrequire") local lpugl = tryrequire("lpugl") +--[[ + @function(...) + + Returns *true* if bitwise AND of its operands is different from zero. +]] local btest = lpugl and lpugl.btest + if not btest then local bit = tryrequire("bit") if bit then @@ -13,6 +19,9 @@ if not btest then end if not btest then + if not lpugl then + require("lpugl") -- let require produce error message + end error("no bitoperations found") end diff --git a/src/lwtk/get.lua b/src/lwtk/get.lua index 1dfff0b..100a095 100644 --- a/src/lwtk/get.lua +++ b/src/lwtk/get.lua @@ -4,6 +4,8 @@ local WeakKeysTable = lwtk.WeakKeysTable local get = {} +get.objectMeta = WeakKeysTable() +get.class = WeakKeysTable() get.superClass = WeakKeysTable() get.app = WeakKeysTable() get.root = WeakKeysTable() @@ -13,9 +15,6 @@ get.focusHandler = WeakKeysTable() get.parentFocusHandler = WeakKeysTable() get.focusedChild = WeakKeysTable() -get.wrapper = WeakKeysTable() -get.wrappedChild = WeakKeysTable() -get.wrappingParent = WeakKeysTable() get.focusableChildren = WeakKeysTable() get.actions = WeakKeysTable() get.keyBinding = WeakKeysTable() @@ -24,5 +23,6 @@ get.fontInfos = WeakKeysTable() get.childLookup = WeakKeysTable() get.visibilityChanges = WeakKeysTable() get.deferredChanges = WeakKeysTable() +get.mixinBase = WeakKeysTable() return get diff --git a/src/lwtk/init.lua b/src/lwtk/init.lua index d937802..46e6f4c 100644 --- a/src/lwtk/init.lua +++ b/src/lwtk/init.lua @@ -1,3 +1,6 @@ +--[[ + Root module for all other *lwtk* modules. +]] local lwtk = {} lwtk.MOD_SHIFT = 1 diff --git a/src/lwtk/internal/ColumnImpl.lua b/src/lwtk/internal/ColumnImpl.lua index 123ad6d..2cf58a4 100644 --- a/src/lwtk/internal/ColumnImpl.lua +++ b/src/lwtk/internal/ColumnImpl.lua @@ -9,8 +9,8 @@ local calculateTBMeasures = lwtk.internal.LayoutImpl.calculateTBMeasures local applyLRLayout = lwtk.internal.LayoutImpl.applyLRLayout local applyTBLayout = lwtk.internal.LayoutImpl.applyTBLayout -local lr4Caches = setmetatable({}, { __mode = "k" }) -local tb4Caches = setmetatable({}, { __mode = "k" }) +local lr4Caches = lwtk.WeakKeysTable() +local tb4Caches = lwtk.WeakKeysTable() ------------------------------------------------------------------------------------------------- @@ -72,13 +72,15 @@ end ------------------------------------------------------------------------------------------------- -function ColumnImpl.implementColumn(class, isRow) +function ColumnImpl.implementColumn(isRow) + local impl = {} + local getChildLRMeasures = isRow and getChildLRMeasuresForRow or getChildLRMeasuresForColumn local getChildTBMeasures = isRow and getChildTBMeasuresForRow or getChildTBMeasuresForColumn - function class:getMeasures() + function impl:getMeasures() local minWidth, bestWidth, maxWidth, leftMargin, rightMargin = calculateLRMeasures(self, getChildLRMeasures) @@ -102,7 +104,7 @@ function ColumnImpl.implementColumn(class, isRow) topMargin, rightMargin, bottomMargin, leftMargin end - function class:onLayout(width, height, isLayoutTransition) + function impl:onLayout(width, height, isLayoutTransition) if not isLayoutTransition then local topMargin, rightMargin, bottomMargin, leftMargin = getOuterMargins(self) if isRow then @@ -130,6 +132,8 @@ function ColumnImpl.implementColumn(class, isRow) end end end + + return impl end diff --git a/src/lwtk/internal/StyleRuleContext.lua b/src/lwtk/internal/StyleRuleContext.lua index a8f43f8..f0050b6 100644 --- a/src/lwtk/internal/StyleRuleContext.lua +++ b/src/lwtk/internal/StyleRuleContext.lua @@ -6,6 +6,15 @@ local errorf = lwtk.errorf local StyleRuleContext = lwtk.newClass("lwtk.internal.StyleRuleContext") +StyleRuleContext:declare( + "ctxRules", + "style", + "classSelectorPath", + "stateSelectorPath", + "localParams", + "localInvolved" +) + function StyleRuleContext:new(ctxRules, style, classSelectorPath, stateSelectorPath, localParams) self.ctxRules = ctxRules self.style = style diff --git a/src/lwtk/internal/TypeRule.lua b/src/lwtk/internal/TypeRule.lua index 0cb40d2..1a4acb4 100644 --- a/src/lwtk/internal/TypeRule.lua +++ b/src/lwtk/internal/TypeRule.lua @@ -5,9 +5,9 @@ local lower = string.lower local gsub = string.gsub local errorf = lwtk.errorf -local TypeRule = {} +local StyleTypeAttributes = lwtk.StyleTypeAttributes -local toAttrName = lwtk.StyleTypeAttributes.toAttrName +local TypeRule = {} function TypeRule.toPattern(rule) local n = #rule @@ -15,9 +15,8 @@ function TypeRule.toPattern(rule) local result = {} for i = 1, n do local arg = rule[i] - local name = toAttrName[arg] - if name then - result[name] = true + if StyleTypeAttributes[arg] then + result[arg] = true else result[#result + 1] = arg end diff --git a/src/lwtk/internal/utf8string.lua b/src/lwtk/internal/utf8string.lua index 33c910b..c7281cf 100644 --- a/src/lwtk/internal/utf8string.lua +++ b/src/lwtk/internal/utf8string.lua @@ -98,7 +98,7 @@ end local module = { dump = string.dump, byte = string.byte, - code = utf8.codepoint, +-- code = utf8.codepoint, char = utf8.char, format = string.format, rep = string.rep, diff --git a/src/lwtk/vivid.lua b/src/lwtk/internal/vivid.lua similarity index 100% rename from src/lwtk/vivid.lua rename to src/lwtk/internal/vivid.lua diff --git a/src/lwtk/isInstanceOf.lua b/src/lwtk/isInstanceOf.lua index 0137536..aa47e36 100644 --- a/src/lwtk/isInstanceOf.lua +++ b/src/lwtk/isInstanceOf.lua @@ -2,15 +2,26 @@ local lwtk = require"lwtk" local getSuperClass = lwtk.get.superClass -local function isInstanceOf(obj, T) - local mt = getmetatable(obj) - while mt do - if mt == T then - return true +--[[ + Determines if object is instance of the given class. + + Returns *true*, if *self* is an object that was created by invoking class *C* + or by invoking a subclass of *C*. + + Returns also *true* if *C* is a metatable of *self* or somewhere in the + metatable chain of *self*. +]] +local function isInstanceOf(self, C) + local c = getmetatable(self) + if c then + repeat + if c == C then + return true + end + c = getSuperClass[c] + until not c end - mt = getSuperClass[mt] - end - return false + return false end return isInstanceOf diff --git a/src/lwtk/layout.lua b/src/lwtk/layout.lua index 8fcacf9..9cf6a29 100644 --- a/src/lwtk/layout.lua +++ b/src/lwtk/layout.lua @@ -94,7 +94,8 @@ end local function collectOldFrames(widget, oldFrames) - for _, c in ipairs(widget) do + for i = 1, #widget do + local c = widget[i] oldFrames[c] = { c.x, c.y, c.w, c.h } c._isRelayouting = true collectOldFrames(c, oldFrames) diff --git a/src/lwtk/love/Application.lua b/src/lwtk/love/Application.lua index bf72793..71f4b4e 100644 --- a/src/lwtk/love/Application.lua +++ b/src/lwtk/love/Application.lua @@ -1,77 +1,28 @@ local lwtk = require"lwtk" -local getApp = lwtk.get.app +local getApp = lwtk.get.app +local keyNameMap = lwtk.love.keyNameMap -local Super = lwtk.MouseDispatcher(lwtk.Application) -local Application = lwtk.newClass("lwtk.love.Application", Super) +local Super = lwtk.MouseDispatcher(lwtk.Node(lwtk.Application)) -local keyNameMap = -{ - space = "Space", - up = "Up", - down = "Down", - right = "Right", - left = "Left", - home = "Home", - ["end"] = "End", - pageup = "Page_Up", - pagedown = "Page_Down", - insert = "Insert", - backspace = "Backspace", - tab = "Tab", - clear = "Clear", - ["return"] = "Return", - delete = "Delete", - escape = "Escape", - - kp0 = "KP_0", - kp1 = "KP_1", - kp2 = "KP_2", - kp3 = "KP_3", - kp4 = "KP_4", - kp5 = "KP_5", - kp6 = "KP_6", - kp7 = "KP_7", - kp8 = "KP_8", - kp9 = "KP_9", - kpenter = "KP_Enter", - ["kp+"] = "KP_Add", - ["kp-"] = "KP_Subtract", - ["kp/"] = "KP_Divide", - ["kp,"] = "KP_Separator", - ["kp."] = "KP_Separator", +--[[ + Application implementation for the [LÖVE](https://love2d.org/) 2D game engine. - f1 = "F1", - f2 = "F2", - f3 = "F3", - f4 = "F4", - f5 = "F5", - f6 = "F6", - f7 = "F7", - f8 = "F8", - f9 = "F9", - f10 = "F10", - f11 = "F11", - f12 = "F12", - f13 = "F13", - f14 = "F14", - f15 = "F15", - f16 = "F16", - f17 = "F17", - f18 = "F18", + Use lwtk.Application for runing standalone desktop applications. +]] +local Application = lwtk.newClass("lwtk.love.Application", Super) + +Application:declare( + "_implicitWindowFocus", + "_keyModState", + "modKeyToBit", + "mouseEntered", + "focusWindow", + "_handledKey" +) - rshift = "Shift_R", - lshift = "Shift_L", - rctrl = "Ctrl_R", - lctrl = "Ctrl_L", - ralt = "Alt_R", - lalt = "Alt_L", - rgui = "Super_R", - lgui = "Super_L", - capslock = "Caps_Lock", -} -function Application:new(initParams) +function Application.override:new(initParams) if not initParams then initParams = {} end @@ -98,7 +49,7 @@ end local setFocusWindow -function Application:update() +function Application.override:update() local driver = self.driver do local newWindows = driver.newWindows diff --git a/src/lwtk/love/DrawContext.lua b/src/lwtk/love/DrawContext.lua index d97cfa8..339a789 100644 --- a/src/lwtk/love/DrawContext.lua +++ b/src/lwtk/love/DrawContext.lua @@ -3,13 +3,18 @@ local lwtk = require"lwtk" local Super = lwtk.love.LayoutContext local DrawContext = lwtk.newClass("lwtk.love.DrawContext", Super) -function DrawContext:new(...) +DrawContext:declare( + "opacityStack", + "scissorStack" +) + +function DrawContext.override:new(...) Super.new(self, ...) self.opacityStack = {} self.scissorStack = {} end -function DrawContext:_reset() +function DrawContext.override:_reset() Super._reset() local opacityStack = self.opacityStack for k, v in pairs(opacityStack) do diff --git a/src/lwtk/love/Driver.lua b/src/lwtk/love/Driver.lua index 60a652c..36092d0 100644 --- a/src/lwtk/love/Driver.lua +++ b/src/lwtk/love/Driver.lua @@ -5,6 +5,15 @@ local View = lwtk.love.View local Driver = lwtk.newClass("lwtk.love.Driver") +Driver:declare( + "drawContext", + "layoutContext", + "newWindows", + "processFunc", + "nextProcessTime", + "hasViews" +) + function Driver:new(initParams) self.drawContext = lwtk.love.DrawContext() self.layoutContext = lwtk.love.LayoutContext() diff --git a/src/lwtk/love/LayoutContext.lua b/src/lwtk/love/LayoutContext.lua index f740582..d5f2629 100644 --- a/src/lwtk/love/LayoutContext.lua +++ b/src/lwtk/love/LayoutContext.lua @@ -4,6 +4,13 @@ local floor = math.floor local LayoutContext = lwtk.newClass("lwtk.love.LayoutContext") +LayoutContext:declare( + "fonts", + "font", + "fontHeight", + "fontAscent" +) + function LayoutContext:new() love.graphics.reset() self.fonts = {} diff --git a/src/lwtk/love/View.lua b/src/lwtk/love/View.lua index 4407bd2..da0ddfa 100644 --- a/src/lwtk/love/View.lua +++ b/src/lwtk/love/View.lua @@ -3,9 +3,16 @@ local lwtk = require"lwtk" local floor = math.floor local unpack = unpack or table.unpack +local getWindow = lwtk.WeakKeysTable() + local View = lwtk.newClass("lwtk.love.View") -local getWindow = lwtk.WeakKeysTable() +View:declare( + "x", "y", "w", "h", + "damagedArea", + "canvas", + "closed" +) function View:new(window, initParams) getWindow[self] = window diff --git a/src/lwtk/love/init.lua b/src/lwtk/love/init.lua index 9f68643..f559831 100644 --- a/src/lwtk/love/init.lua +++ b/src/lwtk/love/init.lua @@ -1,3 +1,6 @@ +--[[ + Modules for using *lwtk* with the [LÖVE](https://love2d.org/) 2D game engine. +]] local internal = {} diff --git a/src/lwtk/love/keyNameMap.lua b/src/lwtk/love/keyNameMap.lua new file mode 100644 index 0000000..5bf69ca --- /dev/null +++ b/src/lwtk/love/keyNameMap.lua @@ -0,0 +1,67 @@ +local keyNameMap = +{ + space = "Space", + up = "Up", + down = "Down", + right = "Right", + left = "Left", + home = "Home", + ["end"] = "End", + pageup = "Page_Up", + pagedown = "Page_Down", + insert = "Insert", + backspace = "Backspace", + tab = "Tab", + clear = "Clear", + ["return"] = "Return", + delete = "Delete", + escape = "Escape", + + kp0 = "KP_0", + kp1 = "KP_1", + kp2 = "KP_2", + kp3 = "KP_3", + kp4 = "KP_4", + kp5 = "KP_5", + kp6 = "KP_6", + kp7 = "KP_7", + kp8 = "KP_8", + kp9 = "KP_9", + kpenter = "KP_Enter", + ["kp+"] = "KP_Add", + ["kp-"] = "KP_Subtract", + ["kp/"] = "KP_Divide", + ["kp,"] = "KP_Separator", + ["kp."] = "KP_Separator", + + f1 = "F1", + f2 = "F2", + f3 = "F3", + f4 = "F4", + f5 = "F5", + f6 = "F6", + f7 = "F7", + f8 = "F8", + f9 = "F9", + f10 = "F10", + f11 = "F11", + f12 = "F12", + f13 = "F13", + f14 = "F14", + f15 = "F15", + f16 = "F16", + f17 = "F17", + f18 = "F18", + + rshift = "Shift_R", + lshift = "Shift_L", + rctrl = "Ctrl_R", + lctrl = "Ctrl_L", + ralt = "Alt_R", + lalt = "Alt_L", + rgui = "Super_R", + lgui = "Super_L", + capslock = "Caps_Lock", +} + +return keyNameMap diff --git a/src/lwtk/lpugl/CairoDrawContext.lua b/src/lwtk/lpugl/CairoDrawContext.lua index 2cdca79..14c148a 100644 --- a/src/lwtk/lpugl/CairoDrawContext.lua +++ b/src/lwtk/lpugl/CairoDrawContext.lua @@ -3,7 +3,11 @@ local lwtk = require"lwtk" local Super = lwtk.lpugl.CairoLayoutContext local CairoDrawContext = lwtk.newClass("lwtk.lpugl.CairoDrawContext", Super) -function CairoDrawContext:new(...) +CairoDrawContext:declare( + "opacityStack" +) + +function CairoDrawContext.override:new(...) Super.new(self, ...) self.opacityStack = {} end diff --git a/src/lwtk/lpugl/CairoLayoutContext.lua b/src/lwtk/lpugl/CairoLayoutContext.lua index 1c67927..a75091d 100644 --- a/src/lwtk/lpugl/CairoLayoutContext.lua +++ b/src/lwtk/lpugl/CairoLayoutContext.lua @@ -4,6 +4,12 @@ local floor = math.floor local CairoLayoutContext = lwtk.newClass("lwtk.lpugl.CairoLayoutContext") +CairoLayoutContext:declare( + "ctx", + "platform", + "adjustFamilyName" +) + function CairoLayoutContext:new(cairoCtx, platform) self.ctx = assert(cairoCtx) self.platform = assert(platform) diff --git a/src/lwtk/lpugl/Driver.lua b/src/lwtk/lpugl/Driver.lua index 59cc238..8b5fe73 100644 --- a/src/lwtk/lpugl/Driver.lua +++ b/src/lwtk/lpugl/Driver.lua @@ -15,6 +15,12 @@ local extract = lwtk.extract local Driver = lwtk.newClass("lwtk.lpugl.Driver") +Driver:declare( + "world", + "layoutContext", + "drawContext" +) + function Driver:new(initParams) self.world = extract(initParams, "world") if not self.world then diff --git a/src/lwtk/lpugl/init.lua b/src/lwtk/lpugl/init.lua index e86d832..3104382 100644 --- a/src/lwtk/lpugl/init.lua +++ b/src/lwtk/lpugl/init.lua @@ -1,3 +1,7 @@ +--[[ + Modules for using *lwtk* on top of [LPugl](https://github.com/osch/lua-lpugl#lpugl), + a minimal Lua-API for building GUIs for Linux, Windows or macOS. +]] local internal = {} diff --git a/src/lwtk/newClass.lua b/src/lwtk/newClass.lua index 32cd946..173680b 100644 --- a/src/lwtk/newClass.lua +++ b/src/lwtk/newClass.lua @@ -1,13 +1,28 @@ local lwtk = require"lwtk" -local type = lwtk.type -local function newClass(className, baseClass, ...) +local ltype = lwtk.type + +--[[ + Creates new class object. A class object has lwtk.Class as metatable + and lwtk.type() evaluates to `"lwtk.Class"`. + + * *className* - string value + * *superClass* - optional class object, if not given, lwtk.Object + is taken as superclass. + * *...* - optional further arguments that are reached over + to [lwtk.Object.newSubClass()](../lwtk/Object.md#.newSubClass). + + See [lwtk.Class Usage](../../Class.md) for detailed documentation + and usage examples. +]] +local function newClass(className, superClass, ...) assert(type(className) == "string", "arg 1: exptected class name string") - if baseClass then - assert(type(baseClass) == "lwtk.Class", "arg 2 must be of type lwtk.Class") + assert(not className:match("[()<>]"), "arg 1: invalid class name string") + if superClass then + assert(ltype(superClass) == "lwtk.Class", "arg 2 must be of type lwtk.Class") end - local b = baseClass or lwtk.Object - local c = b.newSubClass(className, b, ...) + local b = superClass or lwtk.Object + local c = b:newSubClass(className, ...) return c end diff --git a/src/lwtk/newMeta.lua b/src/lwtk/newMeta.lua new file mode 100644 index 0000000..22b1717 --- /dev/null +++ b/src/lwtk/newMeta.lua @@ -0,0 +1,21 @@ +local lwtk = require"lwtk" + +local Meta = lwtk.Meta +local fallbackToString = Meta.fallbackToString + +--[[ + Creates new meta object. A meta object has lwtk.Meta as metatable + and lwtk.type() evaluates to `"lwtk.Meta"`. + + See [lwtk.Meta Usage](../../Meta.md) for detailed documentation + and usage examples. +]] +local function newMeta(name) + local meta = { + __name = name, + __tostring = fallbackToString + } + return setmetatable(meta, Meta) +end + +return newMeta diff --git a/src/lwtk/newMixin.lua b/src/lwtk/newMixin.lua index 12eff98..59a7062 100644 --- a/src/lwtk/newMixin.lua +++ b/src/lwtk/newMixin.lua @@ -1,59 +1,166 @@ local lwtk = require("lwtk") -local type = lwtk.type -local caches = lwtk.WeakKeysTable() -local mixins = lwtk.WeakKeysTable() -local unpack = table.unpack or unpack +local unpack = table.unpack or unpack +local format = string.format +local ltype = lwtk.type +local getSuperClass = lwtk.get.superClass +local getObjectMeta = lwtk.get.objectMeta +local getMixinBase = lwtk.get.mixinBase + +local caches = lwtk.WeakKeysTable() +local mixins = lwtk.WeakKeysTable() local Mixin = lwtk.Mixin +local cacheMeta = { + __mode = "v" +} + +--[[ + Creates new mixin object. A mixin object has lwtk.Mixin as metatable + and lwtk.type() evaluates to `"lwtk.Mixin"`. + + See [lwtk.Mixin Usage](../../Mixin.md) for detailed documentation + and usage examples. +]] local function newMixin(name, ...) - assert(type(name) == "string", "arg 1 must be string") + assert(ltype(name) == "string", "arg 1 must be string") local mixin = { name = name } local nargs = select("#", ...) for i = 1, nargs do local arg = select(i, ...) - if type(arg) ~= "lwtk.Mixin" then + if ltype(arg) ~= "lwtk.Mixin" then break end mixin[i] = arg end mixin.cargs = { nargs = nargs - #mixin, select(#mixin + 1, ...) } - local self = setmetatable({}, Mixin) - mixins[self] = mixin - caches[self] = setmetatable({}, { __mode = "v" }) - return self + local m = setmetatable({}, Mixin) + m.__name = name + mixins[m] = mixin + caches[m] = setmetatable({}, cacheMeta) + return m end -function Mixin.__index:isInstanceOf(mt) +local method = {} + +function method:isInstanceOf(mt) return lwtk.isInstanceOf(self, mt) end +function method:declare(...) + local m = mixins[self].declare + if not m then + m = {} + mixins[self].declare = m + end + local n = #m + for i = 1, select("#", ...) do + m[n + i] = select(i, ...) + end +end + +function Mixin:__index(k) + local v = method[k] + if v ~= nil then + return v + elseif k == "extra" or k == "override" or k == "implement" then + v = {} + self[k] = v + return v + else + v = self.override[k] + if v == nil then + v = self.implement[k] + end + return v + end +end + function Mixin:__tostring() - return "lwtk.Mixin("..mixins[self].name..")" + return "lwtk.Mixin<"..mixins[self].name..">" end function Mixin:__call(baseClass, ...) - assert(type(baseClass) == "lwtk.Class", "arg must be of type lwtk.Class, but is "..type(baseClass)) + if baseClass ~= nil then + assert(ltype(baseClass) == "lwtk.Class", "arg must be of type lwtk.Class, but is "..ltype(baseClass)) + else + baseClass = lwtk.Object + end + local mixin = mixins[self] + for i = #mixin, 1, -1 do + baseClass = mixin[i](baseClass) + end local cache = caches[self] local class = cache[baseClass] if not class then - local mixin = mixins[self] - for i = #mixin, 1, -1 do - baseClass = mixin[i](baseClass) + do + local s = baseClass + while s do + if getMixinBase[s] == self then + lwtk.errorf("Mixin %q is already involved in superclass %q", mixin.name, baseClass:getClassPath()) + end + s = getSuperClass[s] + end end local cargs = mixin.cargs - class = baseClass.newSubClass(mixin.name, baseClass, unpack(cargs, 1, cargs.nargs)) + local nargs = cargs.nargs + local lastArg = (nargs > 0) and cargs[nargs] + local initClass + if lastArg and ltype(lastArg) == "function" then + nargs = nargs - 1 + initClass = lastArg + end + local baseName = (baseClass == lwtk.Object) and "" or baseClass.__name + class = baseClass:newSubClass(format("%s(%s)", mixin.name, baseName), unpack(cargs, 1, nargs)) + local declare = mixin.declare + if declare then + for i = 1, #declare do + local var = declare[i] + if var:match("^[a-zA-Z_][a-zA-Z_0-9]*$") then + local objMeta = getObjectMeta[class] + if objMeta[var] == nil then + class[var] = false + else + local c = class + local m = objMeta + while true do + if m.declared[var] then + lwtk.errorf("member %q from mixin %q is already declared in superclass %q in class path %s", var, mixin.name, m.__name, class:getClassPath()) + end + c = getSuperClass[c] + m = getObjectMeta[c] + end + end + else + lwtk.errorf("invalid member name %q in Mixin %s", var, mixin.name) + end + end + end for k, v in pairs(self) do - if k ~= "initClass" and k ~= "extra" then + if k ~= "extra" and k ~= "override" and k ~= "implement" and k ~= "__name" then class[k] = v end end - local initClass = self.initClass + local myOverride = self.override + if myOverride then + local classOverride = class.override + for k, v in pairs(myOverride) do + classOverride[k] = v + end + end + local myImplement = self.implement + if myImplement then + local classImplement = class.implement + for k, v in pairs(myImplement) do + classImplement[k] = v + end + end if initClass then initClass(class, baseClass) end + getMixinBase[class] = self cache[baseClass] = class end return class diff --git a/src/lwtk/type.lua b/src/lwtk/type.lua index 96f257f..5023528 100644 --- a/src/lwtk/type.lua +++ b/src/lwtk/type.lua @@ -1,5 +1,18 @@ local luaType = type +--[[ + Returns the type name. + + * If *arg* is of type *"table"* or *"userdata"* and has a metatable of + type *"table"* with a field *"__name"*, than the value of this field + is returned. + + * If *arg* is of type *"table"* or *"userdata"* and has a metatable of + type *"string"*, than this string value is returned. + + * In all other cases this functions returns the same value, as the + builtin Lua function *type()* would return. +]] local function type(arg) local t = luaType(arg) if t == "table" or t == "userdata" then diff --git a/src/lwtk/undef.lua b/src/lwtk/undef.lua new file mode 100644 index 0000000..6d556b3 --- /dev/null +++ b/src/lwtk/undef.lua @@ -0,0 +1,24 @@ +local lwtk = require"lwtk" + +local get = lwtk.get + +local function undef(class) + if type(class) == "table" then + local objectMeta = get.objectMeta[class] + for k, v in pairs(get) do + v[class] = nil + if objectMeta then + v[objectMeta] = nil + end + end + if objectMeta then + for k, v in pairs(objectMeta) do + objectMeta[k] = nil + end + end + for k, v in pairs(class) do + class[k] = nil + end + end +end +return undef diff --git a/src/mkdoc/README.md b/src/mkdoc/README.md new file mode 100644 index 0000000..8551c4e --- /dev/null +++ b/src/mkdoc/README.md @@ -0,0 +1,18 @@ +Requires: + +- lpeglabel: + https://luarocks.org/modules/sergio-medeiros/lpeglabel + https://github.com/sqmedeiros/lpeglabel + +- lpath: + https://luarocks.org/modules/xavier-wang/lpath + + +Contains: + +- modified pprint, original code: + https://github.com/jagt/pprint.lua + +- modified lua-parser, original code: + https://github.com/andremm/lua-parser + diff --git a/src/mkdoc/comments.lua b/src/mkdoc/comments.lua new file mode 100644 index 0000000..fd5483c --- /dev/null +++ b/src/mkdoc/comments.lua @@ -0,0 +1,289 @@ +local lpeg = require "lpeglabel" -- https://luarocks.org/modules/sergio-medeiros/lpeglabel +local re = require "relabel" -- https://luarocks.org/modules/sergio-medeiros/lpeglabel + +local byte = string.byte + +lpeg.locale(lpeg) + +local P, S, V = lpeg.P, lpeg.S, lpeg.V +local C, Carg, Cb, Cc = lpeg.C, lpeg.Carg, lpeg.Cb, lpeg.Cc +local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg.Cf, lpeg.Cg, lpeg.Cmt, lpeg.Cp, lpeg.Cs, lpeg.Ct +local Lc, T = lpeg.Lc, lpeg.T + +local alpha, digit, alnum = lpeg.alpha, lpeg.digit, lpeg.alnum +local xdigit = lpeg.xdigit +local space = lpeg.space + +local comments = {} +do + local globalPrint = print + local print = globalPrint + local list + local startPosMap + local endPosMap + local subject + + function comments.init(fileContent, myPrint) + print = myPrint or globalPrint + list = {} + startPosMap = {} + endPosMap = {} + subject = fileContent + end + + local LF = byte("\n") + + local function beginOfLine(pos) + for i = pos-1, 2, -1 do + if byte(subject, i) == LF then + return i+1 + end + end + return 1 + end + + local function column(pos) + return pos - beginOfLine(pos) + 1 + end + + function comments.add(pos1, pos2, end_pos1, end_pos2, comment) + local entry = { pos1 = pos1, + pos2 = pos2, + end_pos1 = end_pos1, + end_pos2 = end_pos2, + comment = comment } + list[#list + 1] = entry + assert(not startPosMap[pos1]) + assert(not endPosMap[end_pos2]) + startPosMap[pos1] = entry + endPosMap[end_pos2] = entry + print("PPP", pos1, pos2, end_pos1, end_pos2, comment) + end + + function comments.sort() + table.sort(list, function(a,b) return a.pos1 < b.pos1 end) + for i = 1, #list do + list[i].i = i + end + end + + local notLfSpace = -P"\n" * space + local singleCmt = P"--" * -(P"[" * P"="^0 * P"[") + local exclSingleCmt = (notLfSpace^0 * P"\n" * notLfSpace^0)^1 * singleCmt + local exclCmt = (notLfSpace^0 * P"\n" * notLfSpace^0) + local blankLine = (notLfSpace^0 * P"\n" * notLfSpace^0)^2 + + local function isExclCmt(entry) + if entry.pos1 == 1 then + return true + else + local p = entry.pos1 + if entry.i > 1 then + local pe = list[entry.i - 1] + if pe.end_pos2 + 1 == p then + p = pe.end_pos1 + 1 + end + end + return lpeg.match(exclCmt, subject, p) + end + end + + local function isSingleLineCmt(entry) + return lpeg.match(singleCmt, subject, entry.pos2) + end + local function isExclSingleLineCmt(entry) + if entry.pos1 == 1 then + return lpeg.match(singleCmt, subject, entry.pos2) + else + local p = entry.pos1 + if entry.i > 1 then + local pe = list[entry.i - 1] + if pe.end_pos2 + 1 == p then + p = pe.end_pos1 + 1 + end + end + return lpeg.match(exclSingleCmt, subject, p) + end + end + + local function isBlankLineBefore(entry) + local p = entry.pos1 + local pe = list[entry.i - 1] + if pe and pe.end_pos2 + 1 == p then + p = pe.end_pos1 + 1 + end + return lpeg.match(blankLine, subject, p) + end + + local function isBlankLineAfter(entry) + local rslt = lpeg.match(blankLine, subject, entry.end_pos1 + 1) + return rslt + end + + local singleLineCmtBegin = P"--" * P"-"^0 * C(P(1)^0) + + local function removeSingleLineCmtBegin(entry) + return lpeg.match(singleLineCmtBegin, entry.comment) + end + + local multiLineCmtBegin = P"--[" * C(P"="^0) * "[" * C(space^0) * Cp() * C(P(1)^0) + + local function removeMultiLineCmt(entry) + local eq, beginSpace, pos, rest = lpeg.match(multiLineCmtBegin, entry.comment) + local indent + if beginSpace:match("\n") then + indent = lpeg.match(((P"\n" * C(notLfSpace^0) * -P(1)) + P(1))^1, + beginSpace) + else + local col = column(entry.pos2 + pos - 1) + print("###################", require"inspect"{entry, pos, col}) + indent = string.rep(" ", col - 1) + end + local rest2 = rest:gsub("\n"..indent, "\n") + + print("#########", require"inspect"{rest, rest2, indent}) + local cmtEnd = space^0 * P("]"..eq.."]") + return lpeg.match(C((-cmtEnd * P(1))^0) * cmtEnd * -P(1), rest2) + end + + function comments.getBefore(p) + local entry = endPosMap[p - 1] + if entry and not isBlankLineAfter(entry) then + if entry then + if isSingleLineCmt(entry) then + if isExclSingleLineCmt(entry) then + local col = column(entry.pos2) + if col == column(p) then + local i = entry.i + local e = entry + while i-1 > 0 do + local pe = list[i-1] + if pe.end_pos2 + 1 == e.pos1 and isSingleLineCmt(pe) + and not isBlankLineBefore(e) and column(pe.pos2) == col + then + i = i - 1 + e = pe + else + break + end + end + if isExclSingleLineCmt(list[i]) then + local b = {} + for j = i, entry.i do + local m = removeSingleLineCmtBegin(list[j]) + if m then + b[#b + 1] = m + end + end + return table.concat(b, "\n") + else + --local l1 = re.calcline(subject, list[i].pos2) + --local l2 = re.calcline(subject, entry.end_pos1) + --lwtk.errorf("Ambiguous multiline comment from line %d to line %d", l1, l2) + end + end + end + else + if isExclCmt(entry) then + return removeMultiLineCmt(entry) + end + end + end + end + end + + function comments.getAfter(p1, p2) + local entry = startPosMap[p1+1] + if not entry and p2 then + for p = p1+2, p2-1 do + entry = startPosMap[p] + if entry then + break + end + end + end + if entry then + for i = p1+1, entry.pos2-1 do + if byte(subject, i) == LF then + return + end + end + if isSingleLineCmt(entry) then + local col = column(entry.pos2) + local i = entry.i + local e = entry + while i+1 <= #list do + local ne = list[i+1] + if e.end_pos2 + 1 == ne.pos1 and isExclSingleLineCmt(ne) and col == column(ne.pos2) then + i = i + 1 + e = ne + else + break + end + end + local b = {} + for j = entry.i, i do + local m = removeSingleLineCmtBegin(list[j]) + if m then + b[#b + 1] = m + end + end + return table.concat(b, "\n") + else + return removeMultiLineCmt(entry) + end + end + end + + local endSpace = space^0 * -P(1) + local dotSpace = P"." * space + local shortDocPattern = space^0 * C(((-dotSpace - blankLine - endSpace) * P(1))^0 * P"."^-1) + + function comments.getShortDoc(docString) + if docString then + return lpeg.match(shortDocPattern, docString):gsub("%s+", " ") + end + end + + local argListBeginPattern = Cp() * P"@function(" + local argListPattern = (-argListBeginPattern * P(1))^0 * argListBeginPattern * Cp() * (-P")" * P(1))^0 * Cp() * ")" * Cp() + local argListPattern0 = P"\n" * Cp() * notLfSpace^0 * P(-1) + local argListPattern1 = (-argListPattern0 * P(1))^0 * argListPattern0 + + Cp() * notLfSpace^0 * P(-1) + local argListPattern2 = notLfSpace^0 * (P"\n" + P(-1)) * Cp() + + function comments.stripArgListDoc(docString) + if docString then + local p1, p2, p3, p4 = lpeg.match(argListPattern, docString) + local rsltDoc + local argListString + if p1 then + if p1 > 1 or p4 <= #docString then + local d1, d2 = docString:sub(1,p1-1), docString:sub(p4,-1) + local s1 = lpeg.match(argListPattern1, d1) + local s2 = lpeg.match(argListPattern2, d2) + if s1 and s2 then + d1 = d1:sub(1, s1-1) + d2 = d2:sub(s2,-1) + end + rsltDoc = (d1..d2):gsub("%s+$", "") + end + argListString = docString:sub(p2, p3-1):gsub("%s",""):gsub(",", ", ") + else + rsltDoc = docString + end + return rsltDoc, argListString + end + end + + function comments.argListDocToMethod(argListDoc) + if argListDoc:match("^self,") then + return argListDoc:gsub("^self,%s*",""), true + elseif argListDoc:match("^self$") then + return "", true + else + return argListDoc + end + end +end +return comments diff --git a/src/mkdoc/lua-parser/LICENSE b/src/mkdoc/lua-parser/LICENSE new file mode 100644 index 0000000..1e1f6a6 --- /dev/null +++ b/src/mkdoc/lua-parser/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Andre Murbach Maidl + +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. + +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. diff --git a/src/mkdoc/lua-parser/parser.lua b/src/mkdoc/lua-parser/parser.lua new file mode 100644 index 0000000..0fe8660 --- /dev/null +++ b/src/mkdoc/lua-parser/parser.lua @@ -0,0 +1,489 @@ +--[[ +This module implements a parser for Lua 5.3 with LPeg, +and generates an Abstract Syntax Tree that is similar to the one generated by Metalua. +For more information about Metalua, please, visit: +https://github.com/fab13n/metalua-parser + +block: { stat* } + +stat: + `Do{ stat* } + | `Set{ {lhs+} {expr+} } -- lhs1, lhs2... = e1, e2... + | `While{ expr block } -- while e do b end + | `Repeat{ block expr } -- repeat b until e + | `If{ (expr block)+ block? } -- if e1 then b1 [elseif e2 then b2] ... [else bn] end + | `Fornum{ ident expr expr expr? block } -- for ident = e, e[, e] do b end + | `Forin{ {ident+} {expr+} block } -- for i1, i2... in e1, e2... do b end + | `Local{ {ident+} {expr+}? } -- local i1, i2... = e1, e2... + | `Localrec{ ident expr } -- only used for 'local function' + | `Goto{ } -- goto str + | `Label{ } -- ::str:: + | `Return{ } -- return e1, e2... + | `Break -- break + | apply + +expr: + `Nil + | `Dots + | `Boolean{ } + | `Number{ } + | `String{ } + | `Function{ { `Id{ }* `Dots? } block } + | `Table{ ( `Pair{ expr expr } | expr )* } + | `Op{ opid expr expr? } + | `Paren{ expr } -- significant to cut multiple values returns + | apply + | lhs + +apply: + `Call{ expr expr* } + | `Invoke{ expr `String{ } expr* } + +lhs: `Id{ } | `Index{ expr expr } + +opid: -- includes additional operators from Lua 5.3 and all relational operators + 'add' | 'sub' | 'mul' | 'div' + | 'idiv' | 'mod' | 'pow' | 'concat' + | 'band' | 'bor' | 'bxor' | 'shl' | 'shr' + | 'eq' | 'ne' | 'lt' | 'gt' | 'le' | 'ge' + | 'and' | 'or' | 'unm' | 'len' | 'bnot' | 'not' +]] + +local lpeg = require "lpeglabel" + +lpeg.locale(lpeg) + +local P, S, V = lpeg.P, lpeg.S, lpeg.V +local C, Carg, Cb, Cc = lpeg.C, lpeg.Carg, lpeg.Cb, lpeg.Cc +local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg.Cf, lpeg.Cg, lpeg.Cmt, lpeg.Cp, lpeg.Cs, lpeg.Ct +local Lc, T = lpeg.Lc, lpeg.T + +local alpha, digit, alnum = lpeg.alpha, lpeg.digit, lpeg.alnum +local xdigit = lpeg.xdigit +local space = lpeg.space + +local commentCollector + +-- error message auxiliary functions + +local labels = { + { "ErrExtra", "unexpected character(s), expected EOF" }, + { "ErrInvalidStat", "unexpected token, invalid start of statement" }, + + { "ErrEndIf", "expected 'end' to close the if statement" }, + { "ErrExprIf", "expected a condition after 'if'" }, + { "ErrThenIf", "expected 'then' after the condition" }, + { "ErrExprEIf", "expected a condition after 'elseif'" }, + { "ErrThenEIf", "expected 'then' after the condition" }, + + { "ErrEndDo", "expected 'end' to close the do block" }, + { "ErrExprWhile", "expected a condition after 'while'" }, + { "ErrDoWhile", "expected 'do' after the condition" }, + { "ErrEndWhile", "expected 'end' to close the while loop" }, + { "ErrUntilRep", "expected 'until' at the end of the repeat loop" }, + { "ErrExprRep", "expected a conditions after 'until'" }, + + { "ErrForRange", "expected a numeric or generic range after 'for'" }, + { "ErrEndFor", "expected 'end' to close the for loop" }, + { "ErrExprFor1", "expected a starting expression for the numeric range" }, + { "ErrCommaFor", "expected ',' to split the start and end of the range" }, + { "ErrExprFor2", "expected an ending expression for the numeric range" }, + { "ErrExprFor3", "expected a step expression for the numeric range after ','" }, + { "ErrInFor", "expected '=' or 'in' after the variable(s)" }, + { "ErrEListFor", "expected one or more expressions after 'in'" }, + { "ErrDoFor", "expected 'do' after the range of the for loop" }, + + { "ErrDefLocal", "expected a function definition or assignment after local" }, + { "ErrNameLFunc", "expected a function name after 'function'" }, + { "ErrEListLAssign", "expected one or more expressions after '='" }, + { "ErrEListAssign", "expected one or more expressions after '='" }, + + { "ErrFuncName", "expected a function name after 'function'" }, + { "ErrNameFunc1", "expected a function name after '.'" }, + { "ErrNameFunc2", "expected a method name after ':'" }, + { "ErrOParenPList", "expected '(' for the parameter list" }, + { "ErrCParenPList", "expected ')' to close the parameter list" }, + { "ErrEndFunc", "expected 'end' to close the function body" }, + { "ErrParList", "expected a variable name or '...' after ','" }, + + { "ErrLabel", "expected a label name after '::'" }, + { "ErrCloseLabel", "expected '::' after the label" }, + { "ErrGoto", "expected a label after 'goto'" }, + { "ErrRetList", "expected an expression after ',' in the return statement" }, + + { "ErrVarList", "expected a variable name after ','" }, + { "ErrExprList", "expected an expression after ','" }, + + { "ErrOrExpr", "expected an expression after 'or'" }, + { "ErrAndExpr", "expected an expression after 'and'" }, + { "ErrRelExpr", "expected an expression after the relational operator" }, + { "ErrBOrExpr", "expected an expression after '|'" }, + { "ErrBXorExpr", "expected an expression after '~'" }, + { "ErrBAndExpr", "expected an expression after '&'" }, + { "ErrShiftExpr", "expected an expression after the bit shift" }, + { "ErrConcatExpr", "expected an expression after '..'" }, + { "ErrAddExpr", "expected an expression after the additive operator" }, + { "ErrMulExpr", "expected an expression after the multiplicative operator" }, + { "ErrUnaryExpr", "expected an expression after the unary operator" }, + { "ErrPowExpr", "expected an expression after '^'" }, + + { "ErrExprParen", "expected an expression after '('" }, + { "ErrCParenExpr", "expected ')' to close the expression" }, + { "ErrNameIndex", "expected a field name after '.'" }, + { "ErrExprIndex", "expected an expression after '['" }, + { "ErrCBracketIndex", "expected ']' to close the indexing expression" }, + { "ErrNameMeth", "expected a method name after ':'" }, + { "ErrMethArgs", "expected some arguments for the method call (or '()')" }, + + { "ErrArgList", "expected an expression after ',' in the argument list" }, + { "ErrCParenArgs", "expected ')' to close the argument list" }, + + { "ErrCBraceTable", "expected '}' to close the table constructor" }, + { "ErrEqField", "expected '=' after the table key" }, + { "ErrExprField", "expected an expression after '='" }, + { "ErrExprFKey", "expected an expression after '[' for the table key" }, + { "ErrCBracketFKey", "expected ']' to close the table key" }, + + { "ErrDigitHex", "expected one or more hexadecimal digits after '0x'" }, + { "ErrDigitDeci", "expected one or more digits after the decimal point" }, + { "ErrDigitExpo", "expected one or more digits for the exponent" }, + + { "ErrQuote", "unclosed string" }, + { "ErrHexEsc", "expected exactly two hexadecimal digits after '\\x'" }, + { "ErrOBraceUEsc", "expected '{' after '\\u'" }, + { "ErrDigitUEsc", "expected one or more hexadecimal digits for the UTF-8 code point" }, + { "ErrCBraceUEsc", "expected '}' after the code point" }, + { "ErrEscSeq", "invalid escape sequence" }, + { "ErrCloseLStr", "unclosed long string" }, +} + +local function throw(label) + label = "Err" .. label + for i, labelinfo in ipairs(labels) do + if labelinfo[1] == label then + return T(i) + end + end + + error("Label not found: " .. label) +end + +local function expect (patt, label) + return patt + throw(label) +end + + +-- regular combinators and auxiliary functions + +local function kw (str) + return P(str) * -V"IdRest" +end + +local function dec(n) + return n - 1 +end + +local function tagC (tag, patt) + return Ct(Cg(Cp(), "pos") * Cg(Cc(tag), "tag") * patt * Cg(Cp() / dec, "end_pos")) +end + +local function unaryOp (op, e) + return { tag = "Op", pos = e.pos, end_pos = e.end_pos, [1] = op, [2] = e } +end + +local function binaryOp (e1, op, e2) + if not op then + return e1 + else + return { tag = "Op", pos = e1.pos, end_pos = e2.end_pos, [1] = op, [2] = e1, [3] = e2 } + end +end + +local function sepBy (patt, sep, label) + if label then + return patt * Cg(V"Skip" * sep * V"Skip" * expect(patt, label))^0 + else + return patt * Cg(V"Skip" * sep * V"Skip" * patt)^0 + end +end + +local function chainOp (patt, sep, label) + return Cf(sepBy(patt, sep, label), binaryOp) +end + +local function tagDo (block) + block.tag = "Do" + return block +end + +local function fixFuncStat (func) + if func[1].is_method then table.insert(func[2][1], 1, { tag = "Id", [1] = "self" }) end + func[1] = {func[1]} + func[2] = {func[2]} + return func +end + +local function addDots (params, dots) + if dots then table.insert(params, dots) end + return params +end + +local function insertIndex (t, index) + return { tag = "Index", pos = t.pos, end_pos = index.end_pos, [1] = t, [2] = index } +end + +local function markMethod(t, method) + if method then + return { tag = "Index", pos = t.pos, end_pos = method.end_pos, is_method = true, [1] = t, [2] = method } + end + return t +end + +local function makeIndexOrCall (t1, t2) + if not t2 then return t1 end + if t2.tag == "Call" or t2.tag == "Invoke" then + local t = { tag = t2.tag, pos = t1.pos, end_pos = t2.end_pos, [1] = t1 } + for k, v in ipairs(t2) do + table.insert(t, v) + end + return t + end + return { tag = "Index", pos = t1.pos, end_pos = t2.end_pos, [1] = t1, [2] = t2[1] } +end + +-- grammar +local G = { V"Lua", + Lua = V"Shebang"^-1 * V"Skip" * V"Block" * expect(P(-1), "Extra"); + Shebang = P"#!" * (P(1) - P"\n")^0; + + Block = tagC("Block", V"Stat"^0 * V"RetStat"^-1); + Stat = V"IfStat" + V"DoStat" + V"WhileStat" + V"RepeatStat" + V"ForStat" + + V"LocalStat" + V"FuncStat" + V"BreakStat" + V"LabelStat" + V"GoToStat" + + V"FuncCall" * V"Skip" + V"Assignment" + P(";") * V"Skip" + -V"BlockEnd" * throw("InvalidStat"); + BlockEnd = P"return" + "end" + "elseif" + "else" + "until" + -1; + + IfStat = tagC("If", V"IfPart" * V"ElseIfPart"^0 * V"ElsePart"^-1 * expect(kw("end") * V"Skip", "EndIf")); + IfPart = kw("if") * V"Skip" * expect(V"Expr", "ExprIf") * V"Skip" * expect(kw("then") * V"Skip", "ThenIf") * V"Block"; + ElseIfPart = kw("elseif") * V"Skip" * expect(V"Expr", "ExprEIf") * V"Skip" * expect(kw("then") * V"Skip", "ThenEIf") * V"Block"; + ElsePart = kw("else") * V"Skip" * V"Block"; + + DoStat = kw("do") * V"Skip" * V"Block" * expect(kw("end") * V"Skip", "EndDo") / tagDo; + WhileStat = tagC("While", kw("while") * V"Skip" * expect(V"Expr", "ExprWhile") * V"Skip" * V"WhileBody"); + WhileBody = expect(kw("do") * V"Skip", "DoWhile") * V"Block" * expect(kw("end") * V"Skip", "EndWhile"); + RepeatStat = tagC("Repeat", kw("repeat") * V"Skip" * V"Block" * expect(kw("until") * V"Skip", "UntilRep") * expect(V"Expr", "ExprRep")) * V"Skip" ; + + ForStat = kw("for") * V"Skip" * expect(V"ForNum" + V"ForIn", "ForRange") * expect(kw("end") * V"Skip", "EndFor"); + ForNum = tagC("Fornum", V"Id" * V"Skip" * P("=") * V"Skip" * V"NumRange" * V"ForBody"); + NumRange = expect(V"Expr", "ExprFor1") * V"Skip" * expect(P(","), "CommaFor") * V"Skip" * expect(V"Expr", "ExprFor2") * V"Skip" + * (P(",") * V"Skip" * expect(V"Expr", "ExprFor3"))^-1 * V"Skip"; + ForIn = tagC("Forin", V"NameList" * expect(kw("in") * V"Skip", "InFor") * expect(V"ExprList", "EListFor") * V"Skip" * V"ForBody"); + ForBody = expect(kw("do") * V"Skip", "DoFor") * V"Block"; + +-- LocalStat = kw("local") * V"Skip" * expect(V"LocalFunc" + V"LocalAssign", "DefLocal"); +-- LocalFunc = tagC("Localrec", kw("function") * V"Skip" * expect(V"Id", "NameLFunc") * V"Skip" * V"FuncBody") / fixFuncStat * V"Skip"; +-- LocalAssign = tagC("Local", V"NameList" * (P("=") * V"Skip" * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) * V"Skip"; + + LocalStat = V"LocalFunc" + V"LocalAssign" + kw("local") * V"Skip" * throw ("DefLocal"); + LocalFunc = tagC("Localrec", kw("local") * V"Skip" * kw("function") * V"Skip" * expect(V"Id", "NameLFunc") * V"Skip" * V"FuncBody") / fixFuncStat * V"Skip"; + LocalAssign = tagC("Local", kw("local") * V"Skip" * V"NameList" * (P("=") * V"Skip" * expect(V"ExprList", "EListLAssign") + Ct(Cc()))) * V"Skip"; + + Assignment = tagC("Set", V"VarList" * P("=") * V"Skip" * expect(V"ExprList", "EListAssign")) * V"Skip"; + + FuncStat = tagC("Set", kw("function") * V"Skip" * expect(V"FuncName", "FuncName") * V"FuncBody") / fixFuncStat * V"Skip"; + FuncName = Cf(V"Id" * (V"Skip" * P(".") * V"Skip" * expect(V"StrId", "NameFunc1") * V"Skip")^0, insertIndex) * V"Skip" + * (P(":") * V"Skip" * expect(V"StrId", "NameFunc2") * V"Skip")^-1 / markMethod; + FuncBody = tagC("Function", V"FuncParams" * V"Block" * expect(kw("end"), "EndFunc")); + FuncParams = expect(P("(") * V"Skip", "OParenPList") * V"ParList" * expect(P(")") * V"Skip", "CParenPList"); + ParList = V"NameList" * (P(",") * V"Skip" * expect(tagC("Dots", P("...") * V"Skip"), "ParList"))^-1 / addDots + + Ct(tagC("Dots", P("...") * V"Skip")) + + Ct(Cc()); -- Cc({}) generates a bug since the {} would be shared across parses + + LabelStat = tagC("Label", P("::") * V"Skip" * expect(V"Name", "Label") * V"Skip" * expect(P("::") * V"Skip", "CloseLabel")); + GoToStat = tagC("Goto", kw("goto") * V"Skip" * expect(V"Name", "Goto") * V"Skip"); + BreakStat = tagC("Break", kw("break") * V"Skip"); + RetStat = tagC("Return", kw("return") * (V"Skip" * sepBy(V"Expr", P(","), "RetList"))^-1 * (V"Skip" * P(";"))^-1) * V"Skip"; + + NameList = tagC("NameList", sepBy(V"Id", P(","))) * V"Skip"; + VarList = tagC("VarList", sepBy(V"VarExpr", P(","), "VarList")) * V"Skip"; + ExprList = tagC("ExpList", sepBy(V"Expr", P(","), "ExprList")); + + Expr = V"OrExpr"; + OrExpr = chainOp(V"AndExpr", V"OrOp", "OrExpr"); + AndExpr = chainOp(V"RelExpr", V"AndOp", "AndExpr"); + RelExpr = chainOp(V"BOrExpr", V"RelOp", "RelExpr"); + BOrExpr = chainOp(V"BXorExpr", V"BOrOp", "BOrExpr"); + BXorExpr = chainOp(V"BAndExpr", V"BXorOp", "BXorExpr"); + BAndExpr = chainOp(V"ShiftExpr", V"BAndOp", "BAndExpr"); + ShiftExpr = chainOp(V"ConcatExpr", V"ShiftOp", "ShiftExpr"); + ConcatExpr = V"AddExpr" * (V"Skip" * V"ConcatOp" * V"Skip" * expect(V"ConcatExpr", "ConcatExpr"))^-1 / binaryOp; + AddExpr = chainOp(V"MulExpr", V"AddOp", "AddExpr"); + MulExpr = chainOp(V"UnaryExpr", V"MulOp", "MulExpr"); + UnaryExpr = V"UnaryOp" * V"Skip" * expect(V"UnaryExpr", "UnaryExpr") / unaryOp + + V"PowExpr"; + PowExpr = V"SimpleExpr" * (V"Skip" * V"PowOp" * V"Skip" * expect(V"UnaryExpr", "PowExpr"))^-1 / binaryOp; + + SimpleExpr = tagC("Number", V"Number") + + tagC("String", V"String") + + tagC("Nil", kw("nil")) + + tagC("Boolean", kw("false") * Cc(false)) + + tagC("Boolean", kw("true") * Cc(true)) + + tagC("Dots", P("...")) + + V"FuncDef" + + V"Table" + + V"SuffixedExpr"; + + FuncCall = Cmt(V"SuffixedExpr", function(s, i, exp) return exp.tag == "Call" or exp.tag == "Invoke", exp end); + VarExpr = Cmt(V"SuffixedExpr", function(s, i, exp) return exp.tag == "Id" or exp.tag == "Index", exp end); + + SuffixedExpr = Cf(V"PrimaryExpr" * (V"Skip" * (V"Index" + V"Call"))^0, makeIndexOrCall); + PrimaryExpr = V"Id" * V"Skip" + tagC("Paren", P("(") * V"Skip" * expect(V"Expr", "ExprParen") * V"Skip" * expect(P(")"), "CParenExpr")); + Index = tagC("DotIndex", P"." * V"Skip" * -P"." * expect(V"StrId", "NameIndex")) + + tagC("ArrayIndex", P("[") * -S"=[" * V"Skip" * expect(V"Expr", "ExprIndex") * V"Skip" * expect(P("]"), "CBracketIndex")); + Call = tagC("Invoke", Cg(P(":") * -P":" * V"Skip" * expect(V"StrId", "NameMeth") * V"Skip" * expect(V"FuncArgs", "MethArgs"))) + + tagC("Call", V"FuncArgs"); + + FuncDef = kw("function") * V"Skip" * V"FuncBody"; + FuncArgs = P("(") * V"Skip" * sepBy(V"Expr", P(","), "ArgList")^-1 * V"Skip" * expect(P(")"), "CParenArgs") + + V"Table" + + tagC("String", V"String"); + + Table = tagC("Table", P("{") * V"Skip" * V"FieldList"^-1 * expect(P("}"), "CBraceTable")); + FieldList = sepBy(V"Field", V"FieldSep") * (V"Skip" * V"FieldSep")^-1 * V"Skip"; + Field = tagC("Pair", V"FieldKey" * expect(P("=") * V"Skip", "EqField") * expect(V"Expr", "ExprField")) + + V"Expr"; + FieldKey = P("[" * -P(S"=[")) * V"Skip" * expect(V"Expr", "ExprFKey") * V"Skip" * expect(P("]") * V"Skip", "CBracketFKey") + + V"StrId" * V"Skip" * #("=" * -P"="); + FieldSep = P(",") * V"Skip" + P(";") * V"Skip"; + + Id = tagC("Id", V"Name"); + StrId = tagC("String", V"Name"); + + -- lexer + Skip = ((Cp() * space^0 * Cp() * C(V"Comment") * Cp() * space^0 * Cp()) / function(p1a, p1b, c, p2a, p2b) + commentCollector.add(p1a, p1b, p2a-1, p2b-1, c) + end + + V"Space")^0; + + Space = space^1; + Comment = P"--" * V"LongStr" / function () return end + + P"--" * (P(1) - P"\n")^0; + + Name = -V"Reserved" * C(V"Ident"); + Reserved = V"Keywords" * -V"IdRest"; + Keywords = P"and" + "break" + "do" + "elseif" + "else" + "end" + + "false" + "for" + "function" + "goto" + "if" + "in" + + "local" + "nil" + "not" + "or" + "repeat" + "return" + + "then" + "true" + "until" + "while"; + Ident = V"IdStart" * V"IdRest"^0; + IdStart = alpha + P"_"; + IdRest = alnum + P"_"; + + Number = (V"Hex" + V"Float" + V"Int") / tonumber; + Hex = (P"0x" + "0X") * expect(xdigit^1, "DigitHex"); + Float = V"Decimal" * V"Expo"^-1 + + V"Int" * V"Expo"; + Decimal = digit^1 * "." * digit^0 + + P"." * -P"." * expect(digit^1, "DigitDeci"); + Expo = S"eE" * S"+-"^-1 * expect(digit^1, "DigitExpo"); + Int = digit^1; + + String = (V"ShortStr" + V"LongStr"); + ShortStr = P'"' * Cs((V"EscSeq" + (P(1)-S'"\n'))^0) * expect(P'"', "Quote") + + P"'" * Cs((V"EscSeq" + (P(1)-S"'\n"))^0) * expect(P"'", "Quote"); + + EscSeq = P"\\" / "" -- remove backslash + * ( P"a" / "\a" + + P"b" / "\b" + + P"f" / "\f" + + P"n" / "\n" + + P"r" / "\r" + + P"t" / "\t" + + P"v" / "\v" + + + P"\n" / "\n" + + P"\r" / "\n" + + + P"\\" / "\\" + + P"\"" / "\"" + + P"\'" / "\'" + + + P"z" * space^0 / "" + + + digit * digit^-2 / tonumber / string.char + + P"x" * expect(C(xdigit * xdigit), "HexEsc") * Cc(16) / tonumber / string.char + + P"u" * expect("{", "OBraceUEsc") + * expect(C(xdigit^1), "DigitUEsc") * Cc(16) + * expect("}", "CBraceUEsc") + / tonumber + / (utf8 and utf8.char or string.char) -- true max is \u{10FFFF} + -- utf8.char needs Lua 5.3 + -- string.char works only until \u{FF} + + + throw("EscSeq") + ); + + LongStr = V"Open" * C((P(1) - V"CloseEq")^0) * expect(V"Close", "CloseLStr") / function (s, eqs) return s end; + Open = "[" * Cg(V"Equals", "openEq") * "[" * P"\n"^-1; + Close = "]" * C(V"Equals") * "]"; + Equals = P"="^0; + CloseEq = Cmt(V"Close" * Cb("openEq"), function (s, i, closeEq, openEq) return #openEq == #closeEq end); + + OrOp = kw("or") / "or"; + AndOp = kw("and") / "and"; + RelOp = P("~=") / "ne" + + P("==") / "eq" + + P("<=") / "le" + + P(">=") / "ge" + + P("<") / "lt" + + P(">") / "gt"; + BOrOp = P("|") / "bor"; + BXorOp = P("~" * -P"=") / "bxor"; + BAndOp = P("&") / "band"; + ShiftOp = P("<<") / "shl" + + P(">>") / "shr"; + ConcatOp = P("..") / "concat"; + AddOp = P("+") / "add" + + P("-") / "sub"; + MulOp = P("*") / "mul" + + P("//") / "idiv" + + P("/") / "div" + + P("%") / "mod"; + UnaryOp = kw("not") / "not" + + P("-") / "unm" + + P("#") / "len" + + P("~") / "bnot"; + PowOp = P("^") / "pow"; +} + +local parser = { detailed_errors = false } + +local validator = require("mkdoc.lua-parser.validator") +local validate = validator.validate +local syntaxerror = validator.syntaxerror + +function parser.parse (subject, filename, comments) + commentCollector = comments + local errorinfo = { subject = subject, filename = filename } + lpeg.setmaxstack(1000) + local ast, label, errorpos = lpeg.match(G, subject, nil, errorinfo) + if not ast then + if parser.detailed_errors then + local re = require "relabel" + local line, col = re.calcline(subject, errorpos) + return ast, { + line = line; + column = col; + id = labels[label][1]; + message = labels[label][2]; + position = errorpos; + } + else + local errmsg = labels[label][2] + return ast, syntaxerror(errorinfo, errorpos, errmsg) + end + end + commentCollector = nil + return validate(ast, errorinfo) +end + +return parser diff --git a/src/mkdoc/lua-parser/scope.lua b/src/mkdoc/lua-parser/scope.lua new file mode 100644 index 0000000..dd19392 --- /dev/null +++ b/src/mkdoc/lua-parser/scope.lua @@ -0,0 +1,74 @@ +--[[ +This module implements functions that handle scoping rules +]] +local scope = {} + +function scope.lineno (s, i) + if i == 1 then return 1, 1 end + local l, lastline = 0, "" + s = s:sub(1, i) .. "\n" + for line in s:gmatch("[^\n]*[\n]") do + l = l + 1 + lastline = line + end + local c = lastline:len() - 1 + return l, c ~= 0 and c or 1 +end + +function scope.new_scope (env) + if not env.scope then + env.scope = 0 + else + env.scope = env.scope + 1 + end + local scope = env.scope + env.maxscope = scope + env[scope] = {} + env[scope]["label"] = {} + env[scope]["local"] = {} + env[scope]["goto"] = {} +end + +function scope.begin_scope (env) + env.scope = env.scope + 1 +end + +function scope.end_scope (env) + env.scope = env.scope - 1 +end + +function scope.new_function (env) + if not env.fscope then + env.fscope = 0 + else + env.fscope = env.fscope + 1 + end + local fscope = env.fscope + env["function"][fscope] = {} +end + +function scope.begin_function (env) + env.fscope = env.fscope + 1 +end + +function scope.end_function (env) + env.fscope = env.fscope - 1 +end + +function scope.begin_loop (env) + if not env.loop then + env.loop = 1 + else + env.loop = env.loop + 1 + end +end + +function scope.end_loop (env) + env.loop = env.loop - 1 +end + +function scope.insideloop (env) + return env.loop and env.loop > 0 +end + +return scope diff --git a/src/mkdoc/lua-parser/validator.lua b/src/mkdoc/lua-parser/validator.lua new file mode 100644 index 0000000..41a86d7 --- /dev/null +++ b/src/mkdoc/lua-parser/validator.lua @@ -0,0 +1,394 @@ +--[[ +This module impements a validator for the AST +]] +local scope = require "mkdoc.lua-parser.scope" + +local lineno = scope.lineno +local new_scope, end_scope = scope.new_scope, scope.end_scope +local new_function, end_function = scope.new_function, scope.end_function +local begin_loop, end_loop = scope.begin_loop, scope.end_loop +local insideloop = scope.insideloop + +-- creates an error message for the input string +local function syntaxerror (errorinfo, pos, msg) + local l, c = lineno(errorinfo.subject, pos) + local error_msg = "%s:%d:%d: syntax error, %s" + return string.format(error_msg, errorinfo.filename, l, c, msg) +end + +local function exist_label (env, scope, stm) + local l = stm[1] + for s=scope, 0, -1 do + if env[s]["label"][l] then return true end + end + return false +end + +local function set_label (env, label, pos) + local scope = env.scope + local l = env[scope]["label"][label] + if not l then + env[scope]["label"][label] = { name = label, pos = pos } + return true + else + local msg = "label '%s' already defined at line %d" + local line = lineno(env.errorinfo.subject, l.pos) + msg = string.format(msg, label, line) + return nil, syntaxerror(env.errorinfo, pos, msg) + end +end + +local function set_pending_goto (env, stm) + local scope = env.scope + table.insert(env[scope]["goto"], stm) + return true +end + +local function verify_pending_gotos (env) + for s=env.maxscope, 0, -1 do + for k, v in ipairs(env[s]["goto"]) do + if not exist_label(env, s, v) then + local msg = "no visible label '%s' for " + msg = string.format(msg, v[1]) + return nil, syntaxerror(env.errorinfo, v.pos, msg) + end + end + end + return true +end + +local function set_vararg (env, is_vararg) + env["function"][env.fscope].is_vararg = is_vararg +end + +local traverse_stm, traverse_exp, traverse_var +local traverse_block, traverse_explist, traverse_varlist, traverse_parlist + +function traverse_parlist (env, parlist) + local len = #parlist + local is_vararg = false + if len > 0 and parlist[len].tag == "Dots" then + is_vararg = true + end + set_vararg(env, is_vararg) + return true +end + +local function traverse_function (env, exp) + new_function(env) + new_scope(env) + local status, msg = traverse_parlist(env, exp[1]) + if not status then return status, msg end + status, msg = traverse_block(env, exp[2]) + if not status then return status, msg end + end_scope(env) + end_function(env) + return true +end + +local function traverse_op (env, exp) + local status, msg = traverse_exp(env, exp[2]) + if not status then return status, msg end + if exp[3] then + status, msg = traverse_exp(env, exp[3]) + if not status then return status, msg end + end + return true +end + +local function traverse_paren (env, exp) + local status, msg = traverse_exp(env, exp[1]) + if not status then return status, msg end + return true +end + +local function traverse_table (env, fieldlist) + for k, v in ipairs(fieldlist) do + local tag = v.tag + if tag == "Pair" then + local status, msg = traverse_exp(env, v[1]) + if not status then return status, msg end + status, msg = traverse_exp(env, v[2]) + if not status then return status, msg end + else + local status, msg = traverse_exp(env, v) + if not status then return status, msg end + end + end + return true +end + +local function traverse_vararg (env, exp) + if not env["function"][env.fscope].is_vararg then + local msg = "cannot use '...' outside a vararg function" + return nil, syntaxerror(env.errorinfo, exp.pos, msg) + end + return true +end + +local function traverse_call (env, call) + local status, msg = traverse_exp(env, call[1]) + if not status then return status, msg end + for i=2, #call do + status, msg = traverse_exp(env, call[i]) + if not status then return status, msg end + end + return true +end + +local function traverse_invoke (env, invoke) + local status, msg = traverse_exp(env, invoke[1]) + if not status then return status, msg end + for i=3, #invoke do + status, msg = traverse_exp(env, invoke[i]) + if not status then return status, msg end + end + return true +end + +local function traverse_assignment (env, stm) + local status, msg = traverse_varlist(env, stm[1]) + if not status then return status, msg end + status, msg = traverse_explist(env, stm[2]) + if not status then return status, msg end + return true +end + +local function traverse_break (env, stm) + if not insideloop(env) then + local msg = " not inside a loop" + return nil, syntaxerror(env.errorinfo, stm.pos, msg) + end + return true +end + +local function traverse_forin (env, stm) + begin_loop(env) + new_scope(env) + local status, msg = traverse_explist(env, stm[2]) + if not status then return status, msg end + status, msg = traverse_block(env, stm[3]) + if not status then return status, msg end + end_scope(env) + end_loop(env) + return true +end + +local function traverse_fornum (env, stm) + local status, msg + begin_loop(env) + new_scope(env) + status, msg = traverse_exp(env, stm[2]) + if not status then return status, msg end + status, msg = traverse_exp(env, stm[3]) + if not status then return status, msg end + if stm[5] then + status, msg = traverse_exp(env, stm[4]) + if not status then return status, msg end + status, msg = traverse_block(env, stm[5]) + if not status then return status, msg end + else + status, msg = traverse_block(env, stm[4]) + if not status then return status, msg end + end + end_scope(env) + end_loop(env) + return true +end + +local function traverse_goto (env, stm) + local status, msg = set_pending_goto(env, stm) + if not status then return status, msg end + return true +end + +local function traverse_if (env, stm) + local len = #stm + if len % 2 == 0 then + for i=1, len, 2 do + local status, msg = traverse_exp(env, stm[i]) + if not status then return status, msg end + status, msg = traverse_block(env, stm[i+1]) + if not status then return status, msg end + end + else + for i=1, len-1, 2 do + local status, msg = traverse_exp(env, stm[i]) + if not status then return status, msg end + status, msg = traverse_block(env, stm[i+1]) + if not status then return status, msg end + end + local status, msg = traverse_block(env, stm[len]) + if not status then return status, msg end + end + return true +end + +local function traverse_label (env, stm) + local status, msg = set_label(env, stm[1], stm.pos) + if not status then return status, msg end + return true +end + +local function traverse_let (env, stm) + local status, msg = traverse_explist(env, stm[2]) + if not status then return status, msg end + return true +end + +local function traverse_letrec (env, stm) + local status, msg = traverse_exp(env, stm[2][1]) + if not status then return status, msg end + return true +end + +local function traverse_repeat (env, stm) + begin_loop(env) + local status, msg = traverse_block(env, stm[1]) + if not status then return status, msg end + status, msg = traverse_exp(env, stm[2]) + if not status then return status, msg end + end_loop(env) + return true +end + +local function traverse_return (env, stm) + local status, msg = traverse_explist(env, stm) + if not status then return status, msg end + return true +end + +local function traverse_while (env, stm) + begin_loop(env) + local status, msg = traverse_exp(env, stm[1]) + if not status then return status, msg end + status, msg = traverse_block(env, stm[2]) + if not status then return status, msg end + end_loop(env) + return true +end + +function traverse_var (env, var) + local tag = var.tag + if tag == "Id" then -- `Id{ } + return true + elseif tag == "Index" then -- `Index{ expr expr } + local status, msg = traverse_exp(env, var[1]) + if not status then return status, msg end + status, msg = traverse_exp(env, var[2]) + if not status then return status, msg end + return true + else + error("expecting a variable, but got a " .. tag) + end +end + +function traverse_varlist (env, varlist) + for k, v in ipairs(varlist) do + local status, msg = traverse_var(env, v) + if not status then return status, msg end + end + return true +end + +function traverse_exp (env, exp) + local tag = exp.tag + if tag == "Nil" or + tag == "Boolean" or -- `Boolean{ } + tag == "Number" or -- `Number{ } + tag == "String" then -- `String{ } + return true + elseif tag == "Dots" then + return traverse_vararg(env, exp) + elseif tag == "Function" then -- `Function{ { `Id{ }* `Dots? } block } + return traverse_function(env, exp) + elseif tag == "Table" then -- `Table{ ( `Pair{ expr expr } | expr )* } + return traverse_table(env, exp) + elseif tag == "Op" then -- `Op{ opid expr expr? } + return traverse_op(env, exp) + elseif tag == "Paren" then -- `Paren{ expr } + return traverse_paren(env, exp) + elseif tag == "Call" then -- `Call{ expr expr* } + return traverse_call(env, exp) + elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } + return traverse_invoke(env, exp) + elseif tag == "Id" or -- `Id{ } + tag == "Index" then -- `Index{ expr expr } + return traverse_var(env, exp) + else + error("expecting an expression, but got a " .. tag) + end +end + +function traverse_explist (env, explist) + for k, v in ipairs(explist) do + local status, msg = traverse_exp(env, v) + if not status then return status, msg end + end + return true +end + +function traverse_stm (env, stm) + local tag = stm.tag + if tag == "Do" then -- `Do{ stat* } + return traverse_block(env, stm) + elseif tag == "Set" then -- `Set{ {lhs+} {expr+} } + return traverse_assignment(env, stm) + elseif tag == "While" then -- `While{ expr block } + return traverse_while(env, stm) + elseif tag == "Repeat" then -- `Repeat{ block expr } + return traverse_repeat(env, stm) + elseif tag == "If" then -- `If{ (expr block)+ block? } + return traverse_if(env, stm) + elseif tag == "Fornum" then -- `Fornum{ ident expr expr expr? block } + return traverse_fornum(env, stm) + elseif tag == "Forin" then -- `Forin{ {ident+} {expr+} block } + return traverse_forin(env, stm) + elseif tag == "Local" then -- `Local{ {ident+} {expr+}? } + return traverse_let(env, stm) + elseif tag == "Localrec" then -- `Localrec{ ident expr } + return traverse_letrec(env, stm) + elseif tag == "Goto" then -- `Goto{ } + return traverse_goto(env, stm) + elseif tag == "Label" then -- `Label{ } + return traverse_label(env, stm) + elseif tag == "Return" then -- `Return{ * } + return traverse_return(env, stm) + elseif tag == "Break" then + return traverse_break(env, stm) + elseif tag == "Call" then -- `Call{ expr expr* } + return traverse_call(env, stm) + elseif tag == "Invoke" then -- `Invoke{ expr `String{ } expr* } + return traverse_invoke(env, stm) + else + error("expecting a statement, but got a " .. tag) + end +end + +function traverse_block (env, block) + local l = {} + new_scope(env) + for k, v in ipairs(block) do + local status, msg = traverse_stm(env, v) + if not status then return status, msg end + end + end_scope(env) + return true +end + + +local function traverse (ast, errorinfo) + assert(type(ast) == "table") + assert(type(errorinfo) == "table") + local env = { errorinfo = errorinfo, ["function"] = {} } + new_function(env) + set_vararg(env, true) + local status, msg = traverse_block(env, ast) + if not status then return status, msg end + end_function(env) + status, msg = verify_pending_gotos(env) + if not status then return status, msg end + return ast +end + +return { validate = traverse, syntaxerror = syntaxerror } diff --git a/src/mkdoc/main.lua b/src/mkdoc/main.lua new file mode 100644 index 0000000..fa188ed --- /dev/null +++ b/src/mkdoc/main.lua @@ -0,0 +1,1260 @@ +os.setlocale("C") + +local path = require("path") -- https://luarocks.org/modules/xavier-wang/lpath +local fs = require("path.fs") -- https://luarocks.org/modules/xavier-wang/lpath +local perf = require("perf") + +local format = string.format + +--------------------------------------------------------------------------------------------------------------------------- + +local function fprintf(file, ...) + file:write(format(...)) +end + +local function printf(...) + io.write(format(...)) +end + +local function append(t, v) + t[#t + 1] = v +end + +local function addSet(t, v) + assert(not t[v]) + t[v] = true + t[#t + 1] = v +end + +local function add(t, k, v) + assert(not t[k], k) + assert(not t[v]) + t[k] = v + t[v] = true + t[#t + 1] = v +end + +local function addr(t, k, v, r) + assert(not t[k]) + assert(not t[v]) + assert(not t[r]) + t[k] = v + t[v] = true + t[r] = v + t[#t + 1] = v +end + +--------------------------------------------------------------------------------------------------------------------------- + +local ARGS = { ... } +local TRACE = (ARGS[1] == "trace") or false + +fs.removedirs("../doc/gen") +fs.makedirs("../doc/gen/lwtk") + +--------------------------------------------------------------------------------------------------------------------------- + +perf.start"directoryScan" + +local moduleFileNames = {} +for n, t in fs.scandir("lwtk") do + if t == "file" and path.isfile(n) then + moduleFileNames[#moduleFileNames + 1] = n + end +end + +perf.stop"directoryScan" + +--------------------------------------------------------------------------------------------------------------------------- + +perf.start"requireModules" + +local reverseLookup = {} +local isPackage = {} +local toModuleFileName = {} +local packageInfos = {} +local moduleInfos = {} +local classInfos = {} +local mixinInfos = {} +local metaInfos = {} +local functionInfos = {} +local otherInfos = {} +local classMixinInfos = {} +local depOrderedModuleNames = {} +local modules = {} + +--------------------------------------------------------------------------------------------------------------------------- + +local original_require = _G.require +do + local moduleNames = {} + + for i, moduleFileName in ipairs(moduleFileNames) do + local moduleName = moduleFileName:gsub("^(.*)%.lua$", "%1"):gsub("/", "."):gsub("%.init$", "") + isPackage[moduleName] = moduleFileName:match("%/init%.lua$") and true or false + moduleNames[i] = moduleName + toModuleFileName[moduleName] = moduleFileName + end + + function _G.require(moduleName) + local module = original_require(moduleName) + if not moduleName:match("^lwtk") then + return module + end + if not reverseLookup[module] then + --printf("Loading %s\n", moduleName, ) + append(depOrderedModuleNames, moduleName) + local isP = isPackage[moduleName] + local moduleType = type(module) + local packageName = moduleName:gsub("^(.*)%.[^.]+$", "%1") + local isInternal = moduleName:match("^lwtk%.internal") and true or false + local moduleInfo = { + moduleName = moduleName, + docFileName = toModuleFileName[moduleName]:gsub("%.lua", ".md"), + packageName = packageName, + isInternal = isInternal, + isModule = true, + isPackage = isP, + moduleType = moduleType, + memberInfos = {}, + referringInfos = {} + } + reverseLookup[module] = moduleInfo + addr(moduleInfos, moduleName, moduleInfo, module) + if isP then + add(packageInfos, moduleName, moduleInfo) + end + modules[moduleName] = module + end + return module + end + + for _, moduleName in ipairs(moduleNames) do + --printf("Requiring %s\n", moduleName) + require(moduleName) + end +end +_G.require = original_require + +perf.stop"requireModules" + +--------------------------------------------------------------------------------------------------------------------------- + +local lpeg = require "lpeglabel" -- https://luarocks.org/modules/sergio-medeiros/lpeglabel +local re = require("relabel") -- https://luarocks.org/modules/sergio-medeiros/lpeglabel + +local pprint = require("mkdoc.pprint") -- modified version from: https://github.com/jagt/pprint.lua +local parser = require("mkdoc.lua-parser.parser") -- modified version from: https://github.com/andremm/lua-parser +local comments = require("mkdoc.comments") +local util = require("mkdoc.util") + +local lwtk = require("lwtk") +local getMixinBase = lwtk.get.mixinBase + +--------------------------------------------------------------------------------------------------------------------------- + +local getClassModuleName = util.getClassModuleName + +local function getClassModuleInfo(c) + return moduleInfos[getClassModuleName(c)] +end + +--------------------------------------------------------------------------------------------------------------------------- + + +lpeg.locale(lpeg) + +local P, S, V = lpeg.P, lpeg.S, lpeg.V +local C, Carg, Cb, Cc = lpeg.C, lpeg.Carg, lpeg.Cb, lpeg.Cc +local Cf, Cg, Cmt, Cp, Cs, Ct = lpeg.Cf, lpeg.Cg, lpeg.Cmt, lpeg.Cp, lpeg.Cs, lpeg.Ct +local Lc, T = lpeg.Lc, lpeg.T + +local alpha, digit, alnum = lpeg.alpha, lpeg.digit, lpeg.alnum +local xdigit = lpeg.xdigit +local space = lpeg.space + +--------------------------------------------------------------------------------------------------------------------------- + +perf.start"moduleScan" + +do + local function addMemberInfo(moduleInfo, memberName, member, class, parentInfo) + -- for Mixins: class != module + local moduleName = moduleInfo.moduleName + local memberType = type(member) + if memberType == "table" or memberType == "function" then + local memberInfo = moduleInfo.memberInfos[memberName] + local declared = class and class.declared[memberName] or moduleInfo.isMixin + if not memberInfo then + local memberInfo = { + moduleName = moduleName, + isModuleMember = true, + isModuleSubMember = (parentInfo ~= nil and true or nil), + isEntity = true, + memberName = memberName, + memberType = memberType, + member = member, + referringInfos = {}, + declared = declared + } + if memberType == "function" then + local isObjMember = class and rawget(class.__index, memberName) + if declared and (not class or isObjMember) then + addr(moduleInfo.memberFunctions, memberName, memberInfo, member) + elseif class and isObjMember then + local inheritedMethods = moduleInfo.inheritedMethods -- TODO mixin + local i = 0 + local s = class:getSuperClass() + while s do + i = i + 1 + local fromList = inheritedMethods[i] + if not fromList then + fromList = { moduleName = getClassModuleName(s), isMixin = getMixinBase[s] } + inheritedMethods[i] = fromList + end + if s.declared[memberName] then + append(fromList, { moduleName = getClassModuleName(s), + memberName = memberName }) + break + end + s = s:getSuperClass() + end + end + end + local existingInfo = reverseLookup[member] + if not existingInfo then + reverseLookup[member] = memberInfo + else + if existingInfo.moduleName == moduleName then + error(require"inspect"{memberName, moduleName, existingInfo}) + end + add(existingInfo.referringInfos, moduleName, memberInfo) + memberInfo.originalMemberInfo = existingInfo + end + addr(moduleInfo.memberInfos, memberName, memberInfo, member) + + if memberType == "table" and not memberName:match("^__") and memberName ~= "implement" + and memberName ~= "override" and memberName ~= "declared" and memberName ~= "static" + and not getmetatable(member) + then + --print("####", memberName) + local mt = getmetatable(member) + local _pairs = mt and mt.__pairs or pairs + for k, v in _pairs(member) do + --assert(type(k) == "string", require"inspect"{moduleName, memberName, k, v}) + addMemberInfo(moduleInfo, memberName.."."..k, v, nil, memberInfo) + end + end + else + assert(moduleInfo.isMixin) + if memberType == "function" then + if declared then + if moduleInfo.memberFunctions[memberName] ~= memberInfo then + error(require"inspect"{moduleInfo.moduleName, memberName, memberInfo}) + end + elseif class then + assert(moduleInfo.memberFunctions[memberName] == nil) + end + end + if memberType ~= memberInfo.memberType then + if memberInfo.memberType == "boolean" and memberInfo.member == false then + assert(memberType == "table" or memberType == "function") + memberInfo.memberType = memberType + memberInfo.isEntity = true + memberInfo.member = nil + memberInfo.memberRealisation = { member } + else + error(require"inspect"{moduleName, memberName, memberType, memberInfo.memberType, memberInfo}) + end + end + end + else + local memberInfo = moduleInfo.memberInfos[memberName] + if not memberInfo then + local memberInfo = { + moduleName = moduleName, + isModuleMember = true, + isValue = true, + memberName = memberName, + memberType = memberType, + member = member + } + add(moduleInfo.memberInfos, memberName, memberInfo) + else + assert(moduleInfo.isMixin) + if memberType ~= memberInfo.memberType or member ~= memberInfo.member then + error(require"inspect"{moduleName, memberName, memberType, memberInfo.memberType, memberInfo}) + end + end + end + end + + local function visitSuperClasses(thisModuleName, thisModule, thisModuleInfo) + local thisClassPath = util.getReverseClassPathString(thisModule) + local super = thisModule:getSuperClass() + local mixinVisited = false + while super do + local superInfo = getClassModuleInfo(super) + addSet(superInfo.subClassPaths, thisClassPath) + if not mixinVisited and superInfo.isMixin then + -- for Mixins: class != module, i.e. super != modules[superName] + if superInfo.mixinRealisations[super] then + mixinVisited = true + else + local list = util.getReverseClassPathList(super) + list.pathString = util.classPathListToString(list) + addr(superInfo.mixinRealisations, super, list, list.pathString) + for memberName, member in pairs(super.__index) do + if super.declared[memberName] then + addMemberInfo(superInfo, memberName, member, super) + end + end + end + end + super = super:getSuperClass() + end + end + + for _, thisModuleName in ipairs(depOrderedModuleNames) do + local thisModule = modules[thisModuleName] + local thisModuleInfo = moduleInfos[thisModuleName] + local thisModuleType = type(thisModule) + + local isClass = lwtk.isInstanceOf(thisModule, lwtk.Class) + local isMixin = lwtk.isInstanceOf(thisModule, lwtk.Mixin) + local isMeta = lwtk.isInstanceOf(thisModule, lwtk.Meta) + local isFunction = (thisModuleType == "function") + if isClass then + thisModuleInfo.isClass = true + thisModuleInfo.memberFunctions = {} + thisModuleInfo.inheritedMethods = {} + elseif isMixin then + thisModuleInfo.isMixin = true + thisModuleInfo.memberFunctions = {} + thisModuleInfo.inheritedMethods = {} + elseif isMeta then + thisModuleInfo.isMeta = true + elseif isFunction then + thisModuleInfo.isFunction = true + end + + if thisModuleType == "table" and not thisModuleInfo.isPackage then + local mt = getmetatable(thisModule) + local _pairs = mt and mt.__pairs or pairs + local class = isClass and thisModule + for memberName, member in _pairs(thisModule) do + addMemberInfo(thisModuleInfo, memberName, member, class) + end + end + + if isClass --[[or isMixin]] then + thisModuleInfo.subClassPaths = {} + elseif isMixin then + thisModuleInfo.subClassPaths = {} + thisModuleInfo.mixinRealisations = {} + end + if not thisModuleInfo.isInternal then + if isClass then + add(classInfos, thisModuleName, thisModuleInfo) + add(classMixinInfos, thisModuleName, thisModuleInfo) + visitSuperClasses(thisModuleName, thisModule, thisModuleInfo) + elseif isMixin then + add(mixinInfos, thisModuleName, thisModuleInfo) + add(classMixinInfos, thisModuleName, thisModuleInfo) + elseif isMeta then + add(metaInfos, thisModuleName, thisModuleInfo) + elseif isFunction then + add(functionInfos, thisModuleName, thisModuleInfo) + else + add(otherInfos, thisModuleName, thisModuleInfo) + end + end + end +end +do + for _, thisModuleInfo in ipairs(classInfos) do + local thisModuleName = thisModuleInfo.moduleName + local thisModule = modules[thisModuleName] + for k, v in pairs(thisModule.__index) do + local memberInfo = thisModuleInfo.memberInfos[k] + if not memberInfo then + error(require"inspect"{thisModuleName, k}) + end + if type(v) == "function" then + if thisModule.declared[k] then + memberInfo.overrideList = util.getOverrideList(thisModule, k) -- TODO + end + end + end + end +end +perf.stop"moduleScan" + + +--------------------------------------------------------------------------------------------------------------------------- + +perf.start"totalparse" + +local parseModule +do + local function processExp(env, e) + if e.tag == "Call" then + local func = processExp(env, e[1]) + local args = {} + for i = 2, #e do + args[i-1] = processExp(env, e[i]) + end + if func == require then + --local rslt = require(args[1]) + local rslt = moduleInfos[args[1]] + if not rslt then + rslt = require(args[1]) + end + return rslt + elseif func == lwtk.newClass then + --[[ + local class = lwtk.tryrequire(args[1]) + if class then + if classDocs[class] ~= nil then + lwtk.errorf("already found: lwtk.newClass(%q)", class.__name) + end + classDocs[class] = false + return class, NEW_CLASS + else + print("ignoring class", args[1]) + end ]] + end + elseif e.tag == "Index" then + local e1 = processExp(env, e[1]) + local e2 = processExp(env, e[2]) + if e1 then + if moduleInfos[e1] == true then + return e1.memberInfos[e2] + else + return e1[e2] + end + end + elseif e.tag == "String" then + return e[1] + elseif e.tag == "Op" then + local op = e[1] + if op == "concat" then + local e1 = processExp(env, e[2]) + local e2 = processExp(env, e[3]) + return e1..e2 + elseif op == "or" then + local e1 = processExp(env, e[2]) + local e2 = processExp(env, e[3]) + return e1 or e2 + elseif op == "div" then + elseif op == "not" then + elseif op == "and" then + else + error(op) + end + elseif e.tag == "Id" then + return env[e[1]] + elseif e.tag == "Number" then + return e[1] + elseif e.tag == "Table" then + elseif e.tag == "Function" then + elseif e.tag == "Boolean" then + return e[1] + elseif e.tag == "Invoke" then + elseif e.tag == "Paren" then + elseif e.tag == "Nil" then + return nil + else + error(require"inspect"({tag = e.tag, pos = e.pos, end_pos = e.end_pos})) + end + end + + local moduleOutDirs = {} + + function parseModule(thisModuleName, thisModule, thisModuleInfo) + local moduleFileNameStem = thisModuleName:gsub("%.", "/") + if thisModuleInfo.isPackage then + moduleFileNameStem = moduleFileNameStem.."/init" + end + local moduleFileName = moduleFileNameStem..".lua" + local traceFileName = path("../doc/gen", moduleFileNameStem..".trace") + local outDir = path.parent(traceFileName) + if not moduleOutDirs[outDir] then + moduleOutDirs[outDir] = true + fs.makedirs(outDir) + end + + local traceOut = TRACE and io.open(traceFileName, "w") + do + print("Processing", moduleFileName) + local function trace(...) + if traceOut then + local n = select("#", ...) + for i = 1, n do + traceOut:write(tostring(select(i, ...))) + if i < n then + traceOut:write("\t") + end + end + traceOut:write("\n") + end + end + + local file = assert(io.open(moduleFileName, "r"), moduleFileName) + local content = file:read("*a") + file:close() + + comments.init(content, trace) + perf.start"parse" + local ast, err = parser.parse(content, moduleFileName, comments) + perf.stop"parse" + comments.sort() + + ------------------------------------------------------------------------------------ + if TRACE then + perf.start"trace" + trace(pprint.pformat(ast)) + perf.stop"trace" + end + ------------------------------------------------------------------------------------ + + local returnId = nil + local isClass = thisModuleInfo.isClass + local isMeta = thisModuleInfo.isMeta + local isMixin = thisModuleInfo.isMixin + local isFunction = thisModuleInfo.isFunction + + local last = ast[#ast] + assert(last.tag == "Return" and #last == 1) + if last[1].tag == "Id" then + returnId = last[1][1] + else + local s = last + local doc, argListDoc = comments.stripArgListDoc(comments.getBefore(s.pos)) + local shortDoc = comments.getShortDoc(doc) + thisModuleInfo.fullDoc = doc + thisModuleInfo.shortDoc = shortDoc + local argListString, isMethod = util.getArgListString(s[1]) + if argListString and argListDoc then + assert(argListString == argListDoc) + end + if not argListString and argListDoc then + argListString, isMethod = comments.argListDocToMethod(argListDoc) + end + --assert(not isMethod) + thisModuleInfo.argListString = argListString + thisModuleInfo.isMethod = isMethod + end + local function processBlock(ast, env) + for _, s in ipairs(ast) do + trace("TTT", s.pos, s.tag) + local tag = s.tag + if tag == "Local" or tag == "Localrec" then + local s1 = s[1]; + local s2 = s[2]; + local isReturnId = false + if s.tag == "Local" then + assert(s1.tag == "NameList") + assert(not s2.tag or s2.tag == "ExpList", s2) + for i = 1, #s1 do + local n = s1[i]; assert(n.tag == "Id") + if n[1] == returnId then + assert(#s1 == 1 and #s2 == 1) + isReturnId = true + break + end + end + else + assert(#s1 == 1 and s1.tag == nil and s1[1].tag == "Id") + isReturnId = (s1[1][1] == returnId) + end + if isReturnId then + trace("NEW_MODULE", s.pos, s.end_pos) + local docb = comments.getBefore(s.pos) + local doca = comments.getAfter(s.end_pos) + if docb then + trace("FOUNDBEFORE", docb)--require"inspect"(doc)) + end + if doca then + trace("FOUNDAFTER", doca) + end + if doca and docb then + lwtk.errorf("Ambiguous class comment in line %d of file %q", re.calcline(content, s.pos), moduleFileName) + end + env[returnId] = thisModule + local doc, argListDoc = comments.stripArgListDoc(docb or doca) + local shortDoc = comments.getShortDoc(doc) + thisModuleInfo.fullDoc = doc + thisModuleInfo.shortDoc = shortDoc + + if isFunction then + local argListString, isMethod + if tag == "Localrec" then + argListString, isMethod = util.getArgListString(s2[1]) + --assert(not isMethod) + end + if not argListString and argListDoc then + argListString, isMethod = comments.argListDocToMethod(argListDoc) + end + thisModuleInfo.argListString = argListString + thisModuleInfo.isMethod = isMethod + end + elseif tag == "Localrec" then + assert(#s2 == 1 and s2.tag == nil and s2[1].tag == "Function") + local rslt = processExp(env, s2[1]) + trace("setting", s1[1][1], rslt) + env[s1[1][1]] = rslt + else + for i = 1, #s1 do + local n = s1[i]; assert(n.tag == "Id") + local e = s2[i] + if e then + local rslt = processExp(env, e) + trace("setting", n[1], rslt) + env[n[1]] = rslt + end + end + end + elseif tag == "Set" then + local lhsl = s[1]; + local expl = s[2]; + local memberInfo = nil + for i = 1, #lhsl do + local lhs = processExp(env, lhsl[i]); + memberInfo = thisModuleInfo.memberInfos[lhs] + if memberInfo then + assert(#lhsl == 1) + break + end + end + if memberInfo then + local exp = expl[1] + local argListString, isMethod = util.getArgListString(exp) + local fullDoc, argListDoc = comments.stripArgListDoc(comments.getBefore(s.pos)) + if not argListString and argListDoc then + argListString, isMethod = comments.argListDocToMethod(argListDoc) + end + memberInfo.fullDoc = fullDoc + memberInfo.shortDoc = comments.getShortDoc(fullDoc) + memberInfo.argListString = argListString + memberInfo.isMethod = isMethod + --trace("LLLLLLLLLLLL", require"inspect"{memberInfo.memberName, processExp(env, exp), lwtk.TextLabel.getMeasures }) + end + elseif tag == "Invoke" then + local e1 = processExp(env, s[1]) + local m = processExp(env, s[2]) + if isClass and e1 == thisModule then + trace("CCCCCCCCCCCCCCCCCCCC", e1) + if m == "declare" then + for i = 3, #s do + local arg = processExp(env, s[i]) + trace("DDDDDDDDDDDDDDDDD", arg) + assert(type(arg) == "string") + --declared[arg] = declDoc + local nextPos + if i < #s then + nextPos = s[i + 1].pos + else + nextPos = s.end_pos + end + local doca = comments.getAfter(s[i].end_pos, nextPos) + local docb = comments.getBefore(s[i].pos) + if doca then + trace("FOUNDAFTER", doca) + end + if docb then + trace("FOUNDBEFORE", docb) + end + if doca and docb then + lwtk.errorf("Ambiguous comment for declaration in line %d of file %q", re.calcline(content, s[i].pos), moduleFileName) + end + end + end + end + elseif tag == "Block" then + local nextEnv = setmetatable({}, { __index = env }) + processBlock(s, nextEnv) + elseif tag == "If" then + local cond = processExp(env, s[1]) + local nextEnv = setmetatable({}, { __index = env }) + if cond then + processBlock(s[2], nextEnv) + elseif s[3] then + processBlock(s[3], nextEnv) + end + end + end + end + local env = setmetatable({}, { __index = _G }) + processBlock(ast, env) + end + if traceOut then + traceOut:close() + end + end +end +--------------------------------------------------------------------------------------------------------------------------- +do + for _, thisModuleName in ipairs(depOrderedModuleNames) do + + local thisModule = modules[thisModuleName] + local thisModuleInfo = moduleInfos[thisModuleName] + + --------------------------------------------------------------- + parseModule(thisModuleName, thisModule, thisModuleInfo) + --------------------------------------------------------------- + + -- isMethod is only known after parsing the function declaration + -- + if not thisModuleInfo.isInternal and thisModuleInfo.isClass --[[or thisModuleInfo.isMixin]] then + local methods = {} + local functions = {} + if not thisModuleInfo.memberFunctions then + error(require"inspect"{thisModuleName}) + end + for _, f in ipairs(thisModuleInfo.memberFunctions) do + local isMethod = f.isMethod + if isMethod == nil then + if not f.originalMemberInfo then + error(require"inspect"{thisModuleName, f}) + end + isMethod = f.originalMemberInfo.isMethod + assert(type(isMethod) == "boolean", f.memberName) + elseif f.originalMemberInfo then + assert(isMethod == f.originalMemberInfo.isMethod) + end + if isMethod then + add(methods, f.memberName, f) + else + add(functions, f.memberName, f) + end + end + thisModuleInfo.methods = methods + thisModuleInfo.functions = functions + end + end +end +--------------------------------------------------------------------------------------------------------------------------- +do + for _, info in ipairs(classMixinInfos) do + local subClassPaths = info.subClassPaths + table.sort(subClassPaths) + local subClassTree = {} + for _, p in ipairs(subClassPaths) do + local r = subClassTree + for n in p:gmatch("[^/]+") do + local r2 = r[n] + if not r2 then + r2 = { moduleName = n } + add(r, n, r2) + end + r = r2 + end + end + info.subClassTree = subClassTree + end +end +--------------------------------------------------------------------------------------------------------------------------- +do + local function compareMixinRealisation(a, b) + return a.pathString < b.pathString + end + for _, mixinInfo in ipairs(mixinInfos) do + local reals = mixinInfo.mixinRealisations + table.sort(reals, compareMixinRealisation) + local mixinSupers = {} + for _, r in ipairs(reals) do + local s = mixinSupers + for _, e in ipairs(r) do + local s2 = s[e.moduleName] + if not s2 then + s2 = { moduleName = e.moduleName, isMixin = e.isMixin } + add(s, e.moduleName, s2) + end + s = s2 + end + end + mixinInfo.mixinSupers = mixinSupers + end +end + +perf.stop"totalparse" + +--------------------------------------------------------------------------------------------------------------------------- + +local function sortMembers(members) + if members then + table.sort(members, function(a,b) + local an, bn = a.memberName, b.memberName + local am, bm = an:match("^_"), bn:match("^_") + if (am and bm) or (not am and not bm) then + return an < bn + else + return not am + end + end) + end +end + +local function sortInheritedMembers(superClassList) + if superClassList then + for i = #superClassList, 1, -1 do + local methods = superClassList[i] + if #methods > 0 then + sortMembers(methods) + else + table.remove(superClassList, i) + end + end + end +end + +local function sortModules(modules, deep) + table.sort(modules, function(a,b) return a.moduleName < b.moduleName end) + if deep then + for _, module in ipairs(modules) do + if module.methods then + sortMembers(module.methods) + end + if module.functions then + sortMembers(module.functions) + end + if module.inheritedMethods then + sortInheritedMembers(module.inheritedMethods) + end + end + end +end + +sortModules(moduleInfos, true) +sortModules(packageInfos) + +local function newSubstLinks(genDirPrefix) + + local linkFormat = "[%s]("..genDirPrefix.."%s.md)" + local linkPattern = ( C( (S'["' * P"lwtk.") + + (-(S'["' * P"lwtk.") * -P"lwtk." * P(1))^1 + ) + + ((P"lwtk." * (alnum + P".")^1) / + function(m) + if lwtk.tryrequire(m) then + return format(linkFormat, m, m:gsub("%.", "/")) + else + return m + end + end + ) + )^0 / function(...) return table.concat { ... } end + + return function(docString) + return lpeg.match(linkPattern, docString) + end +end + +--------------------------------------------------------------------------------------------------------------------------- +perf.start"output" + +do + local substLinks = newSubstLinks("") + + local sections = { + { "Classes", classInfos }, + { "Mixins", mixinInfos }, + { "Metas", metaInfos }, + { "Functions", functionInfos }, + { "Other", otherInfos } + } + for _, s in ipairs(sections) do + sortModules(s[2]) + for _, info in ipairs(s[2]) do + if not info.isPackage then + local packInfo = moduleInfos[info.packageName] + local infos = packInfo[s[2]] + if not infos then + infos = {} + packInfo[s[2]] = infos + end + add(infos, info.moduleName, info) + end + end + end + + local outName = "../doc/gen/modules.md" + local out = io.open(outName, "w") + do + local function pr(...) + fprintf(out, ...) + end + pr("# Module Index\n\n") + for _, p in ipairs(packageInfos) do + if not p.isInternal then + pr(" * [%s](#%s)", p.moduleName, p.moduleName:gsub("%.","")) + if p.shortDoc then + pr(" - %s", substLinks(p.shortDoc)) + end + pr("\n") + end + end + for _, p in ipairs(packageInfos) do + local packageName = p.moduleName + if not p.isInternal then + pr("\n## %s\n", packageName) + pr("\n") + for _, s in ipairs(sections) do + local infos = p[s[2]] + if infos then + pr("### %s\n", s[1]) + for _, m in ipairs(infos) do + if m.packageName == packageName then + local b = m.isClass and "**" or "" + pr(" * %s[%s](%s)%s", b, m.moduleName, m.docFileName, b) + if m.shortDoc then + pr(" - %s", substLinks(m.shortDoc)) + end + pr("\n") + end + end + end + end + end + end + end + out:close() +end +--------------------------------------------------------------------------------------------------------------------------- +do + for _, m in ipairs(moduleInfos) do + if not m.isInternal then + local genDirPrefix = string.rep("../", #m.moduleName:gsub("[^.]*(%.?)[^.]*", "%1")) + local substLinks = newSubstLinks(genDirPrefix) + local shortModuleName = m.moduleName:gsub("^lwtk%.", "") + local out = assert(io.open(path("../doc/gen", m.docFileName), "w")) + do + local function pr(...) + fprintf(out, ...) + end + local function prind(n) + for i = 1, n do + out:write(" ") + end + end + local module = modules[m.moduleName] + local tp + if type(module) == "function" then + tp = "Function " + elseif m.isClass then + tp = "Class " + elseif m.isMixin then + tp = "Mixin " + elseif m.isMeta then + tp = "Meta " + elseif type(module) == "table" then + tp = "Table " + elseif type(module) == "number" or type(module) == "string" then + tp = "" + else + error(m.moduleName) + end + pr("# %s%s\n\n", tp, m.moduleName) + if m.moduleType == "function" then + local argListString = m.argListString + if m.isMethod and argListString then + argListString = "self, "..argListString + end + pr(" * **`%s(%s)`**\n\n", shortModuleName, + argListString or "?") + if m.fullDoc then + pr(util.indent(5, substLinks(m.fullDoc))) + end + else + if m.fullDoc then + pr("%s\n", substLinks(m.fullDoc)) + end + end + ------------------------------------------------------------------------ + local contentsTitlePrinted = false + local function assureContentsTitle() + if not contentsTitlePrinted then + pr("\n") + pr("## Contents\n\n") + contentsTitlePrinted = true + end + end + local classPathList + if m.isClass then + classPathList = util.getClassPathList(module) + if #classPathList > 1 then + assureContentsTitle() + pr(" * [Inheritance](#inheritance)\n") + end + elseif m.isMixin then + if #m.mixinRealisations > 0 then + assureContentsTitle() + pr(" * [Inheritance](#inheritance)\n") + end + end + local hasNewOk, hasNew = pcall(function() return module["new"] end) + hasNew = hasNewOk and hasNew + local hasConstructor = (m.isMeta or m.isClass) and hasNew + if hasConstructor then + assureContentsTitle() + pr(" * [Constructor](#constructor)\n") + end + local methodFunctionSections = { + { "Methods", "methods", m.methods }, + { "Functions", "functions", m.functions } + } + for _, section in pairs(methodFunctionSections) do + if section[3] and #section[3] > 0 then + assureContentsTitle() + pr(" * [%s](#%s)\n", section[1], section[2]) + for _, meth in ipairs(section[3]) do + pr(" * [%s()](#.%s)", meth.memberName, meth.memberName) + if meth.shortDoc then + pr(" - %s", meth.shortDoc) + else + local orig = meth.originalMemberInfo + if orig and orig.shortDoc then + pr(" - %s", orig.shortDoc) + end + end + pr("\n") + end + end + end + if m.inheritedMethods and #m.inheritedMethods > 0 then + assureContentsTitle() + pr(" * [Inherited Methods](#inherited-methods)\n") + end + if (m.isClass or m.isMixin) and #m.subClassPaths > 0 then + assureContentsTitle() + pr(" * [Subclasses](#subclasses)\n") + end + ------------------------------------------------------------------------ + pr("\n") + if m.isClass and #classPathList > 1 then + pr("\n## Inheritance\n") + --pr(" * Super class path:\n", #classPathList>2 and "es" or "") + pr(" * ") + for i = #classPathList, 1, -1 do + pr(" / ") + local c = classPathList[i] + local cname = c.moduleName + local b = c.isMixin and "" or "**" + if cname == m.moduleName then + pr("_%s`%s`%s_", b, + cname:gsub("^lwtk%.",""), + b) + else + pr("%s[%s](%s%s.md#inheritance)%s", + b, + cname:gsub("^lwtk%.",""), + genDirPrefix, + cname:gsub("%.","/"), + b) + end + end + pr("\n") + elseif m.isMixin and #m.mixinRealisations > 0 then + pr("\n## Inheritance\n") + local function prSup(indn, sup, top) + for _, s0 in ipairs(sup) do + local s = s0 + prind(indn) pr(" * ") + if top then + pr("/ ") + end + while true do + if s ~= s0 then + pr(" / ") + end + local sname = s.moduleName + local b = s.isMixin and "" or "**" + if sname == m.moduleName then + pr("_%s`%s`%s_", b, sname:gsub("^lwtk%.",""), + b) + else + pr("%s[%s](%s%s.md#inheritance)%s", b, sname:gsub("^lwtk%.",""), + genDirPrefix, + sname:gsub("%.","/"), + b) + end + if #s ~= 1 then + break + end + s = s[1] + end + if #s > 1 then + pr(" /\n") + prSup(indn + 5, s) + else + pr("\n") + end + end + end + prSup(0, m.mixinSupers, true) + end + if hasConstructor then + pr("\n## Constructor\n") + if m.isMeta or module.declared["new"] then + local newInfo = assert(m.memberInfos["new"]) + local argListString = newInfo.argListString + pr(" * **`%s(%s)`**\n\n", ".new", shortModuleName, + argListString or "?") + if newInfo.fullDoc then + pr(util.indent(5, newInfo.fullDoc)) + pr("\n") + end + local overrideList = m.isClass and util.getOverrideList(module, "new") + if overrideList then + local indent = " " + --pr("%s * Overrides:\n", indent) + for i, ov in ipairs(overrideList) do + local b = ov.isMixin and "" or "**" + pr("%s * %s: %s[%s()](%s%s.md#constructor)%s\n", string.rep(indent, i), + ov.overrideText, + b, + ov.moduleName:gsub("^lwtk%.", ""), + genDirPrefix, + ov.moduleName:gsub("%.", "/"), + b) + end + pr("\n") + end + else + local inheritedFrom = util.findDeclaratingSuperClass(module, "new") + local inheritedFromInfo = assert(moduleInfos[inheritedFrom]) + local newInfo = assert(inheritedFromInfo.memberInfos["new"]) + local argListString = newInfo.argListString + pr(" * **`%s(%s)`**\n\n", ".new", shortModuleName, + argListString or "?") + local b = inheritedFromInfo.isClass and "**" or "" + pr(" * Inherited from: %s[%s()](%s%s.md#constructor)%s\n", b, inheritedFrom.__name:gsub("^lwtk%.",""), + genDirPrefix, + inheritedFrom.__name:gsub("%.", "/"), + b) + end + pr("\n") + end + for _, section in pairs(methodFunctionSections) do + if section[3] and #section[3] > 0 then + pr("\n## %s\n", section[1]) + for _, meth in ipairs(section[3]) do + --print("#####################", require"inspect"{meth.methodName, moduleDoc.membersDoc}) + local argListString = meth.argListString + local isMethod = meth.isMethod + local original = meth.originalMemberInfo + if not argListString and original then + argListString = original.argListString + isMethod = original.isMethod + end + local sep = isMethod and ":" or "." + pr(" * **`%s%s%s(%s)`**\n\n", "."..meth.memberName, shortModuleName, sep, meth.memberName, + argListString or "?") + if meth.fullDoc then + pr(util.indent(5, meth.fullDoc)) + pr("\n") + elseif original and original.fullDoc then + pr(util.indent(5, original.fullDoc)) + pr("\n") + end + if original then + if original.isModule then + pr(" * Implementation: [%s()](%s%s.md)\n", + original.moduleName, + genDirPrefix, + original.moduleName:gsub("%.","/")) + else + pr(" * Implementation: [%s:%s()](%s%s.md#%s)\n", + original.moduleName:gsub("^lwtk%.",""), + original.memberName, + genDirPrefix, + original.moduleName:gsub("%.","/"), + original.memberName) + end + end + if meth.overrideList then + local indent = " " + for i, ov in ipairs(meth.overrideList) do + pr("%s * %s: [%s:%s()](%s%s.md#.%s)\n", string.rep(indent, i), + ov.overrideText, + ov.moduleName:gsub("^lwtk%.", ""), + meth.memberName, + genDirPrefix, + ov.moduleName:gsub("%.", "/"), + meth.memberName) + end + pr("\n") + end + pr("\n") + end + end + end + if m.inheritedMethods and #m.inheritedMethods > 0 then + pr("\n## Inherited Methods\n") + for _, fromList in ipairs(m.inheritedMethods) do + local b = fromList.isMixin and "" or "**" + local fromFile = format("%s%s.md", genDirPrefix, fromList.moduleName:gsub("%.", "/")) + pr(" * %s[%s](%s)%s:\n", b, fromList.moduleName:gsub("^lwtk%.",""), fromFile, b) + pr(" * ") + for i, fr in ipairs(fromList) do + if i > 1 then pr(", ") end + pr("[%s()](%s#.%s)", fr.memberName, fromFile, fr.memberName) + end + pr("\n") + end + end + if (m.isClass or m.isMixin) and #m.subClassPaths > 0 then + pr("\n## Subclasses\n") + --pr(" * Sub class path%s:\n", #m.subClassTree[1] > 1 and "s" or "") + local function prSub(indn, sub, top) + for _, s0 in ipairs(sub) do + local s = s0 + prind(indn) pr(" * ") + if top then + pr("/ ") + end + while true do + if s ~= s0 then + pr(" / ") + end + local sname = s.moduleName + local sinfo = moduleInfos[sname] + local b = sinfo.isMixin and "" or "**" + local hasSubclass = sinfo.subClassPaths and #sinfo.subClassPaths > 0 + if m.moduleName == sname then + pr("_%s`%s`%s_", b, sname:gsub("^lwtk%.",""), + b) + else + pr("%s[%s](%s%s.md#%s)%s", b, sname:gsub("^lwtk%.",""), + genDirPrefix, + sname:gsub("%.","/"), + hasSubclass and "subclasses" or "inheritance", + b) + end + if #s ~= 1 then + break + end + s = s[1] + end + if #s > 1 then + pr(" /\n") + prSub(indn + 5, s) + else + pr("\n") + end + end + end + prSub(0, m.subClassTree, true) + --pr("%s", pprint.pformat(m.subClassTree)) + pr("\n") + end + end + out:close() + end + end +end +perf.stop"output" +--------------------------------------------------------------------------------------------------------------------------- + +perf.finish() diff --git a/src/mkdoc/pprint.lua b/src/mkdoc/pprint.lua new file mode 100644 index 0000000..d08b5e6 --- /dev/null +++ b/src/mkdoc/pprint.lua @@ -0,0 +1,518 @@ +-- https://github.com/jagt/pprint.lua +--[[ +Chen Tao - jagttt@gmail.com + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 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. + +For more information, please refer to +--]] +local pprint = { VERSION = '0.1' } + +local depth = 1 + +pprint.defaults = { + -- If set to number N, then limit table recursion to N deep. + depth_limit = false, + -- type display trigger, hide not useful datatypes by default + -- custom types are treated as table + show_nil = true, + show_boolean = true, + show_number = true, + show_string = true, + show_table = true, + show_function = false, + show_thread = false, + show_userdata = false, + -- additional display trigger + show_metatable = false, -- show metatable + show_all = false, -- override other show settings and show everything + use_tostring = false, -- use __tostring to print table if available + filter_function = nil, -- called like callback(value[,key, parent]), return truty value to hide + object_cache = 'local', -- cache blob and table to give it a id, 'local' cache per print, 'global' cache + -- per process, falsy value to disable (might cause infinite loop) + -- format settings + indent_size = 2, -- indent for each nested table level + level_width = 80, -- max width per indent level + wrap_string = true, -- wrap string when it's longer than level_width + wrap_array = true, -- wrap every array elements + sort_keys = true, -- sort table keys +} + +local TYPES = { + ['nil'] = 1, ['boolean'] = 2, ['number'] = 3, ['string'] = 4, + ['table'] = 5, ['function'] = 6, ['thread'] = 7, ['userdata'] = 8 +} + +-- seems this is the only way to escape these, as lua don't know how to map char '\a' to 'a' +local ESCAPE_MAP = { + ['\a'] = '\\a', ['\b'] = '\\b', ['\f'] = '\\f', ['\n'] = '\\n', ['\r'] = '\\r', + ['\t'] = '\\t', ['\v'] = '\\v', ['\\'] = '\\\\', +} + +-- generic utilities +local function escape(s) + s = s:gsub('([%c\\])', ESCAPE_MAP) + local dq = s:find('"') + local sq = s:find("'") + if dq and sq then + return s:gsub('"', '\\"'), '"' + elseif sq then + return s, '"' + else + return s, "'" + end +end + +local function is_plain_key(key) + return type(key) == 'string' and key:match('^[%a_][%a%d_]*$') +end + +local CACHE_TYPES = { + ['table'] = true, ['function'] = true, ['thread'] = true, ['userdata'] = true +} + +-- cache would be populated to be like: +-- { +-- function = { `fun1` = 1, _cnt = 1 }, -- object id +-- table = { `table1` = 1, `table2` = 2, _cnt = 2 }, +-- visited_tables = { `table1` = 7, `table2` = 8 }, -- visit count +-- } +-- use weakrefs to avoid accidentall adding refcount +local function cache_apperance(obj, cache, option) + if not cache.visited_tables then + cache.visited_tables = setmetatable({}, {__mode = 'k'}) + end + local t = type(obj) + + -- TODO can't test filter_function here as we don't have the ix and key, + -- might cause different results? + -- respect show_xxx and filter_function to be consistent with print results + if (not TYPES[t] and not option.show_table) + or (TYPES[t] and not option['show_'..t]) then + return + end + + if CACHE_TYPES[t] or TYPES[t] == nil then + if not cache[t] then + cache[t] = setmetatable({}, {__mode = 'k'}) + cache[t]._cnt = 0 + end + if not cache[t][obj] then + cache[t]._cnt = cache[t]._cnt + 1 + cache[t][obj] = cache[t]._cnt + end + end + if t == 'table' or TYPES[t] == nil then + if cache.visited_tables[obj] == false then + -- already printed, no need to mark this and its children anymore + return + elseif cache.visited_tables[obj] == nil then + cache.visited_tables[obj] = 1 + else + -- visited already, increment and continue + cache.visited_tables[obj] = cache.visited_tables[obj] + 1 + return + end + for k, v in pairs(obj) do + cache_apperance(k, cache, option) + cache_apperance(v, cache, option) + end + local mt = getmetatable(obj) + if mt and option.show_metatable then + cache_apperance(mt, cache, option) + end + end +end + +-- makes 'foo2' < 'foo100000'. string.sub makes substring anyway, no need to use index based method +local function str_natural_cmp(lhs, rhs) + while #lhs > 0 and #rhs > 0 do + local lmid, lend = lhs:find('%d+') + local rmid, rend = rhs:find('%d+') + if not (lmid and rmid) then return lhs < rhs end + + local lsub = lhs:sub(1, lmid-1) + local rsub = rhs:sub(1, rmid-1) + if lsub ~= rsub then + return lsub < rsub + end + + local lnum = tonumber(lhs:sub(lmid, lend)) + local rnum = tonumber(rhs:sub(rmid, rend)) + if lnum ~= rnum then + return lnum < rnum + end + + lhs = lhs:sub(lend+1) + rhs = rhs:sub(rend+1) + end + return lhs < rhs +end + +local function cmp(lhs, rhs) + local tleft = type(lhs) + local tright = type(rhs) + if tleft == 'number' and tright == 'number' then return lhs < rhs end + if tleft == 'string' and tright == 'string' then return str_natural_cmp(lhs, rhs) end + if tleft == tright then return str_natural_cmp(tostring(lhs), tostring(rhs)) end + + -- allow custom types + local oleft = TYPES[tleft] or 9 + local oright = TYPES[tright] or 9 + return oleft < oright +end + +-- setup option with default +local function make_option(option) + if option == nil then + option = {} + end + for k, v in pairs(pprint.defaults) do + if option[k] == nil then + option[k] = v + end + if option.show_all then + for t, _ in pairs(TYPES) do + option['show_'..t] = true + end + option.show_metatable = true + end + end + return option +end + +-- override defaults and take effects for all following calls +function pprint.setup(option) + pprint.defaults = make_option(option) +end + +-- format lua object into a string +function pprint.pformat(obj, option, printer) + option = make_option(option) + local buf = {} + local function default_printer(s) + table.insert(buf, s) + end + printer = printer or default_printer + + local cache + if option.object_cache == 'global' then + -- steal the cache into a local var so it's not visible from _G or anywhere + -- still can't avoid user explicitly referentce pprint._cache but it shouldn't happen anyway + cache = pprint._cache or {} + pprint._cache = nil + elseif option.object_cache == 'local' then + cache = {} + end + + local last = '' -- used for look back and remove trailing comma + local status = { + indent = '', -- current indent + len = 0, -- current line length + } + + local wrapped_printer = function(s) + printer(last) + last = s + end + + local function _indent(d) + status.indent = string.rep(' ', d + #(status.indent)) + end + + local function _n(d) + wrapped_printer('\n') + wrapped_printer(status.indent) + if d then + _indent(d) + end + status.len = 0 + return true -- used to close bracket correctly + end + + local function _p(s, nowrap) + status.len = status.len + #s + if not nowrap and status.len > option.level_width then + _n() + wrapped_printer(s) + status.len = #s + else + wrapped_printer(s) + end + end + + local formatter = {} + local function format(v) + local f = formatter[type(v)] + f = f or formatter.table -- allow patched type() + if option.filter_function and option.filter_function(v, nil, nil) then + return '' + else + return f(v) + end + end + + local function tostring_formatter(v) + return tostring(v) + end + + local function number_formatter(n) + return n == math.huge and '[[math.huge]]' or tostring(n) + end + + local function nop_formatter(v) + return '' + end + + local function make_fixed_formatter(t, has_cache) + if has_cache then + return function (v) + return string.format('[[%s %d]]', t, cache[t][v]) + end + else + return function (v) + return '[['..t..']]' + end + end + end + + local function string_formatter(s, force_long_quote) + local s, quote = escape(s) + local quote_len = force_long_quote and 4 or 2 + if quote_len + #s + status.len > option.level_width then + _n() + -- only wrap string when is longer than level_width + if option.wrap_string and #s + quote_len > option.level_width then + -- keep the quotes together + _p('[[') + while #s + status.len >= option.level_width do + local seg = option.level_width - status.len + _p(string.sub(s, 1, seg), true) + _n() + s = string.sub(s, seg+1) + end + _p(s) -- print the remaining parts + return ']]' + end + end + + return force_long_quote and '[['..s..']]' or quote..s..quote + end + + local function table_formatter(t) + if option.use_tostring then + local mt = getmetatable(t) + if mt and mt.__tostring then + return string_formatter(tostring(t), true) + end + end + + local print_header_ix = nil + local ttype = type(t) + if option.object_cache then + local cache_state = cache.visited_tables[t] + local tix = cache[ttype][t] + -- FIXME should really handle `cache_state == nil` + -- as user might add things through filter_function + if cache_state == false then + -- already printed, just print the the number + return string_formatter(string.format('%s %d', ttype, tix), true) + elseif cache_state > 1 then + -- appeared more than once, print table header with number + print_header_ix = tix + cache.visited_tables[t] = false + else + -- appeared exactly once, print like a normal table + end + end + + local limit = tonumber(option.depth_limit) + if limit and depth > limit then + if print_header_ix then + return string.format('[[%s %d]]...', ttype, print_header_ix) + end + return string_formatter(tostring(t), true) + end + + local tlen = #t + local wrapped = false + _p('{') + _indent(option.indent_size) + _p(string.rep(' ', option.indent_size - 1)) + if print_header_ix then + _p(string.format('--[[%s %d]] ', ttype, print_header_ix)) + end + local wrap_array = option.wrap_array + if wrap_array then + local allvalues = true + for ix = 1,tlen do + local tp = type(t[ix]) + if tp ~= "string" and tp ~= "number" and tp ~= "boolean" then + allvalues = false + break + end + end + if allvalues then + wrap_array = false + end + end + for ix = 1,tlen do + local v = t[ix] + if formatter[type(v)] == nop_formatter or + (option.filter_function and option.filter_function(v, ix, t)) then + -- pass + else + if wrap_array then + wrapped = _n() + end + depth = depth+1 + _p(format(v)..', ') + depth = depth-1 + end + end + + -- hashmap part of the table, in contrast to array part + local function is_hash_key(k) + if type(k) ~= 'number' then + return true + end + + local numkey = math.floor(tonumber(k)) + if numkey ~= k or numkey > tlen or numkey <= 0 then + return true + end + end + + local function print_kv(k, v, t) + -- can't use option.show_x as obj may contain custom type + if formatter[type(v)] == nop_formatter or + formatter[type(k)] == nop_formatter or + (option.filter_function and option.filter_function(v, k, t)) then + return + end + wrapped = _n() + if is_plain_key(k) then + _p(k, true) + else + _p('[') + -- [[]] type string in key is illegal, needs to add spaces inbetween + local k = format(k) + if string.match(k, '%[%[') then + _p(' '..k..' ', true) + else + _p(k, true) + end + _p(']') + end + _p(' = ', true) + depth = depth+1 + _p(format(v), true) + depth = depth-1 + _p(',', true) + end + + if option.sort_keys then + local keys = {} + for k, _ in pairs(t) do + if is_hash_key(k) then + table.insert(keys, k) + end + end + table.sort(keys, cmp) + for _, k in ipairs(keys) do + print_kv(k, t[k], t) + end + else + for k, v in pairs(t) do + if is_hash_key(k) then + print_kv(k, v, t) + end + end + end + + if option.show_metatable then + local mt = getmetatable(t) + if mt then + print_kv('__metatable', mt, t) + end + end + + _indent(-option.indent_size) + -- make { } into {} + last = string.gsub(last, '^ +$', '') + -- peek last to remove trailing comma + last = string.gsub(last, ',%s*$', ' ') + if wrapped then + _n() + end + _p('}') + + return '' + end + + -- set formatters + formatter['nil'] = option.show_nil and tostring_formatter or nop_formatter + formatter['boolean'] = option.show_boolean and tostring_formatter or nop_formatter + formatter['number'] = option.show_number and number_formatter or nop_formatter -- need to handle math.huge + formatter['function'] = option.show_function and make_fixed_formatter('function', option.object_cache) or nop_formatter + formatter['thread'] = option.show_thread and make_fixed_formatter('thread', option.object_cache) or nop_formatter + formatter['userdata'] = option.show_userdata and make_fixed_formatter('userdata', option.object_cache) or nop_formatter + formatter['string'] = option.show_string and string_formatter or nop_formatter + formatter['table'] = option.show_table and table_formatter or nop_formatter + + if option.object_cache then + -- needs to visit the table before start printing + cache_apperance(obj, cache, option) + end + + _p(format(obj)) + printer(last) -- close the buffered one + + -- put cache back if global + if option.object_cache == 'global' then + pprint._cache = cache + end + + return table.concat(buf) +end + +-- pprint all the arguments +function pprint.pprint( ... ) + local args = {...} + -- select will get an accurate count of array len, counting trailing nils + local len = select('#', ...) + for ix = 1,len do + pprint.pformat(args[ix], nil, io.write) + io.write('\n') + end +end + +setmetatable(pprint, { + __call = function (_, ...) + pprint.pprint(...) + end +}) + +return pprint + diff --git a/src/mkdoc/util.lua b/src/mkdoc/util.lua new file mode 100644 index 0000000..06f6998 --- /dev/null +++ b/src/mkdoc/util.lua @@ -0,0 +1,141 @@ +local lwtk = require"lwtk" + +local insert = table.insert +local getMixinBase = lwtk.get.mixinBase + +local util = {} + +function util.findDeclaratingSuperClass(thisClass, memberName) + local s = thisClass:getSuperClass() + while s do + if s.declared[memberName] then + return s + end + s = s:getSuperClass() + end +end + + +function util.getClassModuleName(class) + local name = class.__name + local mixinBase = getMixinBase[class] + if mixinBase then + return mixinBase.__name + else + return name + end + +end +local getModuleName = util.getClassModuleName + +function util.getOverrideList(thisClass, memberName) + local rslt = {} + local s = thisClass:getSuperClass() + while s do + if s.declared[memberName] then + local overrideText = (s[memberName] == false) and "Implements" or "Overrides" + local entry = { moduleName = getModuleName(s), overrideText = overrideText, isMixin = getMixinBase[s] and true } + rslt[s.__name] = entry + rslt[#rslt + 1] = entry + end + s = s:getSuperClass() + end + if #rslt > 0 then + return rslt + end +end + +function util.getSuperClassList(thisClass, endClass) + local rslt = {} + local s = thisClass:getSuperClass() + while s do + local entry = { moduleName = getModuleName(s), isMixin = getMixinBase[s] and true } + rslt[#rslt + 1] = entry + if endClass and s == endClass then + break + end + s = s:getSuperClass() + end + return rslt +end + +function util.getNonMixinSuperClassWithList(thisClass) + local list = {} + local s = thisClass:getSuperClass() + while s do + list[#list + 1] = s.__name + if getMixinBase[s] == nil then + return s, list + end + s = s:getSuperClass() + end +end + +function util.getClassPathList(thisClass, endClass) + local rslt = {} + local s = thisClass + while s do + local entry = { moduleName = getModuleName(s), isMixin = getMixinBase[s] and true } + rslt[s.__name] = entry + rslt[#rslt + 1] = entry + if endClass and s == endClass then + break + end + s = s:getSuperClass() + end + return rslt +end + +function util.getReverseClassPathList(thisClass, endClass) + local list = util.getClassPathList(thisClass, endClass) + local rslt = {} + local n = #list + for i, e in ipairs(list) do + rslt[n-i+1] = e + end + return rslt +end + +function util.getReverseClassPathString(thisClass, endClass) + local list = util.getClassPathList(thisClass, endClass) + local rslt = {} + local n = #list + for i, e in ipairs(list) do + rslt[n-i+1] = e.moduleName + end + return table.concat(rslt, "/") +end + +function util.classPathListToString(list) + local rslt = {} + for i, e in ipairs(list) do + rslt[i] = e.moduleName + end + return table.concat(rslt, "/") +end + + +function util.indent(indent, comment) + local indentSting = string.rep(" ", indent) + return comment:gsub("^", indentSting):gsub("\n", "\n"..indentSting) +end + +function util.getArgListString(exp) + if exp and exp.tag == "Function" then + local argl = exp[1] + local isMethod = (#argl >= 1 and argl[1][1] == "self") + local rslt = {} + for i = isMethod and 2 or 1, #argl do + if argl[i].tag == "Dots" then + rslt[#rslt + 1] = "..." + else + assert(argl[i].tag == "Id", require"inspect"{argl[i]}) + rslt[#rslt + 1] = argl[i][1] + end + end + return table.concat(rslt, ", "), isMethod + end +end + + +return util diff --git a/src/perf.lua b/src/perf.lua new file mode 100644 index 0000000..7377915 --- /dev/null +++ b/src/perf.lua @@ -0,0 +1,79 @@ +local time = require"chronos".nanotime -- https://luarocks.org/modules/ldrumm/chronos + +local perf = {} + +local t0 +local timers = {} + +function perf.reset() + t0 = nil + timers = {} +end + +function perf.start(name) + if not t0 then + t0 = time() + end + local timer = timers[name] + if not timer then + local timer = { name = name, t0 = time(), dt = 0, count = 1, started = 1 } + timers[name] = timer + timers[#timers + 1] = timer + else + local started = timer.started + if started > 0 then + timer.started = started + 1 + else + timer.t0 = time() + timer.started = 1 + end + timer.count = timer.count + 1 + end +end + +function perf.stop(name) + local timer = timers[name] + local started = timer.started + started = started - 1 + if started == 0 then + local dt = time() - timer.t0 + timer.dt = timer.dt + dt + end + timer.started = started +end + +function perf.finish() + print("----------------------------------------------------------------------------") + local t1 = time() + local nlen = 0 + local tlen = 0 + local clen = 0 + do + for _, timer in ipairs(timers) do + local len = #timer.name + if len > nlen then + nlen = len + end + local len = #string.format("%d", math.ceil(timer.dt * 1000)) + local len = #string.format("%d", timer.count) + if len > clen then + clen = len + end + end + nlen = nlen + 8 + tlen = 4 + #string.format("%d", math.ceil((t1 - t0) * 1000)) + end + for _, timer in ipairs(timers) do + local name = timer.name + io.write(string.format("%"..nlen.."s %"..tlen..".3f ms for %"..clen.."d", name..":", timer.dt * 1000, timer.count)) + if timer.count > 1 then + io.write(string.format(" (avg: %.3f ms)", timer.dt * 1000 / timer.count)) + end + io.write("\n") + assert(timer.started == 0) + end + print(string.format("%"..nlen.."s %"..tlen..".3f ms", "total:", (t1 - t0) * 1000)) + print("----------------------------------------------------------------------------") +end + +return perf \ No newline at end of file diff --git a/src/printclasses.lua b/src/printclasses.lua index d0afc95..814c052 100755 --- a/src/printclasses.lua +++ b/src/printclasses.lua @@ -8,7 +8,7 @@ local format = string.format local lwtk = require("lwtk") local lfs = require("lfs") -local getSuperClass = lwtk.getSuperClass +lwtk.NDEBUG = true local moduleNames = {} @@ -26,12 +26,6 @@ collect("lwtk/internal") collect("lwtk/lpugl") collect("lwtk/love") -local function getFullPath(c) - local s = getSuperClass(c) - local p = s and getFullPath(s)..">" or "" - return p..c.__name:match("^lwtk%.(.*)$") -end - table.sort(moduleNames) local maxl = 0 @@ -46,7 +40,7 @@ for i = 1, #moduleNames do if #n > maxl then maxl = #n end - classpaths[#classpaths + 1] = getFullPath(m) + classpaths[#classpaths + 1] = m:getReverseClassPath():gsub("([/#])lwtk%.", "%1") stylepaths[#stylepaths + 1] = lwtk.get.stylePath[m] end end diff --git a/src/test01.lua b/src/test01.lua index 4c85afc..e30dbd5 100644 --- a/src/test01.lua +++ b/src/test01.lua @@ -62,13 +62,17 @@ local app = lwtk.Application("test01.lua", lwtk.Style { local MyGroup = lwtk.newClass("MyGroup", lwtk.Group) +MyGroup:declare("color") + local MyBox = lwtk.newClass("MyBox", lwtk.Widget) +MyBox:declare("color") + function MyBox:setColor(color) self.color = color end -function MyBox:onDraw(ctx) +function MyBox.override:onDraw(ctx) local c = self:getStyleParam("Color") if self.id == "mb1" then --do @@ -79,14 +83,14 @@ function MyBox:onDraw(ctx) end MyGroup.setColor = MyBox.setColor -MyGroup.onDraw = MyBox.onDraw +MyGroup.override.onDraw = MyBox.onDraw -function MyBox:onMouseEnter(x, y) +function MyBox.override:onMouseEnter(x, y) -- print(self.id, "move", x, y) self:setState("hover", true) end -function MyBox:onMouseLeave(x, y) +function MyBox.override:onMouseLeave(x, y) -- print(self.id, "leave", x, y) self:setState("hover", false) end @@ -120,13 +124,13 @@ local win1 = app:newWindow { print(win1:childById("b1")) print(win1:childById("mb1")) -assert(win1:childById("mb1").__name == "MyBox") -assert(win1:childById("b1").__name == "lwtk.Button") -assert(win1:childById("b2").__name == "lwtk.PushButton") -assert(win1:childById("b2"):is(PushButton)) -assert(win1:childById("b2"):is(Button)) -assert(win1:childById("b1"):is(Button)) -assert(not win1:childById("b1"):is(PushButton)) +assert(lwtk.type(win1:childById("mb1")) == "MyBox") +assert(lwtk.type(win1:childById("b1")) == "lwtk.Button") +assert(lwtk.type(win1:childById("b2")) == "lwtk.PushButton") +assert(win1:childById("b2"):isInstanceOf(PushButton)) +assert(win1:childById("b2"):isInstanceOf(Button)) +assert(win1:childById("b1"):isInstanceOf(Button)) +assert(not win1:childById("b1"):isInstanceOf(PushButton)) local g1a = Group { id = "g1", @@ -144,7 +148,7 @@ g:addChild(g1a) print(g:addChild(Button { id = "b3" })) print(g:addChild(Button()):getStyleParam"borderColor") local b = g:addChild(PushButton()) -print(b, b.__name, b.className) +print(b, lwtk.type(b), getmetatable(b).__name) b.state.xxx = true print(b:getStyleParam"borderColor") win1:show() diff --git a/src/test03a.lua b/src/test03a.lua index 2ba5fd4..36254c2 100644 --- a/src/test03a.lua +++ b/src/test03a.lua @@ -11,22 +11,24 @@ local newClass = lwtk.newClass local MyBox = newClass("MyBox", lwtk.Widget) do - function MyBox:onDraw(ctx) + MyBox:declare("measures") + + function MyBox.implement:onDraw(ctx) local w, h = self:getSize() ctx:fillRect(self:getStyleParam("Color"), 0, 0, w, h) end - function MyBox:setMeasures(m) - self.measures = m - end - function MyBox:getMeasures() + function MyBox.implement:getMeasures() local m = self.measures return m[1], m[2], m[3], m[4], m[5], m[6] end + function MyBox:setMeasures(m) + self.measures = m + end end local MyColumn = newClass("MyColumn", Column) do - function MyColumn:onDraw(ctx) + function MyColumn.override:onDraw(ctx) local w, h = self:getSize() ctx:fillRect(self:getStyleParam("Color"), 0, 0, w, h) end diff --git a/src/test03b.lua b/src/test03b.lua index cee5256..bfa8667 100644 --- a/src/test03b.lua +++ b/src/test03b.lua @@ -6,18 +6,19 @@ local Widget = lwtk.Widget local Color = lwtk.Color local Row = lwtk.Row local newClass = lwtk.newClass -local fillRect = lwtk.draw.fillRect local MyBox = newClass("MyBox", lwtk.Widget) do - function MyBox:onDraw(ctx) + MyBox:declare("measures") + + function MyBox.implement:onDraw(ctx) local w, h = self:getSize() - fillRect(ctx, self:getStyleParam("Color"), 0, 0, w, h) + ctx:fillRect(self:getStyleParam("Color"), 0, 0, w, h) end function MyBox:setMeasures(m) self.measures = m end - function MyBox:getMeasures() + function MyBox.implement:getMeasures() local m = self.measures return m[1], m[2], m[3], m[4], m[5], m[6] end @@ -25,9 +26,9 @@ end local MyRow = newClass("MyRow", Row) do - function MyRow:onDraw(ctx) + function MyRow.implement:onDraw(ctx) local w, h = self:getSize() - fillRect(ctx, self:getStyleParam("Color"), 0, 0, w, h) + ctx:fillRect(self:getStyleParam("Color"), 0, 0, w, h) end end diff --git a/src/tests/test01.lua b/src/tests/test01.lua index 5dbe430..a388ec4 100644 --- a/src/tests/test01.lua +++ b/src/tests/test01.lua @@ -1,4 +1,5 @@ local lua_version = _VERSION:match("[%d%.]*$") +local isLua51 = (lua_version == "5.1") local isOldLua = (#lua_version == 3 and lua_version < "5.3") ------------------------------------------------------------------------------------------- @@ -28,15 +29,16 @@ end PRINT("----------------------------------------------------------------------------------") do - local M1 = lwtk.newMixin("M1") - function M1.initClass(M1, Super) -- luacheck: ignore 431/M1 - function M1:new(value) - Super.new(self, 1000 + value) + local M1 = lwtk.newMixin("M1", + function(M1, Super) + function M1.override:new(value) + Super.new(self, 1000 + value) + end + function M1.override:getValue() + return 1000 + Super.getValue(self) + end end - function M1:getValue() - return 1000 + Super.getValue(self) - end - end + ) function M1:getValue2() return 555 end @@ -45,12 +47,13 @@ do assert(not M1:isInstanceOf(lwtk.Object)) assert(not M1:isInstanceOf(lwtk.Class)) assert(lwtk.isInstanceOf(M1, lwtk.Mixin)) - assert(tostring(M1) == "lwtk.Mixin(M1)") + assert(tostring(M1) == "lwtk.Mixin") local C1 = lwtk.newClass("C1") assert(C1:isInstanceOf(lwtk.Class)) assert(not C1:isInstanceOf(lwtk.Object)) assert(not C1:isInstanceOf(lwtk.Mixin)) assert(lwtk.isInstanceOf(C1, lwtk.Class)) + C1.value = false function C1:new(value) self.value = value + 1 end @@ -58,7 +61,7 @@ do return self.value + 1 end assert(lwtk.type(C1) == "lwtk.Class") - assert(tostring(C1) == "C1") + assert(tostring(C1) == "lwtk.Class") local c1 = C1(100) @@ -67,11 +70,8 @@ do assert(not c1:isInstanceOf(lwtk.Class)) assert(not c1:isInstanceOf(lwtk.Mixin)) assert(lwtk.Object.isInstanceOf(c1, lwtk.Object)) - assert(lwtk.Object.super == nil) assert(getSuperClass(lwtk.Object) == nil) - assert(C1.super == nil) assert(getSuperClass(C1) == lwtk.Object) - assert(c1.super == nil) assert(getSuperClass(c1) == nil) assert(lwtk.type(c1) == "C1") @@ -81,24 +81,24 @@ do local M1C1 = M1(C1) assertEq(lwtk.type(M1C1), "lwtk.Class") - assertEq(tostring(M1C1), "M1") + assertEq(tostring(M1C1), "lwtk.Class") assertEq(getSuperClass(M1C1), C1) local M1C1_2 = M1(C1) assertEq(lwtk.type(M1C1_2), "lwtk.Class") - assertEq(tostring(M1C1_2), "M1") + assertEq(tostring(M1C1_2), "lwtk.Class") assertEq(getSuperClass(M1C1_2), C1) assertEq(M1C1_2, M1C1) local m1c1 = M1C1(100) - assertEq(lwtk.type(m1c1), "M1") + assertEq(lwtk.type(m1c1), "M1(C1)") assert(m1c1:getValue(), 2102) assert(m1c1:getValue(), 2102) assert(m1c1:getValue2(), 555) local C2 = lwtk.newClass("C2", M1(C1)) assertEq(lwtk.type(C2), "lwtk.Class") - assertEq(tostring(C2), "C2") + assertEq(tostring(C2), "lwtk.Class") assertEq(getSuperClass(C2), M1C1) local c2 = C2(200) @@ -106,17 +106,21 @@ do assert(c2:getValue(), 2202) assert(c2:getValue(), 2202) - local C3 = lwtk.newClass("C3", M1(M1(C1))) - assertEq(lwtk.type(C3), "lwtk.Class") - assertEq(tostring(C3), "C3") - assertEq(lwtk.type(getSuperClass(C3)), "lwtk.Class") - assertEq(tostring(getSuperClass(C3)), "M1") - assertEq(getSuperClass(C3), M1(M1(C1))) - - local c3 = C3(300) - assertEq(lwtk.type(c3), "C3") - assert(c3:getValue(), 2304) - assert(c3:getValue(), 2304) + assert(not pcall(function() lwtk.newClass("C3", M1(M1(C1))) end)) +end +PRINT("----------------------------------------------------------------------------------") +do + local T = setmetatable({}, { __mode = "v" }) + T.C1 = lwtk.newClass("C1") + collectgarbage() + if isLua51 then + assert(T.C1 ~= nil) + lwtk.undef(T.C1) + collectgarbage() + assert(T.C1 == nil) + else + assert(T.C1 == nil) + end end PRINT("----------------------------------------------------------------------------------") do @@ -136,12 +140,13 @@ do assert(C1.a == "a1") assert(C1.extra.b == "b1") assert(c1.a == "a1") - assert(c1.extra.b == "b1") + assert(not pcall(function() return c1.extra end)) + assert(C1.extra.b == "b1") assert(C2.a == "a1") - assert(C2.extra == nil) + assert(next(C2.extra) == nil) assert(c2.a == "a1") - assert(c2.extra == nil) + assert(not pcall(function() return c2.extra end)) local C3 = lwtk.newClass("C3", C1) C3.extra = {} @@ -149,53 +154,68 @@ do local c3 = C3() assert(c3:m1(2) == 3) assert(C3.extra.c == "c3") - assert(c3.extra.c == "c3") + assert(not pcall(function() return c3.extra end)) end +if isLua51 then + lwtk.undef("C1") -- for Lua 5.1 + lwtk.undef("C2") -- for Lua 5.1 +end +collectgarbage() PRINT("----------------------------------------------------------------------------------") do - local M1 = lwtk.newMixin("M1") - function M1.initClass(M1, Super) -- luacheck: ignore 431/M1 - end - local M2 = lwtk.newMixin("M2", M1) - function M2.initClass(M2, Super) -- luacheck: ignore 431/M2 - end + local M1 = lwtk.newMixin("M1", + function(M1, Super) + end + ) + local M2 = lwtk.newMixin("M2", M1, + function(M2, Super) + end + ) assertEq(lwtk.type(M2), "lwtk.Mixin") - assertEq(tostring(M2), "lwtk.Mixin(M2)") + assertEq(tostring(M2), "lwtk.Mixin") local C1 = lwtk.newClass("C1") assertEq(lwtk.type(C1), "lwtk.Class") local M2C1 = M2(C1) assertEq(lwtk.type(M2C1), "lwtk.Class") local C2 = lwtk.newClass("C2", M2C1) assertEq(lwtk.type(C2), "lwtk.Class") - assertEq(tostring(C2), "C2") - assertEq(tostring(getSuperClass(C2)), "M2") - assertEq(tostring(getSuperClass(getSuperClass(C2))), "M1") - assertEq(tostring(getSuperClass(getSuperClass(getSuperClass(C2)))), "C1") + assertEq(tostring(C2), "lwtk.Class") + assertEq(tostring(getSuperClass(C2)), "lwtk.Class") + assertEq(tostring(getSuperClass(getSuperClass(C2))), "lwtk.Class") + assertEq(tostring(getSuperClass(getSuperClass(getSuperClass(C2)))), "lwtk.Class") +end +if isLua51 then + lwtk.undef("C1") -- for Lua 5.1 + lwtk.undef("C2") -- for Lua 5.1 end +collectgarbage() PRINT("----------------------------------------------------------------------------------") do - local M1 = lwtk.newMixin("M1") - function M1.initClass(M1, Super) -- luacheck: ignore 431/M1 - end - local M2 = lwtk.newMixin("M2") - function M2.initClass(M2, Super) -- luacheck: ignore 431/M2 - end - local M3 = lwtk.newMixin("M3", M1, M2) - function M3.initClass(M3, Super) -- luacheck: ignore 431/M3 - end + local M1 = lwtk.newMixin("M1", + function(M1, Super) + end + ) + local M2 = lwtk.newMixin("M2", + function(M2, Super) + end + ) + local M3 = lwtk.newMixin("M3", M1, M2, + function(M3, Super) + end + ) assertEq(lwtk.type(M3), "lwtk.Mixin") - assertEq(tostring(M3), "lwtk.Mixin(M3)") + assertEq(tostring(M3), "lwtk.Mixin") local C1 = lwtk.newClass("C1") assertEq(lwtk.type(C1), "lwtk.Class") local M3C1 = M3(C1) assertEq(lwtk.type(M3C1), "lwtk.Class") local C2 = lwtk.newClass("C2", M3C1) assertEq(lwtk.type(C2), "lwtk.Class") - assertEq(tostring(C2), "C2") - assertEq(tostring(getSuperClass(C2)), "M3") - assertEq(tostring(getSuperClass(getSuperClass(C2))), "M1") - assertEq(tostring(getSuperClass(getSuperClass(getSuperClass(C2)))), "M2") - assertEq(tostring(getSuperClass(getSuperClass(getSuperClass(getSuperClass(C2))))), "C1") + assertEq(tostring(C2), "lwtk.Class") + assertEq(tostring(getSuperClass(C2)), "lwtk.Class") + assertEq(tostring(getSuperClass(getSuperClass(C2))), "lwtk.Class") + assertEq(tostring(getSuperClass(getSuperClass(getSuperClass(C2)))), "lwtk.Class") + assertEq(tostring(getSuperClass(getSuperClass(getSuperClass(getSuperClass(C2))))), "lwtk.Class") end PRINT("----------------------------------------------------------------------------------") @@ -230,7 +250,7 @@ do end PRINT("----------------------------------------------------------------------------------") do - assert(tostring(lwtk.Button) == "lwtk.Button") + assert(tostring(lwtk.Button) == "lwtk.Class") assert(tostring(lwtk.Button()):match("^lwtk.Button: [x0-9A-Fa-f]+$")) local ok, err = pcall(function() lwtk.Button()() end) @@ -242,13 +262,15 @@ do local MyButton = lwtk.newClass("MyButton", lwtk.Widget) do + MyButton.text = false + function MyButton:setText(text) self.text = text self:triggerRedraw() end end - assertEq(tostring(MyButton), "MyButton") + assertEq(tostring(MyButton), "lwtk.Class") assert(tostring(MyButton()):match("^MyButton: [x0-9A-Fa-f]+$")) local g1 = Group { @@ -265,7 +287,6 @@ do assert(g1:childById("b1") ~= nil) assert(g1:childById("b2") ~= nil) assertEq(g1:childById("b2").text, "B2") - assertEq(g1.root, nil) assertEq(g1:childById("b2"):getRoot(), g1) assertEq(g1:childById("b2"):getRoot(), g1) assertEq(g1:childById("b2"):getRoot():childById("b1").text, "B1") @@ -282,9 +303,6 @@ do assert (g2:childById("b2") ~= nil) assertEq(g2:childById("b2"):getRoot(), g2) - local BorderedButton = lwtk.Bordered(lwtk.Button) - assert(tostring(BorderedButton) == "lwtk.Bordered(lwtk.Button)") - assert(tostring(BorderedButton()):match("^lwtk.Bordered%(lwtk.Button%)%: [x0-9A-Fa-f]+$")) end PRINT("----------------------------------------------------------------------------------") do @@ -385,25 +403,28 @@ do local MyBox = lwtk.newClass("MyBox", lwtk.Widget) + MyBox.color = false + function MyBox:setColor(color) self.color = color end - function MyBox:onDraw(ctx) + function MyBox.implement:onDraw(ctx) local c = self:getStyleParam("Color") ctx:set_source_rgb(c:toRGB()) ctx:rectangle(0, 0, self.w, self.h) ctx:fill() end + MyGroup.color = false MyGroup.setColor = MyBox.setColor - MyGroup.onDraw = MyBox.onDraw + MyGroup.implement.onDraw = MyBox.onDraw - function MyBox:onMouseEnter(x, y) + function MyBox.implement:onMouseEnter(x, y) self:setState("hover", true) end - function MyBox:onMouseLeave(x, y) + function MyBox.implement:onMouseLeave(x, y) -- print(self.id, "leave", x, y) self:setState("hover", false) end @@ -443,9 +464,9 @@ do --local b0 = win1.child.child.xxx print(win1:childById("b1")) print(win1:childById("mb1")) - assert(win1:childById("mb1").__name == "MyBox") - assert(win1:childById("b1").__name == "lwtk.Button") - assert(win1:childById("b2").__name == "lwtk.PushButton") + assertEq(getmetatable(win1:childById("mb1")).__name, "MyBox") + assertEq(getmetatable(win1:childById("b1")).__name, "lwtk.Button") + assert(getmetatable(win1:childById("b2")).__name == "lwtk.PushButton") assert(win1:childById("b2"):isInstanceOf(PushButton)) assert(win1:childById("b2"):isInstanceOf(Button)) assert(win1:childById("b1"):isInstanceOf(Button)) @@ -520,4 +541,17 @@ do assertEq(g:childById("g1"):byId("g/g2"):childById("b2").text, "g2b2") end PRINT("----------------------------------------------------------------------------------") +do + local get = lwtk.StyleRef.get + local scale = lwtk.StyleRef.scale + + local s = lwtk.DefaultStyle() + + local w1 = lwtk.Widget { } + local w2 = lwtk.Widget { style = { TextSize = scale(100, get"TextSize") } } + + assert(s:getStyleParam(w2, "TextSize") == 100 * s:getStyleParam(w1, "TextSize")) + +end +PRINT("----------------------------------------------------------------------------------") print("OK.") diff --git a/src/tests/test02.lua b/src/tests/test02.lua index 123237e..2eb2f55 100644 --- a/src/tests/test02.lua +++ b/src/tests/test02.lua @@ -21,11 +21,11 @@ end local Box = lwtk.newClass("Box", lwtk.Widget) -function Box:onDraw(ctx) +function Box.implement:onDraw(ctx) print("onDraw", self.id) end -function Box:getMeasures() +function Box.implement:getMeasures() return 0, 0, 20, 10, 200, 100 end