Paned window and AspectFrame tutorials.




Here are "tutorials" for my Paned window and AspectFrame widgets.
(They are pretty much just a brief overview with an example.) They
probably really shouldn't be main sections in the tutorial, though
I've marked them that way for now.

Regards,
                                        Owen Taylor
======

<sect> Paned Window Widgets
<p>
The paned window widgets are useful when you want to divide an area
into two parts, with the relative size of the two parts controlled by
the user. A groove is drawn between the two portions with a handle
that the user can drag to change the ratio.  The division can either
be horizontal (HPaned) or vertical (VPaned).

<p>
To create a new paned window, call one of:

<tscreen><verb>
void gtk_hpaned_new (void)
void gtk_vpaned_new (void)
</verb></tscreen>

<p>
After creating the paned window widget, you need to add child widgets
to its two halves. To do this, use the functions:

<tscreen><verb>
void gtk_paned_add1 (GtkPaned *paned, GtkWidget *child)
void gtk_paned_add2 (GtkPaned *paned, GtkWidget *child)
</verb></tscreen>

<tt/gtk_paned_add1()/ adds the child window to the left or top half of
the paned window. <tt/gtk_paned_add2()/ adds the child window to the
right or bottom half of the paned window.

<p>
As an example, we will create part of the user interface of an
imaginary email program. A window is divided into two portions
vertically, with the top portion being a list of email messages and
the bottom portion the text of the email message. Most of the program
is pretty straightforward. A couple of points to note are: Text can't
be added to a Text widget until it is realized. This could be done by
calling <tt/gtk_widget_realize()/, but as a demonstration of an alternate
technique, we connect a handler to the "realize" signal to add the
text. Also, we need to add the <tt/GTK_SHRINK/ option to some of the
items in the table containing the text window and its scrollbars, so
that when the bottom portion is made smaller, the correct portions
shrink instead of being pushed off the bottom of the window.

<tscreen><verb>
#include <gtk/gtk.h>

/* Create the list of "messages" */
GtkWidget *
create_list (void)
{
  GtkWidget *scrolled_window;
  GtkWidget *list;
  GtkWidget *list_item;

  int i;
  char buffer[16];

  /* Create a new scrolled window, with scrollbars only if needed */
  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  /* Create a new list and put it in the scrolled window */
  list = gtk_list_new ();
  gtk_container_add (GTK_CONTAINER(scrolled_window), list);
  gtk_widget_show (list);

  /* Add some messages to the window */
  for (i=0; i<10; i++)
    {
      sprintf(buffer,"Message #%d",i);
      list_item = gtk_list_item_new_with_label (buffer);
      gtk_container_add (GTK_CONTAINER(list), list_item);
      gtk_widget_show (list_item);
    }

  return scrolled_window;
}

/* Add some text to our text widget - this is a callback that is invoked
   when our window is realized. We could also force our window to be
   realized with gtk_widget_realize, but it would have to be part of
   a hierarchy first */
void
realize_text (GtkWidget *text, gpointer data)
{
  gtk_text_freeze (GTK_TEXT (text));
  
  gtk_text_insert (GTK_TEXT (text), NULL, &amp;text->style->black, NULL, 
		   "From: pathfinder@nasa.gov\n"
		   "To: mom@nasa.gov\n"
		   "Subject: Made it!\n"
		   "\n"
		   "We just got in this morning. The weather has been\n"
		   "great - clear but cold, and there are lots of fun sights.\n"
		   "Sojourner says hi. See you soon.\n"
		   "                                      -Path\n", -1);

  gtk_text_thaw (GTK_TEXT (text));
}     

/* Create a scrolled text area that displays a "messages" */
GtkWidget *
create_text (void)
{
  GtkWidget *table;
  GtkWidget *text;
  GtkWidget *hscrollbar;
  GtkWidget *vscrollbar;

  /* Create a table to hold the text widget and scrollbars */
  table = gtk_table_new (2, 2, FALSE);

  /* Put a text widget in the upper left hand corner. Note the use of
     GTK_SHRINK in the y direction */
  text = gtk_text_new (NULL, NULL);
  gtk_table_attach (GTK_TABLE (table), text, 0, 1, 0, 1,
		    GTK_FILL | GTK_EXPAND,
		    GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
  gtk_widget_show (text);

  /* Put a HScrollbar in the lower left hand corner */
  hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
  gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
		    GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (hscrollbar);

  /* And a VScrollbar in the upper right */
  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
  gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
		    GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0);
  gtk_widget_show (vscrollbar);

  /* Add a handler to put a message in the text widget when it is realized */
  gtk_signal_connect (GTK_OBJECT (text), "realize",
		      GTK_SIGNAL_FUNC (realize_text), NULL);

  return table;
}

