doc: event propagation for widgets

pull/2416/head
Qingping Hou 8 years ago
parent d1f9cf932b
commit 09564d4b4d

@ -1,20 +1,17 @@
Data Store Data Store
========== ==========
LuaSettings ## LuaSettings ##
-----------
TODO TODO
DocSettings ## DocSettings ##
-----------
TODO TODO
SQLite3 ## SQLite3 ##
-------
KOReader ships with the SQLite3 library, which is a great embedded database for KOReader ships with the SQLite3 library, which is a great embedded database for
desktop and mobile applications. desktop and mobile applications.

@ -1,10 +1,45 @@
Builtin Events Events
============== ======
Reader Events ## Overview ##
-------------
All widgets is a subclass of @{ui.widget.eventlistener}, therefore inherit
the @{ui.widget.eventlistener:handleEvent|handleEvent} method. To send an event
to a widget, you can simply invoke the handleEvent method like the following:
```lua
widget_foo:handleEvent(Event:new("Timeout"))
```
## Builtin events ##
### Reader events ###
* UpdatePos: emitted by typesetting related modules to notify other modules to * UpdatePos: emitted by typesetting related modules to notify other modules to
recalculate the view based on the new typesetting. recalculate the view based on the new typesetting.
* PosUpdate: emitted by readerrolling module to signal a change in pos. * PosUpdate: emitted by readerrolling module to signal a change in pos.
## Event propagation ##
Most of the UI components is a subclass of
@{ui.widget.container.widgetcontainer|WidgetContainer}. A WidgetContainer is an array that
stores a list of children widgets.
When @{ui.widget.container.widgetcontainer:handleEvent|WidgetContainer:handleEvent} is called with a new
event, it will run roughly the following code:
```lua
-- First propagate event to its children
for _, widget in ipairs(self) do
if widget:handleEvent(event) then
-- stop propagating when an event handler returns true
return true
end
end
-- If not consumed by children, try consume by itself
return self["on"..event.name](self, unpack(event.args))
```

@ -1,8 +1,7 @@
Hacking Hacking
======= =======
Developing UI Widgets ## Developing UI widgets ##
---------------------
`tools/wbuilder.lua` is your friend, if you need to create new UI widgets. It `tools/wbuilder.lua` is your friend, if you need to create new UI widgets. It
sets up a minimal environment to bootstrap KOReader's UI framework to avoid sets up a minimal environment to bootstrap KOReader's UI framework to avoid

@ -8,7 +8,7 @@ widgets event-aware see the implementation in @{ui.widget.container.widgetcontai
]] ]]
--[[-- --[[--
@field handler name for the handler method @field handler name for the handler method: `"on"..Event.name`
@field args array of arguments for the event @field args array of arguments for the event
@table Event @table Event
]] ]]

@ -1,7 +1,16 @@
--[[-- --[[--
WidgetContainer is a container for another Widget. Base class for all the widget containers. WidgetContainer is a container for one or multiple Widgets. It is the base
class for all the container widgets.
It handles event propagation and paiting (with different alignments) for its children. Child widgets are stored in WidgetContainer as conventional array items:
WidgetContainer:new{
ChildWidgetFoo:new{},
ChildWidgetBar:new{},
...
}
It handles event propagation and painting (with different alignments) for its children.
]] ]]
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
@ -85,8 +94,8 @@ end
--[[-- --[[--
WidgetContainer will pass event to its children by calling their handleEvent WidgetContainer will pass event to its children by calling their handleEvent
methods. If no child responded to the event (by returning true), it will call its own methods. If no child consumes the event (by returning true), it will try
handleEvent method. to react to the event by itself.
@tparam ui.event.Event event @tparam ui.event.Event event
@treturn bool true if event is consumed, othewise false. A consumed event will @treturn bool true if event is consumed, othewise false. A consumed event will

@ -1,10 +1,12 @@
--[[ --[[--
The EventListener is an interface that handles events The EventListener is an interface that handles events. This is the base class
for @{ui.widget.widget}
EventListeners have a rudimentary event handler/dispatcher that EventListeners have a rudimentary event handler/dispatcher that
will call a method "onEventName" for an event with name will call a method "onEventName" for an event with name
"EventName" "EventName"
--]] ]]
local EventListener = {} local EventListener = {}
local DEBUG = require("dbg") local DEBUG = require("dbg")
@ -16,6 +18,15 @@ function EventListener:new(new_o)
return o return o
end end
--[[--
Invoke handler method for an event.
Handler method name is determined by @{ui.event.Event}'s handler field.
By default, it's `"on"..Event.name`.
@tparam ui.event.Event event
@treturn bool return true if event is consumed successfully.
]]
function EventListener:handleEvent(event) function EventListener:handleEvent(event)
if self[event.handler] then if self[event.handler] then
if self.id or self.name then if self.id or self.name then

@ -1,34 +1,40 @@
local EventListener = require("ui/widget/eventlistener") --[[--
This is a generic Widget interface, which is the base class for all other widgets.
--[[
This is a generic Widget interface
widgets can be queried about their size and can be paint. Widgets can be queried about their size and can be painted on screen.
that's it for now. Probably we need something more elaborate that's it for now. Probably we need something more elaborate
later. later.
if the table that was given to us as parameter has an "init" If the table that was given to us as parameter has an "init"
method, it will be called. use this to set _instance_ variables method, it will be called. use this to set _instance_ variables
rather than class variables. rather than class variables.
--]] ]]
local EventListener = require("ui/widget/eventlistener")
local Widget = EventListener:new() local Widget = EventListener:new()
--[[ --[[--
Use this method to define a class that's inherited from current class. Use this method to define a subclass widget class that's inherited from a
It only setup the metabale (or prototype chain) and will not initiatie base class widget. It only setups the metabale (or prototype chain) and will
a real instance, i.e. call self:init() not initiate a real instance, i.e. call self:init().
--]]
function Widget:extend(from_o) @tparam Widget baseclass
local o = from_o or {} @treturn Widget
]]
function Widget:extend(baseclass)
local o = baseclass or {}
setmetatable(o, self) setmetatable(o, self)
self.__index = self self.__index = self
return o return o
end end
--[[ --[[--
Use this method to initiatie a instance of a class, don't use it for class Use this method to initiatie a instance of a class, don't use it for class
definition. definition because it also calls self:init().
--]]
@tparam Widget o
@treturn Widget
]]
function Widget:new(o) function Widget:new(o)
o = self:extend(o) o = self:extend(o)
-- Both o._init and o.init are called on object creation. But o._init is -- Both o._init and o.init are called on object creation. But o._init is
@ -40,10 +46,26 @@ function Widget:new(o)
return o return o
end end
--[[
FIXME: enable this doc section when we verified all self.dimen is a Geom so we
can return self.dime:copy().
Return size of the widget.
@treturn ui.geometry.Geom
--]]
function Widget:getSize() function Widget:getSize()
return self.dimen return self.dimen
end end
--[[--
Paint widget to a BlitBuffer.
@tparam BlitBuffer BlitBuffer to paint to. If it's the screen BlitBuffer, then
widget will show up on screen refresh.
@int x x offset within the BlitBuffer
@int y y offset within the BlitBuffer
]]
function Widget:paintTo(bb, x, y) function Widget:paintTo(bb, x, y)
end end

Loading…
Cancel
Save