Re: Placement of popup ( CellRendererDate from examples )




On Sep 5, 2005, at 11:28 PM, Daniel Kasak wrote:

muppet wrote:

I know ( or I think I know anyway ... I haven't tried it yet ) I can do $popup->allocation to get the size of the popup.

There's also get_size_request(), which will ask the widget to calculate the size it wants (which propagates to children); you can use this before the widget is onscreen to avoid flicker.

This is returning -1 for x and y sizes.

I told you wrong; gtk_widget_get_size_request() merely fetches the existing size request, which is -1,-1 before the widget goes onscreen. gtk_widget_size_request() asks the widget to calculate and populate the requisition. I can never remember which is which without going to the docs...

But in this case, it doesn't matter, because the widget it fully realized offscreen.

But now that i look at it, this is pretty hackish, and can actually result in obnoxious flicker if you have another screen configured to the left and above the main one, and even worse if the screen at -500,-500 has a different font size. Unlikely, but hey, it's a chance to learn how to use size_request() properly.

# ensure that you've already called show() on all children of $popup
    $popup->realize();
    my $requisition = $popup->size_request();
    my $popup_width = $requisition->width;
    my $popup_height = $requisition->height;
    ...
    $popup->move (...);
    $popup->show;


This leaves you open the the possibility that the allocation is not the same as the requisition, but doesn't map-then-move the window.



Not to worry - allocation() is working fine, and I've got a working solution now. I've attached a patch, against the cellrenderer_date.pl from Gtk2-1.081, to fix the issue ... it's a damned useful example ... maybe even a candidate for Gtk2::Ex::CoolStuff or something?

Is this the right place to send patches for the example apps?

Yep.


--- cellrenderer_date.pl.original 2005-09-06 12:26:08.000000000 +1000
+++ cellrenderer_date.pl    2005-09-06 12:27:47.000000000 +1000
@@ -212,14 +212,26 @@
   $popup -> move(-500, -500);
   $popup -> show_all();

- # Align the top right edge of the popup with the the bottom right edge of the
-  # cell.
+  # Figure out where to put the popup - ie don't put it offscreen,
+  # as it's not movable ( by the user )
+  my $screen_height = $popup->get_screen->get_height;
+  my $popup_height = $popup->allocation->height;
+
my ($x_origin, $y_origin) = $view -> get_bin_window() -> get_origin();
-
-  $popup -> move(
- $x_origin + $cell_area -> x() + $cell_area -> width() - $popup -> allocation() -> width(),
-    $y_origin + $cell_area -> y() + $cell_area -> height()
-  );
+
+  my ($popup_x, $popup_y);
+
+ if ($x_origin + $cell_area -> x() + $cell_area -> width() - $popup -> allocation() -> width() < 0) {
+    $popup_x = 0;
+  } else {
+ $popup_x = $x_origin + $cell_area -> x() + $cell_area -> width () - $popup -> allocation() -> width();
+  }

For brevity and to avoid repeating yourself,

   $popup_x = big hairy calculation;
   $popup_x = 0 if $popup_x < 0;

+ if ($y_origin + $cell_area->y + $cell_area->height + $popup_height > $screen_height) {
+    $popup_y = $screen_height - $popup_height;

That just anchors it at the bottom of the screen. Less surprising, and somewhat more useful, is to hang the popup off the top edge of the cell instead of the bottom edge, like so:

  my $popup_y = $y_origin + $cell_area -> y() + $cell_area -> height();
  if ($popup_y + $popup_height > $screen_height) {
    $popup_y = $y_origin + $cell_area -> y() - $popup_height;
  }

That way, the user can still click the arrow to pop down easily, e.g., if it was an accident to pop it up in the first place. ;-)

+  } else {
+ $popup_y = $y_origin + $cell_area -> y() + $cell_area -> height ();
+  }

And don't forget to add back the

  $popup->move ($popup_x, $popup_y);


   # Grab the focus and the pointer.
   Gtk2 -> grab_add($popup);


It's handy; i'll commit that.  You still get credit.  :-)


--
Without treatment, a common cold will last about seven days.
With treatment, it will last about a week.
  -- conventional wisdom




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]