Skip to content

Commit

Permalink
some documentation, improvements and minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
osch committed Feb 18, 2023
1 parent 72c740b commit 10e6b4c
Show file tree
Hide file tree
Showing 25 changed files with 406 additions and 83 deletions.
4 changes: 2 additions & 2 deletions doc/Application.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ TODO
## Application Methods
<!-- ---------------------------------------------------------------------------------------- -->

* <a id="Application_runEventLoop">**` Application:runEventLoop(timeout)
* <a id="Application_runEventLoop">**`Application:runEventLoop(timeout)
`**</a>

Update by processing events from the window system.
Expand All @@ -32,7 +32,7 @@ TODO

<!-- ---------------------------------------------------------------------------------------- -->

* <a id="Application_update">**` Application:update(timeout)
* <a id="Application_update">**`Application:update(timeout)
`**</a>

Update by processing events from the window system.
Expand Down
216 changes: 216 additions & 0 deletions doc/Class.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
# lwtk.Class

Each lwtk *object* is actually a Lua table that has a lwtk *class* as metatable. The class
is also called the object's *type*.

<!-- ---------------------------------------------------------------------------------------- -->
## Contents
<!-- ---------------------------------------------------------------------------------------- -->

* [Declaring Classes](#declaring-classes)
* [Instantiating Objects](#instantiating-objects)
* [Declaring Methods](#declaring-methods)
* [Declaring Derived Classes](#declaring-derived-classes)
* [Instantiating Derived Objects](#instantiating-derived-objects)
* [Overriding Methods](#overriding-methods)

<!-- ---------------------------------------------------------------------------------------- -->
## Declaring Classes
<!-- ---------------------------------------------------------------------------------------- -->

Let's start by declaring a new class 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"`:

```lua
assert(type(Foo) == "table")
assert(getmetatable(Foo) == lwtk.Class)
assert(tostring(Foo) == "Foo")
assert(lwtk.type(Foo) == "lwtk.Class")
```

<!-- ---------------------------------------------------------------------------------------- -->
## Instantiating Objects
<!-- ---------------------------------------------------------------------------------------- -->

Objects of a certain class are instantiated by calling the class:

```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"`:

```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)
```

<!-- ---------------------------------------------------------------------------------------- -->
## Declaring Methods
<!-- ---------------------------------------------------------------------------------------- -->

Methods declared for the class table become methods for all objects of this type:

```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)
```

The methods are retrieved by metatable lookup from the class:

```lua
assert(rawget(o1, "setX") == nil)
assert(rawget(Foo, "setX") == Foo.setX)
assert(o1.setX == Foo.setX)
```

<!-- ---------------------------------------------------------------------------------------- -->
## Declaring Derived Classes
<!-- ---------------------------------------------------------------------------------------- -->

Let's create a derived class named `"Bar"` that has `Foo` as super class:

```lua
local Bar = lwtk.newClass("Bar", Foo)

```

Every class declared by `lwtk.newClass()` has a super class,
default super class is `lwtk.Object`:
```lua
assert(lwtk.getSuperClass(Bar) == Foo)
assert(lwtk.getSuperClass(Foo) == lwtk.Object)
assert(lwtk.getSuperClass(lwtk.Object) == nil)
```

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:

```lua
assert(type(Bar) == "table")
assert(tostring(Bar) == "Bar")
assert(lwtk.type(Bar) == "lwtk.Class")
assert(getmetatable(Bar) == lwtk.Class)
```

The derived class contains the methods of the super class at the time when `newClass`
was invoked:

```lua
assert(rawget(Bar, "setX") == Foo.setX)
assert(rawget(Bar, "getX") == Foo.getX)
```

Methods 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)
```

<!-- ---------------------------------------------------------------------------------------- -->
## Instantiating Derived Objects
<!-- ---------------------------------------------------------------------------------------- -->


Let's instantiate an object of the derived class `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`:


```lua
assert(type(o3) == "table")
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:

```lua
assert(o3.setX == Foo.setX)
assert(o3.setY == nil)

o3:setX(300)
assert(o3:getX()== 300)
assert(o3._x == 300)
```

Use `lwtk.isInstanceOf()` to check if an object is an instance of the specified class:

```lua
assert(lwtk.isInstanceOf(o3, Bar))
assert(lwtk.isInstanceOf(o3, Foo))
assert(lwtk.isInstanceOf(o3, lwtk.Object))

assert(not lwtk.isInstanceOf(o2, Bar))
assert(lwtk.isInstanceOf(o2, Foo))
assert(lwtk.isInstanceOf(o2, lwtk.Object))

```


<!-- ---------------------------------------------------------------------------------------- -->
## Overriding Methods
<!-- ---------------------------------------------------------------------------------------- -->

Methods declared for the derived class are only available for derived objects:


```lua
function Bar:addX(x)
return self._x + x
end
assert(o2.addX == nil)
assert(o3.addX ~= nil)
assert(o3:addX(2) == 302)

```

Let's override the method `getX` for the derived class:

```lua
function Bar:getX()
return 2 * Foo.getX(self) -- double the value from the super class
end
assert(o1:getX() == 100) -- invokes Foo.getX
assert(o3:getX() == 600) -- invokes Bar.getX
```


<!-- ---------------------------------------------------------------------------------------- -->
<!--lua
print("Class.md: OK")
-->
5 changes: 3 additions & 2 deletions doc/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# lwtk Documentation

TODO
* [lwtk.Application](Application.md)
* [lwtk.Style](Style.md)
* [lwtk.Class](Class.md) - declaring classes and instantiate objects
* [lwtk.Application](Application.md) - handling windows and events
* [lwtk.Style](Style.md) - configuring widget styles
* TODO
2 changes: 2 additions & 0 deletions doc/Style.md
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,14 @@ local g1 = lwtk.Group {
local win = app:newWindow { g1 }

assert(g1:getStyleParam("FooSeconds") == 23) -- from group
assert(g1:getStyleParam("xxxSeconds") == 33) -- from group

assert(w1a:getStyleParam("FooColumns") == 15) -- from app
assert(w1a:getStyleParam("FooSeconds") == 33) -- from group

assert(w1b:getStyleParam("FooColumns") == 15) -- from app
assert(w1b:getStyleParam("FooSeconds") == 22) -- from widget
assert(w1b:getStyleParam("xxxSeconds") == 33) -- from group
```

TODO
Expand Down
1 change: 1 addition & 0 deletions lwtk-scm-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ build = {
["lwtk.internal.StyleRuleContext"] = "src/lwtk/internal/StyleRuleContext.lua",
["lwtk.internal.TypeRule"] = "src/lwtk/internal/TypeRule.lua",
["lwtk.internal.utf8string"] = "src/lwtk/internal/utf8string.lua",
["lwtk.isInstanceOf"] = "src/lwtk/isInstanceOf.lua",
["lwtk.layout"] = "src/lwtk/layout.lua",
["lwtk.lpugl"] = "src/lwtk/lpugl/init.lua",
["lwtk.lpugl.CairoDrawContext"] = "src/lwtk/lpugl/CairoDrawContext.lua",
Expand Down
1 change: 1 addition & 0 deletions src/.luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ ignore = {
"213", -- unused loop variable
"212", -- unused argument
}
globals = { "love" }


7 changes: 7 additions & 0 deletions src/lwtk/Animatable.lua
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,13 @@ 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()
if self._animationUpdated then
Expand Down
7 changes: 4 additions & 3 deletions src/lwtk/Application.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ local getKeyBinding = lwtk.get.keyBinding
local getFontInfos = lwtk.get.fontInfos
local getVisibilityChanges = lwtk.get.visibilityChanges
local getDeferredChanges = lwtk.get.deferredChanges
local isInstanceOf = lwtk.isInstanceOf

local isClosed = setmetatable({}, { __mode = "k" })
local createClosures
Expand All @@ -21,7 +22,7 @@ function Application:new(arg1, arg2)
local initParams
if type(arg1) == "string" then
appName = arg1
if lwtk.Object.is(arg2, lwtk.Style) then
if isInstanceOf(arg2, lwtk.Style) then
initParams = { style = arg2 }
else
initParams = arg2 or {}
Expand All @@ -40,7 +41,7 @@ function Application:new(arg1, arg2)
local style = initParams.style
if style then
initParams.style = nil
if lwtk.Object.is(style, lwtk.Style) then
if isInstanceOf(style, lwtk.Style) then
style:setScaleFactor((style.scaleFactor or 1) * self.driver:getScreenScale())
else
style.scaleFactor = (style.scaleFactor or 1) * self.driver:getScreenScale()
Expand Down Expand Up @@ -127,7 +128,7 @@ function Application:setStyle(style)
if getApp[style] then
error("Style was alread added to app")
end
if lwtk.Object.is(style, lwtk.Style) then
if isInstanceOf(style, lwtk.Style) then
style:setScaleFactor(style.scaleFactor * self.driver:getScreenScale())
else
style = lwtk.Style(style)
Expand Down
12 changes: 6 additions & 6 deletions src/lwtk/Color.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ local format = string.format
local floor = math.floor

local lwtk = require"lwtk"
local vivid = lwtk.vivid

local vivid = lwtk.vivid

local Object = lwtk.Object
local Color = lwtk.newClass("lwtk.Color")

local isInstanceOf = lwtk.isInstanceOf

local hexCharPat = "[0-9A-Fa-f]"
local hexBytePat = "("..hexCharPat..hexCharPat..")"
local rgbPat = "^"..hexBytePat..hexBytePat..hexBytePat.."$"
Expand Down Expand Up @@ -102,7 +102,7 @@ function Color:__tostring()
end

function Color.__mul(factor, color)
assert(Object.is(color, Color))
assert(isInstanceOf(color, Color))
assert(type(factor) == "number" and 0 <= factor and factor <= 1)
local a = color.a or 1
return Color(factor * color.r,
Expand All @@ -112,8 +112,8 @@ function Color.__mul(factor, color)
end

function Color.__add(color1, color2)
assert(Object.is(color1, Color))
assert(Object.is(color2, Color))
assert(isInstanceOf(color1, Color))
assert(isInstanceOf(color2, Color))
local a1, a2 = color1.a or 1, color2.a or 1
return Color(color1.r + color2.r,
color1.g + color2.g,
Expand Down
4 changes: 4 additions & 0 deletions src/lwtk/Component.lua
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ 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
Expand Down
2 changes: 1 addition & 1 deletion src/lwtk/KeyHandler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ function KeyHandler:_handleKeyDown(keyName, keyState, keyText)
keyName, keyState, keyText = interceptKeyDown(self, keyName, keyState, keyText)
end
local state = getState[self]
local keyName = toHotKeyChar(keyName) or keyName
keyName = toHotKeyChar(keyName) or keyName
if keyName and isModifier[keyName] then
state.mod = keyName
else
Expand Down
4 changes: 2 additions & 2 deletions src/lwtk/MouseDispatcher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function MouseDispatcher:_processMouseDown(mx, my, button, modState)
local bChild = self.mouseButtonChild
if bChild then
self.mouseChildButtons[button] = true
local received, handled = false, false
local received, handled = false, false -- luacheck: ignore 231/received 311/handled
if self ~= bChild then
received, handled = bChild:_processMouseDown(mx - bChild.x, my - bChild.y,
button, modState)
Expand All @@ -177,7 +177,7 @@ function MouseDispatcher:_processMouseDown(mx, my, button, modState)
self.mouseButtonChild = uChild
self.mouseChildButtons[button] = true
call("onMouseDown", self, mx, my, button, modState)
local received, handled = uChild:_processMouseDown(mx - x, my - y, button, modState)
local received, handled = uChild:_processMouseDown(mx - x, my - y, button, modState) -- luacheck: ignore 211/received
return true, handled
else
self.mouseButtonChild = self
Expand Down
Loading

0 comments on commit 10e6b4c

Please sign in to comment.