Permalink
Browse files

add hover_layout_pos option to control position of hover_layout popups

-each coordinate can be given using a sum of number of pixels or
proportion of the widget size (w), screen size (s), or popup size (p)
-the default reference point is the upper right of the widget, unless the
position is preceded with "abs:" in which case the reference point is 0,0
-if the position is only in w or s, a "smart alignment" of the popup is done:
the popup will be centered, or left aligned if on the left border (0w or 0s),
or right aligned if on the right border (1w or 1s)
examples :
".5w x w" : center bottom of widget, equivalent to ".5w-.5p x w-p"
"abs: .5s x 0" : center top of screen, equivalent to "abs: .5s-.5p x 0"
".5w x w-p-10" : 10 pixels above center bottom of widget
example of use :
Cover(hover_delay=1, hover_layout_pos=.5w x w, hover_layout=some_layout)
  • Loading branch information...
1 parent e1d01d0 commit 41b0c69b455fc37f846304c76e594b7543492513 @squentin committed Jan 26, 2012
Showing with 39 additions and 1 deletion.
  1. +39 −1 gmusicbrowser_layout.pm
@@ -1123,7 +1123,7 @@ sub NewWidget
}
else { $widget->{state_tip}=$tip; }
}
- if ($options{hover_layout}) { $widget->{$_}=$options{$_} for qw/hover_layout hover_delay/; Layout::Window::Popup::set_hover($widget); }
+ if ($options{hover_layout}) { $widget->{$_}=$options{$_} for qw/hover_layout hover_delay hover_layout_pos/; Layout::Window::Popup::set_hover($widget); }
if (my $schange=$ref->{schange})
{ my $fields= $options{fields} || $options{field};
$fields= $fields ? [ split / /,$fields ] : undef;
@@ -2017,11 +2017,49 @@ sub Position
{ my $self=shift;
if ( my $widget= delete $self->{options}{popped_from})
{ ::weaken( $self->{popped_from}=$widget );
+ if (my $pos=$widget->{hover_layout_pos})
+ { my ($x0,$y0)= split /\s*x\s*/,$pos;
+ my ($width,$height)=$self->get_size;
+ my ($x,$y)= $widget->window->get_origin;
+ my ($ww,$wh)=$widget->window->get_size;
+ if ($widget->no_window)
+ { (my$wx,my$wy,$ww,$wh)=$widget->allocation->values;
+ $x+=$wx;$y+=$wy;
+ }
+ $x=$y=0 if $x0=~s/abs:\s*//;
+ my $screen=$widget->get_screen;
+ $x+=_compute_pos($x0,$width, $ww,$screen->get_width);
+ $y+=_compute_pos($y0,$height,$wh,$screen->get_height);
+ return $x,$y;
+ }
return ::windowpos($self,$widget);
}
$self->SUPER::Position;
}
+sub _compute_pos
+{ my ($def,$wp,$ww,$ws)=@_;
+ my %h;
+ $def="+$def" unless $def=~m/^[-+]/;
+ ::setlocale(::LC_NUMERIC, 'C'); # so that decimal separator is the dot
+ # can parse strings such as : +3s/2-w-p/2+20
+ for my $v ($def=~m/([-+][^-+]+)/g)
+ { if ($v=~m#([-+](?:\d*\.)?\d*)([pws])(?:/([0-9]+))?#)
+ { $h{$2}= ($1 eq '+' ? 1 : $1 eq '-' ? -1 : $1) / ($3||1);
+ }
+ elsif ($v=~m/^[-+]\d+$/) { $h{n}=$v }
+ }
+ ::setlocale(::LC_NUMERIC, '');
+ # smart alignment if alignment not specified and only widget or screen relative
+ if (!defined $h{p} && (defined $h{w} xor defined $h{s}) && !$h{n})
+ { my $ws= $h{w} || $h{s} || 0;
+ $h{p}= $ws==0 ? 0 : $ws==1 ? -1 : -.5;
+ }
+ $h{$_}||=0 for qw/n p w s/;
+ my $x= $h{n} + $h{p}*$wp + $h{w}*$ww + $h{s}*$ws;
+ return $x;
+}
+
sub HoverPopup
{ my $widget=shift;
delete $widget->{hover_timeout};

0 comments on commit 41b0c69

Please sign in to comment.