Merge pull request #2381 from myk002/myk_framed_panel

[widgets.Panel] support frames around panel widgets
develop
Myk 2022-11-09 10:32:23 -08:00 committed by GitHub
commit ccd43f1710
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 1 deletions

@ -3949,7 +3949,7 @@ Base of all the widgets. Inherits from View and has the following attributes:
Panel class Panel class
----------- -----------
Inherits from Widget, and intended for grouping a number of subviews. Inherits from Widget, and intended for framing and/or grouping subviews.
Has attributes: Has attributes:
@ -3971,6 +3971,13 @@ Has attributes:
height or become visible/hidden and you don't have to worry about height or become visible/hidden and you don't have to worry about
recalculating subview positions. recalculating subview positions.
* ``frame_style``, ``frame_title`` (default: nil)
If defined, a frame will be drawn around the panel and subviews will be inset
by 1. The attributes are identical to what is defined in the
`FramedScreen class`_. When using the predefined frame styles in the ``gui``
module, remember to ``require`` the gui module and prefix the identifier with
``gui.``, e.g. ``gui.GREY_LINE_FRAME``.
ResizingPanel class ResizingPanel class
------------------- -------------------

@ -81,6 +81,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- ``widgets.List``: shift-clicking now triggers the ``submit2`` attribute function if it is defined - ``widgets.List``: shift-clicking now triggers the ``submit2`` attribute function if it is defined
- ``dfhack.constructions.findAtTile()``: exposed preexisting function to Lua. - ``dfhack.constructions.findAtTile()``: exposed preexisting function to Lua.
- ``dfhack.constructions.insert()``: exposed new function to Lua. - ``dfhack.constructions.insert()``: exposed new function to Lua.
- ``widgets.Panel``: new ``frame_style`` and ``frame_title`` attributes for drawing frames around groups of widgets
- ``widgets.EditField`` now allows other widgets to process characters that the ``on_char`` callback rejects. - ``widgets.EditField`` now allows other widgets to process characters that the ``on_char`` callback rejects.
- ``gui.Screen.show()`` now returns ``self`` as a convenience - ``gui.Screen.show()`` now returns ``self`` as a convenience
- ``gui.View.getMousePos()`` now takes an optional ``ViewRect`` parameter in case the caller wants to get the mouse pos relative to a rect that is not the frame_body (such as the frame_rect) - ``gui.View.getMousePos()`` now takes an optional ``ViewRect`` parameter in case the caller wants to get the mouse pos relative to a rect that is not the frame_body (such as the frame_rect)

@ -73,6 +73,8 @@ end
Panel = defclass(Panel, Widget) Panel = defclass(Panel, Widget)
Panel.ATTRS { Panel.ATTRS {
frame_style = DEFAULT_NIL, -- as in gui.FramedScreen
frame_title = DEFAULT_NIL, -- as in gui.FramedScreen
on_render = DEFAULT_NIL, on_render = DEFAULT_NIL,
on_layout = DEFAULT_NIL, on_layout = DEFAULT_NIL,
autoarrange_subviews = false, -- whether to automatically lay out subviews autoarrange_subviews = false, -- whether to automatically lay out subviews
@ -87,6 +89,12 @@ function Panel:onRenderBody(dc)
if self.on_render then self.on_render(dc) end if self.on_render then self.on_render(dc) end
end end
function Panel:computeFrame(parent_rect)
local sw, sh = parent_rect.width, parent_rect.height
return gui.compute_frame_body(sw, sh, self.frame, self.frame_inset,
self.frame_style and 1 or 0)
end
function Panel:postComputeFrame(body) function Panel:postComputeFrame(body)
if self.on_layout then self.on_layout(body) end if self.on_layout then self.on_layout(body) end
end end
@ -112,6 +120,13 @@ function Panel:postUpdateLayout()
self:updateSubviewLayout() self:updateSubviewLayout()
end end
function Panel:onRenderFrame(dc, rect)
Panel.super.onRenderFrame(self, dc, rect)
if not self.frame_style then return end
local x1,y1,x2,y2 = rect.x1, rect.y1, rect.x2, rect.y2
gui.paint_frame(x1, y1, x2, y2, self.frame_style, self.frame_title)
end
------------------- -------------------
-- ResizingPanel -- -- ResizingPanel --
------------------- -------------------
@ -129,8 +144,18 @@ function ResizingPanel:postUpdateLayout(frame_body)
(s.frame and s.frame.h or frame_body.height)) (s.frame and s.frame.h or frame_body.height))
end end
end end
if self.frame_style then
w = w + 2
h = h + 2
end
if not self.frame then self.frame = {} end if not self.frame then self.frame = {} end
local oldw, oldh = self.frame.w, self.frame.h
self.frame.w, self.frame.h = w, h self.frame.w, self.frame.h = w, h
if not self._updateLayoutGuard and (oldw ~= w or oldh ~= h) then
self._updateLayoutGuard = true -- protect against infinite loops
self:updateLayout() -- our frame has changed, we need to fully refresh
end
self._updateLayoutGuard = nil
end end
----------- -----------