/
Widget.pm6
65 lines (54 loc) · 2.53 KB
/
Widget.pm6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use Terminal::Print::Grid;
#| A basic rectangular widget that can work in relative coordinates
class Terminal::Print::Widget {
has Int $.x is required; #= Location of widget's left edge on parent widget/grid
has Int $.y is required; #= Location of widget's top edge on parent widget/grid
has Int $.w is required; #= Width of widget in character cells
has Int $.h is required; #= Height of widget in character cells
has $.parent; #= Parent widget/grid onto which this widget will be composited
has @.children; #= Child widgets that will composite onto this one
has $.grid = Terminal::Print::Grid.new($!w, $!h); #= Widget's backing grid
#| Wrap an existing T::P::Grid into a T::P::Widget
method new-from-grid($grid, |c) {
self.new(:$grid, :w($grid.w), :h($grid.h), :x(0), :y(0), |c);
}
#| Make sure parent widget knows about this child
submethod TWEAK() {
$!parent.add-child(self) if $!parent ~~ Terminal::Print::Widget;
}
#| Move upper left corner to (x, y) on the parent widget/grid
method move-to($!x, $!y) { }
#| Add a child widget to this one
method add-child(Terminal::Print::Widget $child) {
@!children.push($child);
}
#| Remove a child widget from this one
method remove-child(Terminal::Print::Widget $child) {
# <> performs decont (decontainerizing) magic so that =:= can compare
# the identity of the underlying objects, not their containers
@!children .= grep(*<> !=:= $child<>);
}
#| Return T::P::Grid object that this Widget will draw on
method target-grid() {
given $!parent {
when Terminal::Print::Grid { $_ }
when Terminal::Print::Widget { .grid }
default { $*TERMINAL.current-grid }
}
}
#| Composite this widget onto a target grid, optionally printing to screen
# For now, simply copies widget contents (effects such as alpha blend NYI).
# Default behavior is to print iff the widget's parent is the screen grid.
method composite(Terminal::Print::Grid :$to = self.target-grid,
Bool :$print = $to === $*TERMINAL.current-grid) {
# Skip copy if target is own backing grid, e.g. screen's root widget
if $to === $!grid {
print $!grid if $print;
}
else {
# Destination grid (a Monitor) does the work for thread safety
$print ?? $to.print-from($!grid, $!x, $!y)
!! $to .copy-from($!grid, $!x, $!y);
}
}
}