From 8799b4b6b1338fceb87c62898bbbe391ded22bae Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 4 Dec 2016 15:13:49 -0800 Subject: [PATCH] doc: geometry module --- frontend/apps/reader/modules/readerfooter.lua | 2 +- frontend/ui/geometry.lua | 228 +++++++++++------- 2 files changed, 147 insertions(+), 83 deletions(-) diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index c8a1dbbdf..356dcd5d7 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -309,7 +309,7 @@ function ReaderFooter:addToMainMenu(tab_item_table) y = DTAP_ZONE_MINIBAR.y, w = DTAP_ZONE_MINIBAR.w, h = DTAP_ZONE_MINIBAR.h - }:sizeof() == 0 then + }:area() == 0 then table.insert(sub_items, { text = _("Toggle mode"), enabled_func = function() diff --git a/frontend/ui/geometry.lua b/frontend/ui/geometry.lua index 149ec0af3..342cd654e 100644 --- a/frontend/ui/geometry.lua +++ b/frontend/ui/geometry.lua @@ -1,22 +1,34 @@ -local Math = require("optmath") -local DEBUG = require("dbg") - ---[[ +--[[-- 2D Geometry utilities -all of these apply to full rectangles { x = ..., y = ..., w = ..., h = ... } +All of these apply to full rectangles: + + local Geom = require("ui/geometry") + Geom:new{ x = 1, y = 0, w = 100, h = 200, } + +Some behaviour is defined for points: + + Geom:new{ x = 0, y = 0, } + +Some behaviour is defined for dimensions: -some behaviour is defined for points { x = ..., y = ... } -some behaviour is defined for dimensions { w = ..., h = ... } + Geom:new{ w = 600, h = 800, } -just use it on simple tables that have x, y and/or w, h +Just use it on simple tables that have x, y and/or w, h or define your own types using this as a metatable -]]-- + +]] + +local Math = require("optmath") + +--[[-- +@table Geom +]] local Geom = { x = 0, y = 0, w = 0, - h = 0 + h = 0, } function Geom:new(o) @@ -26,6 +38,10 @@ function Geom:new(o) return o end +--[[-- +Make a deep copy of itself. +@treturn Geom +]] function Geom:copy() local n = Geom:new() n.x = self.x @@ -39,48 +55,60 @@ function Geom:__tostring() return self.w.."x"..self.h.."+"..self.x.."+"..self.y end ---[[ -offset rectangle or point by relative values -]]-- +--[[-- +Offset rectangle or point by relative values +@int dx x delta +@int dy y delta +]] function Geom:offsetBy(dx, dy) self.x = self.x + dx self.y = self.y + dy return self end ---[[ -offset rectangle or point to certain coordinates -]]-- +--[[-- +Offsets rectangle or point to certain coordinates +@int x new x +@int y new y +]] function Geom:offsetTo(x, y) self.x = x self.y = y return self end ---[[ -scale rectangle (grow to bottom and to the right) or dimension +--[[-- +Scales rectangle (grow to bottom and to the right) or dimension -if a single factor is given, it is applied to both width and height -]]-- +If a single factor is given, it is applied to both width and height + +@int zx scale for x axis +@int zy scale for y axis +]] function Geom:scaleBy(zx, zy) self.w = Math.round(self.w * zx) self.h = Math.round(self.h * (zy or zx)) return self end ---[[ -this method also takes care of x and y -]]-- +--[[-- +This method also takes care of x and y on top of @{Geom:scaleBy} + +@int zx scale for x axis +@int zy scale for y axis +]] function Geom:transformByScale(zx, zy) self.x = Math.round(self.x * zx) self.y = Math.round(self.y * (zx or zy)) self:scaleBy(zx, zy) end ---[[ -return size of geom -]]-- -function Geom:sizeof() +--[[-- +Returns area of itself. + +@treturn int +]] +function Geom:area() if not self.w or not self.h then return 0 else @@ -88,25 +116,31 @@ function Geom:sizeof() end end ---[[ -enlarges or shrinks dimensions or rectangles +--[[-- +Enlarges or shrinks dimensions or rectangles -note that for rectangles the offset stays the same -]]-- +Note that for rectangles the offset stays the same + +@int dw width delta +@int dh height delta +]] function Geom:changeSizeBy(dw, dh) self.w = self.w + dw self.h = self.h + dh return self end ---[[ -return the outer rectangle that contains both us and a given rectangle +--[[-- +Returns a new outer rectangle that contains both us and a given rectangle -works for rectangles, dimensions and points -]]-- +Works for rectangles, dimensions and points + +@tparam Geom rect_b +@treturn Geom +]] function Geom:combine(rect_b) local combined = self:copy() - if not rect_b or rect_b:sizeof() == 0 then return combined end + if not rect_b or rect_b:area() == 0 then return combined end if combined.x > rect_b.x then combined.x = rect_b.x end @@ -126,11 +160,13 @@ function Geom:combine(rect_b) return combined end ---[[ -returns a rectangle for the part that we and a given rectangle share +--[[-- +Returns a new rectangle for the part that we and a given rectangle share -TODO: what happens if there is no rectangle shared? currently behaviour is undefined. +@tparam Geom rect_b +@treturn Geom ]]-- +-- TODO: what happens if there is no rectangle shared? currently behaviour is undefined. function Geom:intersect(rect_b) -- make a copy of self local intersected = self:copy() @@ -153,9 +189,11 @@ function Geom:intersect(rect_b) return intersected end ---[[ -return true if self does not share any area with rect_b -]]-- +--[[-- +Return true if self does not share any area with rect_b + +@tparam Geom rect_b +]] function Geom:notIntersectWith(rect_b) if (self.x >= (rect_b.x + rect_b.w)) or (self.y >= (rect_b.y + rect_b.h)) @@ -166,28 +204,33 @@ function Geom:notIntersectWith(rect_b) return false end ---[[ -return true if self geom shares area with rect_b -]]-- +--[[-- +Return true if self geom shares area with rect_b + +@tparam Geom rect_b +]] function Geom:intersectWith(rect_b) return not self:notIntersectWith(rect_b) end ---[[ -set size of dimension or rectangle to size of given dimension/rectangle -]]-- +--[[-- +Set size of dimension or rectangle to size of given dimension/rectangle + +@tparam Geom rect_b +]] function Geom:setSizeTo(rect_b) self.w = rect_b.w self.h = rect_b.h return self end ---[[ -check whether rect_b is within current rectangle +--[[-- +Check whether rect_b is within current rectangle -works for dimensions, too -for points, it is basically an equality check -]]-- +Works for dimensions, too. For points, it is basically an equality check + +@tparam Geom rect_b +]] function Geom:contains(rect_b) if self.x <= rect_b.x and self.y <= rect_b.y @@ -199,11 +242,13 @@ function Geom:contains(rect_b) return false end ---[[ -check for equality +--[[-- +Check for equality -works for rectangles, points, dimensions -]]-- +Works for rectangles, points, dimensions + +@tparam Geom rect_b +]] function Geom:__eq(rect_b) if self.x == rect_b.x and self.y == rect_b.y @@ -214,9 +259,11 @@ function Geom:__eq(rect_b) return false end ---[[ -check size of dimension/rectangle for equality -]]-- +--[[-- +Check size of dimension/rectangle for equality + +@tparam Geom rect_b +]] function Geom:equalSize(rect_b) if self.w == rect_b.w and self.h == rect_b.h @@ -226,9 +273,11 @@ function Geom:equalSize(rect_b) return false end ---[[ -check if our size is smaller than the size of the given dimension/rectangle -]]-- +--[[-- +Check if our size is smaller than the size of the given dimension/rectangle + +@tparam Geom rect_b +]] function Geom:__lt(rect_b) DEBUG("lt:",self,rect_b) if self.w < rect_b.w and self.h < rect_b.h then @@ -239,9 +288,10 @@ DEBUG("lt-") return false end ---[[ -check if our size is smaller or equal the size of the given dimension/rectangle -]]-- +--[[-- +Check if our size is smaller or equal the size of the given dimension/rectangle +@tparam Geom rect_b +]] function Geom:__le(rect_b) if self.w <= rect_b.w and self.h <= rect_b.h then return true @@ -249,13 +299,17 @@ function Geom:__le(rect_b) return false end ---[[ -offset the current rectangle by dx, dy while fitting it into the space +--[[-- +Offset the current rectangle by dx, dy while fitting it into the space of a given rectangle -this can also be called with dx=0 and dy=0, which will fit the current +This can also be called with dx=0 and dy=0, which will fit the current rectangle into the given rectangle -]]-- + +@tparam Geom rect_b +@int dx +@int dy +]] function Geom:offsetWithin(rect_b, dx, dy) -- check size constraints and shrink us when we're too big if self.w > rect_b.w then @@ -282,9 +336,13 @@ function Geom:offsetWithin(rect_b, dx, dy) end end ---[[ -center the current rectangle at position x and y of a given rectangle -]]-- +--[[-- +Center the current rectangle at position x and y of a given rectangle + +@tparam Geom rect_b +@int dx +@int dy +]] function Geom:centerWithin(rect_b, x, y) -- check size constraints and shrink us when we're too big if self.w > rect_b.w then @@ -316,16 +374,21 @@ function Geom:shrinkInside(rect_b, dx, dy) return self:intersect(rect_b) end ---[[ -return the Euclidean distance between two geoms -]]-- +--[[-- +Return the Euclidean distance between two geoms + +@tparam Geom rect_b +]] function Geom:distance(geom) return math.sqrt(math.pow(self.x - geom.x, 2) + math.pow(self.y - geom.y, 2)) end ---[[ -return the midpoint of two geoms -]]-- +--[[-- +Return the midpoint of two geoms + +@tparam Geom geom +@treturn Geom +]] function Geom:midpoint(geom) return Geom:new{ x = Math.round((self.x + geom.x) / 2), @@ -334,9 +397,10 @@ function Geom:midpoint(geom) } end ---[[ -return center point in this geom -]]-- +--[[-- +Return center point in this geom +@treturn Geom +]] function Geom:center() return Geom:new{ x = self.x + Math.round(self.w / 2),