Tickit-Widget-Layout-Desktop
view release on metacpan or search on metacpan
lib/Tickit/Widget/Layout/Desktop/Window.pm view on Meta::CPAN
=cut
method with_rb ($rb, $code) {
$rb->save;
$code->($rb);
$rb->restore;
$self;
}
=head2 content_rect
Represents the inner area of this window, i.e. the
content without the frame.
=cut
method content_rect {
my $win = $self->window;
$self->child->window->rect->translate(
$win->top,
$win->left
)
}
method container { $self->{container} }
my %override = (
southeast => 0x256D,
northeast => 0x2570,
southwest => 0x256E,
northwest => 0x256f,
);
=head2 render_to_rb
Returns $self.
=cut
method render_to_rb ($rb, $rect) {
my $win = $self->window or return;
return unless $self->child->window;
# If the exposed area does not overlap the frame, bail out now
return if $self->content_rect->contains($rect);
# Use a default pen for drawing all the line-related pieces
$rb->setpen($self->get_style_pen);
# First, work out any line intersections for our border.
$self->with_rb($rb => sub {
my $rb = shift;
my ($top, $left) = ($win->top, $win->left);
# We'll be rendering relative to the container
$rb->translate(-$top, -$left);
# Ask our container to ask all other floating
# windows to render their frames on our context,
# so we join line segments where expected
$self->{container}->overlay($rb, $rect, $self);
# Restore our origin
# TODO would've thought ->restore should handle this?
$rb->translate($top, $left);
});
my ($w, $h) = map $win->$_ - 1, qw(cols lines);
my $text_pen = $self->get_style_pen('title');
# This is a nasty hack - we want to know whether it's safe to draw
# rounded corners, so we start by checking whether we have any line
# cells already in place in the corners...
# ... then we render our actual border, possibly using a different style for
# active window...
my $line = {
round => LINE_SINGLE,
single => LINE_SINGLE,
thick => LINE_THICK,
double => LINE_DOUBLE,
}->{$self->get_style_values('linetype')};
# So we first render the frame. This will pick up any adjoining lines from
# our overlay, all being well.
$rb->linebox_at(0, $h, 0, $w, $line);
if($self->get_style_values('linetype') eq 'round') {
my $limit = [
$win->root->bottom,
$win->root->right
];
my @corner_char;
CORNER:
foreach my $corner ([0,0], [0,$w], [$h,0], [$h,$w]) {
my ($y, $x) = @$corner;
next CORNER if $y >= $limit->[0] or $x >= $limit->[1] or $x < 0 or $y < 0;
# Apply our window offset... note that ->get_cell will segfault if
# we're outside the render area, so the widget width had better be
# correct here.
my $cell = eval { $rb->get_cell($y, $x); };
# If we have a line segment here, ->linemask should be an object...
next CORNER unless $cell and my $linemask = $cell->linemask;
# ... which we map to a "corner" type
my $corners = join "", grep { $linemask->$_ == LINE_SINGLE } qw( north south east west );
push @corner_char, [
$y, $x, $override{$corners}, $cell->pen
] if exists $override{$corners};
}
# ... and finally we overdraw the corners.
$rb->char_at(@$_) for @corner_char;
}
# Then the title
my $txt = $self->format_label;
$rb->text_at(0, (1 + $w - textwidth($txt)) >> 1, $txt, $text_pen);
# and the icons for min/max/close.
$rb->text_at(0, $w - 3, " ", $self->get_style_pen('maximise'));
$rb->text_at(0, $w - 1, " ", $self->get_style_pen('maximise'));
$rb->text_at(0, $w - 4, "\N{U+25CE}", $self->get_style_pen('maximise'));
$rb->text_at(0, $w - 2, "\N{U+2612}", $self->get_style_pen('close'));
$rb->text_at(0, 1, "[\N{U+25AA}]", $self->get_style_pen('control'));
# Minimise isn't particularly useful, so let's not bother with that one.
# $rb->text_at(0, $w - 5, "\N{U+238A}", Tickit::Pen->new(fg => 'hi-yellow'));
}
method format_label {
' ' . $self->label . ' ';
}
method render_frame ($rb, $target) {
my $win = $self->window or return;
my $line_type = LINE_SINGLE; #LINE_DOUBLE; #$self->is_active ? LINE_DOUBLE : LINE_SINGLE;
$self->with_rb($rb, sub {
my $rb = shift;
( run in 0.929 second using v1.01-cache-2.11-cpan-39bf76dae61 )