2
0
mirror of https://github.com/koreader/koreader synced 2024-11-18 03:25:46 +00:00
koreader/frontend/ui/widget/widget.lua
NiLuJe fadee1f5dc
Clarify our OOP semantics across the codebase (#9586)
Basically:

* Use `extend` for class definitions
* Use `new` for object instantiations

That includes some minor code cleanups along the way:

* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
  * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 02:14:48 +02:00

74 lines
2.0 KiB
Lua

--[[--
This is a generic Widget interface, which is the base class for all other widgets.
Widgets can be queried about their size and can be painted on screen.
that's it for now. Probably we need something more elaborate
later.
If the table that was given to us as parameter has an "init"
method, it will be called. use this to set _instance_ variables
rather than class variables.
]]
local EventListener = require("ui/widget/eventlistener")
--- Widget base class
-- @table Widget
local Widget = EventListener:extend{}
--[[--
Use this method to define a widget subclass that's inherited from a base class widget.
It only setups the metatable (or prototype chain) and will not initiate a real instance, i.e. call self:init().
@tparam table subclass
@treturn Widget
]]
function Widget:extend(subclass_prototype)
local o = subclass_prototype or {}
setmetatable(o, self)
self.__index = self
return o
end
--[[--
Use this method to initiate an instance of a class.
Do NOT use it for class definitions because it also calls self:init().
@tparam table o
@treturn Widget
]]
function Widget:new(o)
o = self:extend(o)
-- Both o._init and o.init are called on object creation.
-- But o._init is used for base widget initialization (basic components used to build other widgets).
-- While o.init is for higher level widgets, for example Menu.
if o._init then o:_init() end
if o.init then o:init() end
return o
end
--[[
FIXME: Enable this doc section once we've verified all self.dimen are Geom objects
so we can return self.dimen:copy() instead of a live ref.
Return size of the widget.
@treturn ui.geometry.Geom
--]]
function Widget:getSize()
return self.dimen
end
--[[--
Paint widget to a BlitBuffer.
@tparam BlitBuffer bb 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)
end
return Widget