Re: getting the natural size of a widget

Julien Moutinho <[email protected]>
Newsgroups gmane.comp.lang.ocaml.lib.gtk
Message-ID <20080207155209.GA5619@localhost>
On Wed, Feb 06, 2008 at 08:34:04PM +0000, David Powers wrote:
> I am attempting to use the GnoCanvas to build what is essentially a custom
> container.  Placing widgets on the canvas works like a charm, but I can't
> seem to find where the normal containers are reading their sizing hints
> from.  I can read the height/width_request properties, but they seem to be
> minimal sizes (e.g. for a text entry box I get a height and width of 1).
> Does anyone have any hints on where I could go hunting - or maybe I should
> be taking a different approach?

According to the following links, gtk_widget_size_request() is the way
containers read their sizing hints:

http://library.gnome.org/devel/gtk/stable/GtkContainer.html#size-requisition

  "The size requisition phase of the widget layout process operates top-down.
  It starts at a top-level widget, typically a GtkWindow.
  The top-level widget asks its child for its size requisition by calling
  gtk_widget_size_request(). To determine its requisition, the child asks
  its own children for their requisitions and so on.
  Finally, the top-level widget will get a requisition back from its child."

http://library.gnome.org/devel/gtk/stable/GtkWidget.html#gtk-widget-size-request

  "This function is typically used when implementing a GtkContainer subclass.
  Obtains the preferred size of a widget. The container uses this information
  to arrange its child widgets and decide what size allocations to give them
  with gtk_widget_size_allocate()."

Unfortunately, gtk_widget_size_request() has not been wrapped inside LablGTK yet.
However, I'm joining a little patch which wraps it plus an example that may help you.
I've also applied the patch to:
  svn://[email protected]/svn/lablgtk/branches/moutinho

NOTE: my lablgtk2 top-loop fails to run the example:
% lablgtk2 lablgtk_example__size_request.ml
Fatal error: exception Failure("float_of_string")
2%
(This bug may be related to ~x ~y ~width ~height parameters,
because without them it does not fail)

So you may have to run the example with this command:

% ocamlc -g -I +lablgtk2 lablgtk.cma lablgnomecanvas.cma gtkInit.cmo \
    lablgtk_example__size_request.ml && ./a.out
root_group#get_bounds: 0. 0. 0. 0.
widget#get_bounds: 0. 0. 23. 12.
widget#get_bounds: 25. 14. 52. 26.
List.length root_group#get_items = 2
root_group#get_bounds: 0. 0. 52. 26.
found a widget item:
  requested_width  = 23
  requested_height = 12
found a widget item:
  requested_width  = 27
  requested_height = 12

HTH.

_______________________________________________
Lablgtk mailing list
[email protected]
http://yquem.inria.fr/cgi-bin/mailman/listinfo/lablgtk
lablgtk_example__size_request.ml (text/plain, 2.1 KB)
(* ocamlc -g -I +lablgtk2 lablgtk.cma lablgnomecanvas.cma gtkInit.cmo \
     lablgtk_example__size_request.ml && ./a.out *)

let window = GWindow.window () ~show: true in
let _ = window#connect#destroy ~callback: GMain.Main.quit in


let canvas = GnoCanvas.canvas ()
  ~packing: window#add in
let root_group = canvas#root in
let () =
	print_string "root_group#get_bounds:";
	Array.iter (fun x -> print_string (" "^(string_of_float x))) root_group#get_bounds;
	print_endline "" in


let widget = GMisc.label ()
  ~text: "Hello" ~show: true in
let width, height =
	GtkBase.Widget.size_request widget#as_widget in
let width  = float_of_int width
and height = float_of_int height in
let widget = GnoCanvas.widget root_group
  ~widget ~width ~height in
let () =
	print_string "widget#get_bounds:";
	Array.iter (fun x -> print_string (" "^(string_of_float x))) widget#get_bounds;
	print_endline "" in

let widget = GMisc.label ()
  ~text: "World" ~show: true in
let x, y = width +. 2., height +. 2. in
let width, height =
	GtkBase.Widget.size_request widget#as_widget in
let width  = float_of_int width
and height = float_of_int height in
let widget = GnoCanvas.widget root_group
  ~widget ~x ~y ~width ~height in
let () =
	print_string "widget#get_bounds:";
	Array.iter (fun x -> print_string (" "^(string_of_float x))) widget#get_bounds;
	print_endline "" in


print_endline ("List.length root_group#get_items = "^string_of_int (List.length root_group#get_items));
let () =
	print_string "root_group#get_bounds:";
	Array.iter (fun x -> print_string (" "^(string_of_float x))) root_group#get_bounds;
	print_endline "" in
List.iter
  begin fun item ->
	let property =
	  try Some (Gobject.Property.get_dyn item#as_item "widget")
	  with Not_found -> None in
	match property with
	| Some (`OBJECT (Some obj)) ->
		print_endline "found a widget item:";
		let obj = GtkBase.Widget.cast obj in
		let requested_width, requested_height =
		  GtkBase.Widget.size_request obj in
		print_endline ("  requested_width  = "^string_of_int requested_width);
		print_endline ("  requested_height = "^string_of_int requested_height);
	| _ -> ()
  end root_group#get_items;

GMain.Main.main ()
lablgtk__gtk_widget_size_request.patch (text/x-diff, 1.7 KB)
Index: src/ml_gtk.c
===================================================================
--- src/ml_gtk.c	(révision 1386)
+++ src/ml_gtk.c	(copie de travail)
@@ -299,6 +299,18 @@
 ML_2 (gtk_widget_get_ancestor, GtkWidget_val, Int_val, Val_GtkWidget)
 ML_1 (gtk_widget_get_colormap, GtkWidget_val, Val_GdkColormap)
 ML_1 (gtk_widget_get_visual, GtkWidget_val, (value))
+CAMLprim value
+ml_gtk_widget_size_request (value w)
+{
+    CAMLparam1(w);
+    CAMLlocal1(ret);
+    GtkRequisition r;
+    gtk_widget_size_request (GtkWidget_val(w), &r);
+    ret = alloc_small (2,0);
+    Field(ret,0) = Val_int(r.width);
+    Field(ret,1) = Val_int(r.height);
+    CAMLreturn(ret);
+}
 CAMLprim value ml_gtk_widget_get_pointer (value w)
 {
     int x,y;
Index: src/gtkBase.ml
===================================================================
--- src/gtkBase.ml	(révision 1386)
+++ src/gtkBase.ml	(copie de travail)
@@ -64,6 +64,7 @@
   external unrealize : [>`widget] obj -> unit = "ml_gtk_widget_unrealize"
   external queue_draw : [>`widget] obj -> unit = "ml_gtk_widget_queue_draw"
   external queue_resize : [>`widget] obj -> unit = "ml_gtk_widget_queue_resize"
+  external size_request : [>`widget] obj -> Gtk.requisition = "ml_gtk_widget_size_request"
   external draw : [>`widget] obj -> Gdk.Rectangle.t option -> unit
       = "ml_gtk_widget_draw"
 (*
Index: src/gtk.ml
===================================================================
--- src/gtk.ml	(révision 1386)
+++ src/gtk.ml	(copie de travail)
@@ -135,6 +135,7 @@
 type statusbar_context
 type selection_data
 
+type requisition = int * int
 type rectangle  = { x: int; y: int; width: int; height: int }
 type target_entry = { target: string; flags: target_flags list; info: int }
 type box_packing =
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.