int 
main (int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *vpaned;
  GtkWidget *list;
  GtkWidget *text;
  
  gtk_init (&amp;argc, &amp;argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  
  gtk_window_set_title (GTK_WINDOW (window), "Paned Windows");
  
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
		      GTK_SIGNAL_FUNC (gtk_exit), NULL);
  
  gtk_container_border_width (GTK_CONTAINER (window), 10);

  /* create a vpaned widget and add it to our toplevel window */

  vpaned = gtk_vpaned_new ();
  gtk_container_add (GTK_CONTAINER(window), vpaned);
  gtk_widget_show (vpaned);

  /* Now create the contents of the two halves of the window */

  list = create_list ();
  gtk_paned_add1 (GTK_PANED(vpaned), list);
  gtk_widget_show (list);

  text = create_text ();
  gtk_paned_add2 (GTK_PANED(vpaned), text);
  gtk_widget_show (text);
  
  gtk_widget_show (window);
  
  gtk_main ();
  
  return 0;
}
</verb></tscreen>

<sect> Aspect Frames
<p>
The aspect frame widget is like a frame widget, except that it also
enforces the aspect ratio (that is, the ratio of the width to the
height) of the child widget to have a certain value, adding extra
space if necessary. This is useful, for instance, if you want to make
a preview of a larger image, The size of the preview should vary when
the user resizes the window, but aspect ratio needs to always match
the original image.

<p>
To create a new aspect frame, use:

<tscreen><verb>
GtkWidget* gtk_aspect_frame_new (const gchar    *label,
				 gfloat          xalign,
				 gfloat          yalign,
				 gfloat          ratio,
				 gint 	         obey_child)
</verb></tscreen>

<p>
<tt/xalign/ and <tt/yalign/ specifiy alignment as with Aligment
widgets. if <tt/obey_child/ is true, the aspect ratio of a child
widget will match the aspect ratio of the ideal size it requests.
Otherwise, it is given by <tt/ratio/.

<p> To change the options of an existing aspect frame, you can use:

<tscreen><verb>
void       gtk_aspect_frame_set (GtkAspectFrame *aspect_frame,
				 gfloat          xalign,
				 gfloat          yalign,
				 gfloat          ratio,
				 gint            obey_child)
</verb></tscreen>

<p>
As an example, the following program uses an AspectFrame to 
present a drawing area whose aspect ratio will always be 2:1, no
matter how the user resizes the top-level window.

<tscreen><verb>
#include <gtk/gtk.h>

int 
main (int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *aspect_frame;
  GtkWidget *drawing_area;
  
  gtk_init (&amp;argc, &amp;argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  
  gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
  
  gtk_signal_connect (GTK_OBJECT (window), "destroy",
		      GTK_SIGNAL_FUNC (gtk_exit), NULL);
  
  gtk_container_border_width (GTK_CONTAINER (window), 10);

  /* Create an aspect_frame and add it to our toplevel window */

  aspect_frame = gtk_aspect_frame_new ("2x1", /* label */
				       0.5, /* center x */
				       0.5, /* center y */
				       2, /* xsize/ysize = 2 */
				       FALSE /* ignore child's aspect */);

  gtk_container_add (GTK_CONTAINER(window), aspect_frame);
  gtk_widget_show (aspect_frame);

  /* Now add a child widget to the aspect frame */

  drawing_area = gtk_drawing_area_new ();

  /* Ask for a 200x200 window, but the AspectFrame will give us a 200x100
     one since we are forcing a 2x1 aspect ratio */
  gtk_widget_set_usize (drawing_area, 200, 200);
  gtk_container_add (GTK_CONTAINER(aspect_frame), drawing_area);
  gtk_widget_show (drawing_area);

  gtk_widget_show (window);
  
  gtk_main ();
  
  return 0;
}

</verb></tscreen>



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