class BBS::Widgets::Scene
A BBS::Art as a picture of the modern face that shows the board’s life: the art (with the layers stacked on it) as the background, and over it the hotspots filled from data, each by a block given for it. A block is called at every render with the Art::Hotspot and returns what goes there: a String (ANSI colours allowed; lines split at \n fill the hotspot’s rows), or nil to leave the art as it is. What a block returns is cut to its hotspot.
house = BBS::Art.load('art/house.yml').with(*BBS::Season.now.layers) scene = BBS::Widgets::Scene.new(art: house, align: :center) scene.fill(:window_1) { node_busy?(1) ? "\e[38;5;220m▓" : nil } scene.fill(:mailbox) { |spot| "✉#{unread}".ljust(spot.width) } container.add(scene)
On a terminal smaller than the art the scene is cut to its bounds: what is right of and below them is left off, and a hotspot outside is not filled. With crop: false it draws nothing instead (a dashboard that drops the picture on a small screen asks fits?).
Attributes
Placement of the art in the bounds: align :left, :center or :right; valign :top, :middle or :bottom.
Whether a scene larger than its bounds is cut (true) or not drawn.
Whether the widget takes its parent’s bounds on every render.
Placement of the art in the bounds: align :left, :center or :right; valign :top, :middle or :bottom.
Public Class Methods
# File lib/bbs/widgets/scene.rb, line 41 def initialize(art:, fills: {}, align: :left, valign: :top, crop: true, fill_parent: false, **kw) super(**kw) @art = art @align = align @valign = valign @crop = crop @fill_parent = fill_parent @fills = {} fills.each { |name, block| fill(name, &block) } end
Creates the scene of art (a BBS::Art); fills maps hotspot names to blocks, as fill does; align, valign, crop and fill_parent as the attributes. Other keywords go to Widget.new. Raises Art::Error for a hotspot name the art does not have.
BBS::Widget::new
Public Instance Methods
Source
# File lib/bbs/widgets/scene.rb, line 55 def fill(name, &block) @art.hotspot(name) @fills[name.to_sym] = block self end
Sets the block that fills hotspot name at every render (see the class description). Raises Art::Error for a name the art does not have. Returns self.
Source
# File lib/bbs/widgets/scene.rb, line 62 def fits? = @art.cols <= bounds.width && @art.rows <= bounds.height
Whether the whole art fits in the bounds.
Source
# File lib/bbs/widgets/scene.rb, line 66 def render(frame) @bounds = parent.bounds.dup if @fill_parent && parent&.bounds return unless drawable? view = self.view @art.draw(frame, x: view.x, y: view.y, width: view.width, height: view.height) @fills.each do |name, block| spot = @art.hotspots[name] paint(frame, spot, block.call(spot), view) if spot end end
Draws the art and the filled hotspots into frame, a BBS::FrameBuffer, inside the bounds.