the
section called Size Allocation in the chapter
called GTK+ Basics describes the size
negotiation process; be sure you're familiar with it
before reading this section.
There's no obvious "right" size for GtkEv, so the size request method
requests an arbitrary size that looks nice:
static void
gtk_ev_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
g_return_if_fail(widget != NULL);
g_return_if_fail(GTK_IS_EV(widget));
/*
* GtkEv always wants to be the same fixed size.
*/
requisition->width = 450;
requisition->height = 300;
}
|
GTK+ takes care of storing a widget's last size request
in
widget->requisition.
If GtkEv were a real-life
widget rather than an illustrative example, it would be
unnecessary to implement a size request method. The
default GtkWidget method
simply returns the current value of widget->requisition, so GtkEv could initialize widget->requisition in gtk_ev_init() and use the default method.
Alternatively, the size request method could be
implemented more elaborately;
GtkEv could attempt to predict the maximum width of
the text to be displayed, for example.
Once a widget's parent container decides how much space
is actually available, the widget receives a size
allocation. The size allocation method should do the
following:
-
Assign the new allocation to widget->allocation; this does
not happen automatically, as
it does for
widget->requisition.
-
Divide the allocation among any child widgets.
-
Resize any
GdkWindows, if the widget is realized.
-
Perform any widget-specific tasks; for example, GtkEv updates the two GdkRectangles representing
its internal layout.
Here is the GtkEv size
allocation method; it should be self-explanatory:
static void
gtk_ev_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
static const gint spacing = 10;
GtkEv* ev;
g_return_if_fail(widget != NULL);
g_return_if_fail(GTK_IS_EV(widget));
ev = GTK_EV(widget);
widget->allocation = *allocation;
ev->event_window_rect.width =
MAX(allocation->width - spacing*2, 0);
ev->event_window_rect.height =
MAX(allocation->height / 5 - spacing / 2, 0);
ev->event_window_rect.x =
(allocation->width - ev->event_window_rect.width)/2;
ev->event_window_rect.y =
MIN(spacing, allocation->height);
ev->description_rect.x = ev->event_window_rect.x;
ev->description_rect.y =
ev->event_window_rect.y + ev->event_window_rect.height + spacing;
ev->description_rect.width =
ev->event_window_rect.width;
ev->description_rect.height =
MAX((allocation->height - ev->event_window_rect.height - spacing*3), 0);
if (GTK_WIDGET_REALIZED (widget))
{
gdk_window_move_resize (widget->window,
allocation->x,
allocation->y,
allocation->width,
allocation->height);
gdk_window_move_resize (ev->event_window,
ev->event_window_rect.x,
ev->event_window_rect.y,
ev->event_window_rect.width,
ev->event_window_rect.height);
}
}
|