Compare commits

...

80 Commits

Author SHA1 Message Date
Tristan Van Berkom
54d44a9bd0 Merge branch 'master' into native-layout
Conflicts:
	gtk/gtkplug.c
	gtk/gtkscrolledwindow.c
2010-08-30 14:56:28 +09:00
Tristan Van Berkom
b3b22c31b9 Merge branch 'master' into native-layout 2010-08-21 12:38:55 -04:00
Tristan Van Berkom
dd6aa6d1cf Merge branch 'master' into native-layout
Conflicts:
	tests/testheightforwidth.c
2010-08-18 20:03:24 -04:00
Tristan Van Berkom
4f47197d33 Removed unused variables. 2010-08-18 19:27:13 -04:00
Tristan Van Berkom
4a2905c34b Fixed gtk_cell_view_allocate() to allocate a fixed array size instead of using
a growing dynamic GArray in a loop.
2010-08-18 19:11:01 -04:00
Tristan Van Berkom
99babef4b8 Merge branch 'master' into native-layout 2010-08-18 15:43:40 -04:00
Tristan Van Berkom
d25c4f9dc1 Added test to show wrapping text in combo boxes and menu items. 2010-08-18 15:23:46 -04:00
Tristan Van Berkom
ddd32757be Fixed combo box's custom menu positioning function to work with new
height-for-width menus.
2010-08-18 15:17:22 -04:00
Tristan Van Berkom
4ff413f48d Added height-for-width geometry management to menus
Now menus can be height-for-width, for a menu to be
height for width it must have a width explicitly set
with gtk_widget_set_size_request()... if such a request
is set then menus will be allocated a smaller height
for the larger provided width (if you have any
wrapping content in the menu items)
2010-08-18 15:14:59 -04:00
Tristan Van Berkom
59aacd7935 Fixing accel label to do its thing in ->get_width() instead
of the old ->size_request()
2010-08-18 15:13:39 -04:00
Tristan Van Berkom
72856830e7 Merge branch 'master' into native-layout 2010-08-17 01:39:09 -04:00
Tristan Van Berkom
94f7cf0347 Fixed height-for-width implementation for combobox/cellview
Now the combo box requests height-for-width properly taking
into account all of its cells at request/allocation time.

Note an implementation of menu-items is needed to get the
the combo's drop-down menu to condense to a proper (smaller)
height when given enough width.
2010-08-17 01:33:11 -04:00
Tristan Van Berkom
c4119e58cf Clipped values for gtk_distribute_natural_allocation() 2010-08-17 01:32:44 -04:00
Tristan Van Berkom
1b526bfcc1 Fixed cellrenderertext to always request a natural width >= minimum width. 2010-08-17 01:30:52 -04:00
Tristan Van Berkom
7d3cb3f9d9 Added an argument check to gtk_distribute_natural_allocation()
and clipped some values in gtkbox.c in case it was allocated less
than it requested.
2010-08-17 01:29:23 -04:00
Tristan Van Berkom
6a5f77a992 Merge branch 'master' into native-layout 2010-08-16 12:02:02 -04:00
Tristan Van Berkom
8740bd2faf Merge branch 'master' into native-layout
Conflicts:
	gtk/gtkframe.c
	tests/testheightforwidth.c
2010-08-07 19:24:35 -04:00
Tristan Van Berkom
360e2c4dd5 Make GtkFrame allocate its label considering natural size requests
Also like the GtkExpander, the label widget is allocated the minimum
height for its allocated width and the remaining space is given to
the child, test case included.
2010-08-06 15:58:12 -04:00
Tristan Van Berkom
fd66586b33 Pulling back some cleanup/changes from the incubator branch 2010-08-06 14:22:59 -04:00
Tristan Van Berkom
add39dfea8 Merge branch 'master' into native-layout 2010-08-06 13:20:57 -04:00
Tristan Van Berkom
a4086282c1 Fixed some merge problems (matching updates from the incubator branch) 2010-08-05 16:59:17 -04:00
Tristan Van Berkom
c3da4007db Fixed merge problem 2010-08-05 16:55:35 -04:00
Tristan Van Berkom
e569c77648 Removed useless struct definition (oops) 2010-08-05 16:54:13 -04:00
Tristan Van Berkom
f0b205f40c Merge branch 'master' into native-layout
Conflicts:
	gtk/gtkbox.c
	gtk/gtkcellrenderer.c
	gtk/gtkcellrenderertext.c
	gtk/gtkcellview.c
	gtk/gtkcombobox.c
	gtk/gtkexpander.c
	gtk/gtkiconview.c
	gtk/gtkplug.c
	gtk/gtkscrolledwindow.c
	gtk/gtksizerequest.c
	gtk/gtksocket.c
	gtk/gtktreeview.c
	gtk/gtktreeviewcolumn.c
	tests/testheightforwidth.c
2010-08-05 14:24:42 -04:00
Tristan Van Berkom
a564e69e51 Merge branch 'master' into native-layout 2010-06-30 10:02:19 -04:00
Tristan Van Berkom
84e2a854dd Merge branch 'master' into native-layout
Conflicts:
	gtk/gtktreeview.c
2010-06-29 17:13:19 -04:00
Tristan Van Berkom
237d97dc25 Augmented the wrapping treeview test to include a scrolled window. 2010-06-29 17:06:53 -04:00
Tristan Van Berkom
6d47681722 GtkTreeview now watches the allocation of the parent scrolled window
at allocation time in order to detect possible feedback loops.

To avoid locking up the desktop some feedback protection is needed,
this patch is not the best but as far as I can see it does the job.
Ideally we should be looking into a GtkScrollable interface that
takes this height-for-width possibility into account.

The problem being that some height-for-width calculations at
allocation time are asynchronous and at some sizes cause the
height-for-width logic to compete with parent allocations
which change due to scrollbars toggling visiblity.

Specific considerations
  a.) The child treeview should not have knowlage of its parents
      allocation or the size of the scrollbars (this patch cheats
      that idealistic rule).
  b.) The parent scrolled window cannot safely determine if a child
      wants its size renegotiated based on a content change or based
      on a previous allocation
2010-06-29 17:01:13 -04:00
Tristan Van Berkom
0809e06881 Made scrolled windows forward along the height-for-width request in
the off-chance that both scrollbars are set to never appear.
2010-06-29 11:24:00 -04:00
Tristan Van Berkom
6d9d23009c Merge branch 'master' into native-layout 2010-06-27 18:40:20 -04:00
Tristan Van Berkom
93b76327ec Changed default window width of wrapping treeview height-for-width demo. 2010-06-27 18:37:53 -04:00
Tristan Van Berkom
a30585167f Filtered GtkCellSizeRequest apis to explicitly return GtkCellRenderer fixed sizes if any are set. 2010-06-27 18:36:53 -04:00
Tristan Van Berkom
deab62c29e Changed private api to allow setting a column dirty without resetting the width
(used when only the height is known to be dirty).
2010-06-27 18:35:54 -04:00
Tristan Van Berkom
02c37eb098 Fixed initial height of treeview when cells are wrapping to allocation.
This commit also adresses the refresh a little more gently and avoids
a lockup when resizing the 'editable cells' demo.
2010-06-27 18:33:56 -04:00
Tristan Van Berkom
ea4d2f9a52 Merge branch 'master' into native-layout 2010-06-26 13:25:40 -04:00
Tristan Van Berkom
bba9e3e070 Added test to demonstrate height-for-width tradeoffs in expander
labels.
2010-06-26 13:22:58 -04:00
Tristan Van Berkom
89a8f35b28 Implemented GtkSizeRequest interface on GtkExpander
In this particular case the label widget is never allocated
anything more than its natural width or its minimum height for
that width (thus prioritizing the content area to the label height).

We could allocate to the full available allocation but
  a.) focus would be drawn around the complete allocation
      instead of only the label
  b.) labels in expanders will need explicit alignments
2010-06-26 13:20:02 -04:00
Tristan Van Berkom
c71bf29d24 Properly separated get_width/get_height code for GtkScrolledWindow
This makes sure only one direction of the children is queried at
a time (and the previous code had a bug when calculating the
extra space for scrollbars).
2010-06-26 13:18:04 -04:00
Tristan Van Berkom
1d0650f871 Merge branch 'master' into native-layout
Conflicts:
	gtk/gtktreeview.c
2010-06-25 12:25:28 -04:00
Tristan Van Berkom
9d97153738 Added test to demonstrate word-wrapping cell renderers in treeviews. 2010-06-24 19:23:45 -04:00
Tristan Van Berkom
86f360fec2 Merge branch 'master' into native-layout 2010-06-24 18:09:33 -04:00
Tristan Van Berkom
f1998d568a Simulate gtk_cell_renderer_get_size() with height-for-width api
Same as GtkWidget does with GtkSizeRequestIface, this will allow
removal of the ->get_size() implementation for renderers that
implement the new api.
2010-06-24 18:09:08 -04:00
Tristan Van Berkom
9f3ad94e75 Fixed some faulty comparisons. 2010-06-24 18:09:08 -04:00
Tristan Van Berkom
4dbbcefe7c Fixed allocation of column buttons (was miscalculating padding). 2010-06-24 18:09:07 -04:00
Tristan Van Berkom
27065e257b Fixed treeview column allocations
Fixed allocations so that the column->width is not to
mention any padding taken into account by the treeview
(it's the allocated width of the column without padding/spacing).
2010-06-24 18:09:07 -04:00
Tristan Van Berkom
fca8db084d Fixed treecolumn's get_width() implementation to report collective width
based on cached widths of all rows.
2010-06-24 18:09:07 -04:00
Tristan Van Berkom
103f3a6a18 Fixed cell renderer to properly export it's height-for-width implementation. 2010-06-24 18:09:07 -04:00
Paolo Borelli
c683dffa9e Do not leak devices list in do_focus_change 2010-06-24 18:09:07 -04:00
noch
ecedc58113 Added Armenian translation - po file. 2010-06-24 18:09:07 -04:00
noch
4a7c237b79 Modified Armenian translation - po file. 2010-06-24 18:09:07 -04:00
noch
2f2486bd5b Added Armenian translation - po file. Modified LINGUAS. 2010-06-24 18:09:07 -04:00
Javier Jardón
ff82a56f28 [gtk] Add gtk_font_selection_dialog_get_font_selection()
This is needed to access the fontsel sealed member.
2010-06-24 18:09:07 -04:00
Javier Jardón
f463059f00 [test] Exclude message-area as it's a object property 2010-06-24 18:09:07 -04:00
Javier Jardón
6d16148936 Add new api to gtk.symbols
Add newly added api gtk_accessible_set_widget() and
gtk_message_dialog_get_message_area()
2010-06-24 18:09:07 -04:00
Jorge González
92ae8ebb01 Updated Spanish translation 2010-06-24 18:09:06 -04:00
Javier Jardón
380120bda9 [gtkaccessible] Use the correct guards in gtk_accessible_set_widget()
Also, allow the widget variable to be NULL
2010-06-24 18:09:06 -04:00
Tor Lillqvist
2517035bc0 Generate correct grab broken event for WM_KILLFOCUS
WM_KILLFOCUS means that a keyboard grab (not a pointer grab), if any,
has been broken. I don't think this bug has matterd much as gtk
generates a grab-broken-event signal for both keybord and pointer
grabs being broken anyway.
2010-06-24 18:09:06 -04:00
Federico Mena Quintero
3651dc278d bgo#328069 - Add gtk_message_dialog_get_message_area()
Signed-off-by: Federico Mena Quintero <federico@novell.com>
2010-06-24 18:09:06 -04:00
Vincent Untz
2c7058bd13 bgo#622371 - Add gtk_accessible_set_widget() - the widget field was GSEAL()ed.
https://bugzilla.gnome.org/show_bug.cgi?id=622371
2010-06-24 18:09:06 -04:00
Chris Kühl
ed639b211e [docs] Fixes issue with GtkEntryBuffer signal documentation 2010-06-24 18:09:06 -04:00
Murray Cumming
49f050a9bc gtkenums.h: Remove trailing comma to fix warning. 2010-06-24 18:09:06 -04:00
Tristan Van Berkom
51dadc0a1a Added test case to reflect natural size allocations in GtkTreeView and GtkTreeViewColumn 2010-06-23 18:02:05 -04:00
Tristan Van Berkom
1700cbe458 Implemented natural size allocations in GtkTreeView and GtkTreeViewColumn
This patch adds gtk_tree_view_column_allocate_width() to compute
the renderer allocation when the column width changes, furthermore
it effects treeview to allocate columns respecting their natural
widths (height-for-width requests still not effecting row heights).
2010-06-23 17:55:45 -04:00
Tristan Van Berkom
ee097eb7ab Fixing debug build (s/extended layout/size request/ in GTK_NOTE flags). 2010-06-23 17:53:30 -04:00
Tristan Van Berkom
9f6c01c665 Refactored gtk_tree_view_column_cell_process_action() and removed
much redundant code.
2010-06-22 13:43:21 -04:00
Tristan Van Berkom
101ad51803 Added height-for-width apis to treeviewcolumn
Added get_natural_width() and get_height_for_width() apis
which need to be treated in a special way from treeview because
of the intricate nature of treeviews and thier requirements:
  - get_natural_width() must be called in the request phase for
    every row which will cache the ->requested_width and ->natural_width
  - get_height_for_width() must be called only after caching the widths
    for the entire view
2010-06-22 13:01:39 -04:00
Tristan Van Berkom
99f73c09f6 Revert "Fixed GtkSpinner to request 12x12 at init time instead of at expose time."
This reverts commit 0dff033a64.

That commit was introduced as a workaround to an erronous state
in the extended layout work, it was not merged into master and
this new commit backs it out from native-layout branch.
2010-06-20 14:30:03 -04:00
Tristan Van Berkom
7c66a29e87 Merge branch 'master' into native-layout 2010-06-20 14:23:14 -04:00
Tristan Van Berkom
0eff4061ab Some more gtk-doc corrections 2010-06-20 14:19:10 -04:00
Tristan Van Berkom
9653cf57b6 Make cell renderer's wrap to allocation. 2010-06-20 14:16:01 -04:00
Tristan Van Berkom
06a5095dc5 Created a _gtk_distribute_allocation() helper function for size allocators.
Migrated a portion of the GtkBox allocator loop to live in
a private function and be reused for distribution of space along
a single orientation.
2010-06-18 19:40:02 -04:00
Tristan Van Berkom
ee9115fb9f Mass API change commit GtkExtendedCell --> GtkCellSizeRequest
This commit moves gtkextendedcell.[ch] --> gtkcellsizerequest.[ch]
and effects the API change all over the tree.

Furthermore it includes the initial height-for-width implementation
on GtkCellRendererText.
2010-06-18 17:07:03 -04:00
Tristan Van Berkom
33d3f72b98 More gtk-doc cleanup 2010-06-18 17:06:29 -04:00
Tristan Van Berkom
4ef145bda6 Merge branch 'master' into native-layout
Conflicts:
	gtk/Makefile.am
	gtk/gtk.h
	gtk/gtk.symbols
	gtk/gtksizerequest.c
2010-06-18 00:44:00 -04:00
Tristan Van Berkom
6e705d7087 Completed missing peices of the GtkExtendedCell api 2010-06-17 20:58:59 -04:00
Tristan Van Berkom
c2abe27b03 Created _gtk_cell_renderer_calc_offset()
Created an internal helper to replace the meaningless 'cell_area',
'x_offset' and 'y_offset' from gtk_cell_renderer_get_size() which
will be deprecated in favor of the new h4w api. At this point GTK+
does no longer depend on renderers calculating this alignment and
its safe to change the calls to gtk_extended_cell_get_desired_size().
2010-06-17 20:58:59 -04:00
Tristan Van Berkom
c20c3fd757 Mass api change from GtkExtendedLayout --> GtkSizeRequest part 2.
This commit makes the api change on the remaining portions of the
native-layout branch.
2010-06-17 20:41:01 -04:00
Tristan Van Berkom
c5a0e04a8d Mass api change from GtkExtendedLayout --> GtkSizeGroup
This commit makes a few massive changes to the extended layout
code:
  a.) gtkextendedlayout.c --> gtksizerequest.c
  b.) _is_height_for_width --> get_request_mode()
  c.) get_desired_size(), get_desired_width(), get_desired_height() -->
      get_size(), get_width(), get_height()

This is the first partial commit and only effects portions
of the tree that have already been merged in master (in order to
easily cherry pick this commit).
2010-06-17 20:38:16 -04:00
Tristan Van Berkom
f04f94e881 Merge branch 'master' into native-layout 2010-06-15 15:04:53 -04:00
Tristan Van Berkom
16715a662e Revert "Mega commit backing out everything from the native-layout branch that"
This reverts commit 2a5272647d.

Conflicts:

	gtk/gtk.symbols
	gtk/gtkextendedlayout.c
2010-06-11 15:44:56 -04:00
14 changed files with 1732 additions and 729 deletions

View File

@@ -4065,6 +4065,7 @@ gtk_tree_view_column_clicked
gtk_tree_view_column_focus_cell
gtk_tree_view_column_get_alignment
gtk_tree_view_column_get_clickable
gtk_tree_view_column_get_desired_size
gtk_tree_view_column_get_expand
gtk_tree_view_column_get_fixed_width
gtk_tree_view_column_get_max_width

View File

@@ -40,6 +40,7 @@
#include "gtkcombobox.h"
#include "gtktextbuffer.h"
#include "gtktreednd.h"
#include "gtkcellsizerequest.h"
#include "gtkprivate.h"
/**
@@ -2939,6 +2940,7 @@ adjust_wrap_width (GtkIconView *icon_view,
if (icon_view->priv->text_cell != -1 &&
icon_view->priv->pixbuf_cell != -1)
{
GtkRequisition min_size;
gint item_width;
text_info = g_list_nth_data (icon_view->priv->cell_list,
@@ -2946,12 +2948,10 @@ adjust_wrap_width (GtkIconView *icon_view,
pixbuf_info = g_list_nth_data (icon_view->priv->cell_list,
icon_view->priv->pixbuf_cell);
gtk_cell_renderer_get_size (pixbuf_info->cell,
GTK_WIDGET (icon_view),
NULL, NULL, NULL,
&pixbuf_width,
NULL);
gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (pixbuf_info->cell),
GTK_WIDGET (icon_view),
&min_size, NULL);
pixbuf_width = min_size.width;
if (icon_view->priv->item_width > 0)
item_width = icon_view->priv->item_width;
@@ -3006,14 +3006,16 @@ gtk_icon_view_calculate_item_size (GtkIconView *icon_view,
for (l = icon_view->priv->cell_list; l; l = l->next)
{
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
GtkRequisition min_size;
if (!gtk_cell_renderer_get_visible (info->cell))
continue;
gtk_cell_renderer_get_size (info->cell, GTK_WIDGET (icon_view),
NULL, NULL, NULL,
&item->box[info->position].width,
&item->box[info->position].height);
gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (info->cell),
GTK_WIDGET (icon_view),
&min_size, NULL);
item->box[info->position].width = min_size.width;
item->box[info->position].height = min_size.height;
if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
@@ -3065,7 +3067,8 @@ gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view,
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
{
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
GtkRequisition min_size;
if (info->pack == (k ? GTK_PACK_START : GTK_PACK_END))
continue;
@@ -3090,10 +3093,17 @@ gtk_icon_view_calculate_item_size2 (GtkIconView *icon_view,
cell_area.height = max_height[i];
}
gtk_cell_renderer_get_size (info->cell, GTK_WIDGET (icon_view),
&cell_area,
&item->box[info->position].x, &item->box[info->position].y,
&item->box[info->position].width, &item->box[info->position].height);
gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (info->cell),
GTK_WIDGET (icon_view),
&min_size, NULL);
item->box[info->position].width = min_size.width;
item->box[info->position].height = min_size.height;
_gtk_cell_renderer_calc_offset (info->cell, &cell_area,
gtk_widget_get_direction (GTK_WIDGET (icon_view)),
item->box[info->position].width, item->box[info->position].height,
&item->box[info->position].x, &item->box[info->position].y);
item->box[info->position].x += cell_area.x;
item->box[info->position].y += cell_area.y;

View File

@@ -47,6 +47,7 @@
#include "gtkplugprivate.h"
#include "x11/gdkx.h"
#include <X11/Xatom.h>
#include "gtkxembed.h"
@@ -408,3 +409,29 @@ _gtk_plug_windowing_filter_func (GdkXEvent *gdk_xevent,
return return_val;
}
void
_gtk_plug_windowing_publish_natural_size (GtkPlug *plug,
GtkRequisition *requisition)
{
GtkWidget *widget = GTK_WIDGET (plug);
GdkDisplay *display;
GdkWindow *window;
gint32 data[2];
Atom property;
gtk_widget_realize (widget);
window = GTK_WIDGET (plug)->window;
display = gdk_drawable_get_display (window);
property = gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE");
data[0] = requisition->width;
data[1] = requisition->height;
XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
GDK_WINDOW_XWINDOW (window), property,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char*)data, 2);
}

View File

@@ -30,6 +30,7 @@
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkplug.h"
#include "gtksizerequest.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkplugprivate.h"
@@ -792,8 +793,12 @@ static void
gtk_plug_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkRequisition natural_size;
GtkBin *bin = GTK_BIN (widget);
GtkWidget *child;
child = gtk_bin_get_child (bin);
if (gtk_widget_is_toplevel (widget))
GTK_WIDGET_CLASS (gtk_plug_parent_class)->size_allocate (widget, allocation);
else
@@ -807,8 +812,6 @@ gtk_plug_size_allocate (GtkWidget *widget,
allocation->x, allocation->y,
allocation->width, allocation->height);
child = gtk_bin_get_child (bin);
if (child != NULL && gtk_widget_get_visible (child))
{
GtkAllocation child_allocation;
@@ -823,6 +826,10 @@ gtk_plug_size_allocate (GtkWidget *widget,
}
}
gtk_size_request_get_size (GTK_SIZE_REQUEST (child),
NULL, &natural_size);
_gtk_plug_windowing_publish_natural_size (GTK_PLUG (widget), &natural_size);
}
static gboolean

View File

@@ -150,4 +150,7 @@ GdkFilterReturn _gtk_plug_windowing_filter_func (GdkXEvent *gdk_xevent,
GdkEvent *event,
gpointer data);
void _gtk_plug_windowing_publish_natural_size (GtkPlug *plug,
GtkRequisition *requisition);
#endif /* __GTK_PLUG_PRIVATE_H__ */

View File

@@ -1749,168 +1749,106 @@ _gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window)
}
}
static GtkSizeRequestIface *parent_size_request_iface;
static void
gtk_scrolled_window_size_request_init (GtkSizeRequestIface *iface)
{
parent_size_request_iface = g_type_interface_peek_parent (iface);
iface->get_width = gtk_scrolled_window_get_width;
iface->get_height = gtk_scrolled_window_get_height;
iface->get_height_for_width = gtk_scrolled_window_get_height_for_width;
iface->get_width_for_height = gtk_scrolled_window_get_width_for_height;
}
static void
gtk_scrolled_window_get_size (GtkSizeRequest *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkScrolledWindow *scrolled_window;
GtkBin *bin;
gint extra_width;
gint extra_height;
gint scrollbar_spacing;
GtkRequisition hscrollbar_requisition;
GtkRequisition vscrollbar_requisition;
GtkRequisition minimum_req, natural_req;
GtkStyle *style;
GtkWidget *child;
gint min_child_size, nat_child_size;
guint border_width;
scrolled_window = GTK_SCROLLED_WINDOW (widget);
bin = GTK_BIN (scrolled_window);
scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
extra_width = 0;
extra_height = 0;
minimum_req.width = 0;
minimum_req.height = 0;
natural_req.width = 0;
natural_req.height = 0;
gtk_widget_size_request (scrolled_window->hscrollbar,
&hscrollbar_requisition);
gtk_widget_size_request (scrolled_window->vscrollbar,
&vscrollbar_requisition);
child = gtk_bin_get_child (bin);
if (child && gtk_widget_get_visible (child))
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
&min_child_size,
&nat_child_size);
if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER)
{
minimum_req.width += min_child_size;
natural_req.width += nat_child_size;
}
else
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (child, FALSE);
if (aux_info && aux_info->width > 0)
{
minimum_req.width += aux_info->width;
natural_req.width += aux_info->width;
extra_width = -1;
}
else
{
minimum_req.width += vscrollbar_requisition.width;
natural_req.width += vscrollbar_requisition.width;
}
}
}
else /* GTK_ORIENTATION_VERTICAL */
{
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
&min_child_size,
&nat_child_size);
if (scrolled_window->vscrollbar_policy == GTK_POLICY_NEVER)
{
minimum_req.height += min_child_size;
natural_req.height += nat_child_size;
}
else
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (child, FALSE);
if (aux_info && aux_info->height > 0)
{
minimum_req.height += aux_info->height;
natural_req.height += aux_info->height;
extra_height = -1;
}
else
{
minimum_req.height += hscrollbar_requisition.height;
natural_req.height += hscrollbar_requisition.height;
}
}
}
}
if (scrolled_window->hscrollbar_policy == GTK_POLICY_AUTOMATIC ||
scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
{
minimum_req.width = MAX (minimum_req.width, hscrollbar_requisition.width);
natural_req.width = MAX (natural_req.width, hscrollbar_requisition.width);
if (!extra_height || scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
extra_height = scrollbar_spacing + hscrollbar_requisition.height;
}
if (scrolled_window->vscrollbar_policy == GTK_POLICY_AUTOMATIC ||
scrolled_window->vscrollbar_policy == GTK_POLICY_ALWAYS)
{
minimum_req.height = MAX (minimum_req.height, vscrollbar_requisition.height);
natural_req.height = MAX (natural_req.height, vscrollbar_requisition.height);
if (!extra_height || scrolled_window->vscrollbar_policy == GTK_POLICY_ALWAYS)
extra_width = scrollbar_spacing + vscrollbar_requisition.width;
}
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
minimum_req.width += border_width * 2 + MAX (0, extra_width);
minimum_req.height += border_width * 2 + MAX (0, extra_height);
natural_req.width += border_width * 2 + MAX (0, extra_width);
natural_req.height += border_width * 2 + MAX (0, extra_height);
if (scrolled_window->shadow_type != GTK_SHADOW_NONE)
{
style = gtk_widget_get_style (GTK_WIDGET (widget));
minimum_req.width += 2 * style->xthickness;
minimum_req.height += 2 * style->ythickness;
natural_req.width += 2 * style->xthickness;
natural_req.height += 2 * style->ythickness;
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
if (minimum_size)
*minimum_size = minimum_req.width;
if (natural_size)
*natural_size = natural_req.width;
}
else
{
if (minimum_size)
*minimum_size = minimum_req.height;
if (natural_size)
*natural_size = natural_req.height;
}
}
static void
gtk_scrolled_window_get_width (GtkSizeRequest *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_scrolled_window_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
GtkScrolledWindow *scrolled_window;
GtkRequisition hscrollbar_requisition;
GtkRequisition vscrollbar_requisition;
GtkStyle *style;
GtkWidget *child;
gint min_width, nat_width;
gint min_child_size, nat_child_size;
gint extra_width, border_width;
gint scrollbar_spacing;
scrolled_window = GTK_SCROLLED_WINDOW (widget);
child = gtk_bin_get_child (GTK_BIN (scrolled_window));
scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
extra_width = 0;
min_width = 0;
nat_width = 0;
gtk_widget_size_request (scrolled_window->hscrollbar,
&hscrollbar_requisition);
gtk_widget_size_request (scrolled_window->vscrollbar,
&vscrollbar_requisition);
if (child && gtk_widget_get_visible (child))
{
gtk_size_request_get_width (GTK_SIZE_REQUEST (child),
&min_child_size,
&nat_child_size);
if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER)
{
min_width += min_child_size;
nat_width += nat_child_size;
}
else
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (child, FALSE);
if (aux_info && aux_info->width > 0)
{
min_width += aux_info->width;
nat_width += aux_info->width;
extra_width = -1;
}
else
{
min_width += vscrollbar_requisition.width;
nat_width += vscrollbar_requisition.width;
}
}
}
if (scrolled_window->hscrollbar_policy == GTK_POLICY_AUTOMATIC ||
scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
{
min_width = MAX (min_width, hscrollbar_requisition.width);
nat_width = MAX (nat_width, hscrollbar_requisition.width);
}
if (scrolled_window->vscrollbar_policy == GTK_POLICY_AUTOMATIC ||
scrolled_window->vscrollbar_policy == GTK_POLICY_ALWAYS)
{
if (!extra_width || scrolled_window->vscrollbar_policy == GTK_POLICY_ALWAYS)
extra_width = scrollbar_spacing + vscrollbar_requisition.width;
}
min_width += border_width * 2 + MAX (0, extra_width);
nat_width += border_width * 2 + MAX (0, extra_width);
if (scrolled_window->shadow_type != GTK_SHADOW_NONE)
{
style = gtk_widget_get_style (GTK_WIDGET (widget));
min_width += 2 * style->xthickness;
nat_width += 2 * style->xthickness;
}
if (minimum_size)
*minimum_size = min_width;
if (natural_size)
*natural_size = nat_width;
}
static void
@@ -1918,7 +1856,88 @@ gtk_scrolled_window_get_height (GtkSizeRequest *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_scrolled_window_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
GtkScrolledWindow *scrolled_window;
GtkRequisition hscrollbar_requisition;
GtkRequisition vscrollbar_requisition;
GtkWidget *child;
GtkStyle *style;
gint min_height, nat_height;
gint min_child_size, nat_child_size;
gint extra_height, border_width;
gint scrollbar_spacing;
scrolled_window = GTK_SCROLLED_WINDOW (widget);
child = gtk_bin_get_child (GTK_BIN (scrolled_window));
scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
extra_height = 0;
min_height = 0;
nat_height = 0;
gtk_widget_size_request (scrolled_window->hscrollbar,
&hscrollbar_requisition);
gtk_widget_size_request (scrolled_window->vscrollbar,
&vscrollbar_requisition);
if (child && gtk_widget_get_visible (child))
{
gtk_size_request_get_height (GTK_SIZE_REQUEST (child),
&min_child_size,
&nat_child_size);
if (scrolled_window->vscrollbar_policy == GTK_POLICY_NEVER)
{
min_height += min_child_size;
nat_height += nat_child_size;
}
else
{
GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (child, FALSE);
if (aux_info && aux_info->height > 0)
{
min_height += aux_info->height;
nat_height += aux_info->height;
extra_height = -1;
}
else
{
min_height += hscrollbar_requisition.height;
nat_height += hscrollbar_requisition.height;
}
}
}
if (scrolled_window->hscrollbar_policy == GTK_POLICY_AUTOMATIC ||
scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
{
if (!extra_height || scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
extra_height = scrollbar_spacing + hscrollbar_requisition.height;
}
if (scrolled_window->vscrollbar_policy == GTK_POLICY_AUTOMATIC ||
scrolled_window->vscrollbar_policy == GTK_POLICY_ALWAYS)
{
min_height = MAX (min_height, vscrollbar_requisition.height);
nat_height = MAX (nat_height, vscrollbar_requisition.height);
}
min_height += border_width * 2 + MAX (0, extra_height);
nat_height += border_width * 2 + MAX (0, extra_height);
if (scrolled_window->shadow_type != GTK_SHADOW_NONE)
{
style = gtk_widget_get_style (GTK_WIDGET (widget));
min_height += 2 * style->ythickness;
nat_height += 2 * style->ythickness;
}
if (minimum_size)
*minimum_size = min_height;
if (natural_size)
*natural_size = nat_height;
}
static void
@@ -1926,10 +1945,16 @@ gtk_scrolled_window_get_height_for_width (GtkSizeRequest *widget,
gint width,
gint *minimum_height,
gint *natural_height)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
{
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_height (widget, minimum_height, natural_height);
/* In the unlikely case that both scrollbars are disabled; forward the child's
* height-for-width request via the GtkBin generic method */
if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER &&
scrolled_window->vscrollbar_policy == GTK_POLICY_NEVER)
parent_size_request_iface->get_height_for_width (widget, width, minimum_height, natural_height);
else
gtk_size_request_get_height (widget, minimum_height, natural_height);
}
static void
@@ -1937,8 +1962,14 @@ gtk_scrolled_window_get_width_for_height (GtkSizeRequest *widget,
gint height,
gint *minimum_width,
gint *natural_width)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
{
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
GTK_SIZE_REQUEST_GET_IFACE (widget)->get_width (widget, minimum_width, natural_width);
/* In the unlikely case that both scrollbars are disabled; forward the child's
* width-for-height request via the GtkBin generic method */
if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER &&
scrolled_window->vscrollbar_policy == GTK_POLICY_NEVER)
parent_size_request_iface->get_width_for_height (widget, height, minimum_width, natural_width);
else
gtk_size_request_get_width (widget, minimum_width, natural_width);
}

View File

@@ -39,6 +39,7 @@
#include "gtkdnd.h"
#include "x11/gdkx.h"
#include <X11/Xatom.h>
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
@@ -123,6 +124,63 @@ _gtk_socket_windowing_size_request (GtkSocket *socket)
gdk_error_trap_pop ();
}
void
_gtk_socket_windowing_get_natural_size (GtkSocket *socket)
{
GtkSocketPrivate *priv;
GdkDisplay *display;
Atom property, type;
int format, status;
unsigned long nitems, bytes_after;
unsigned char *data;
gint32 *data_long;
priv = _gtk_socket_get_private (socket);
priv->natural_width = 1;
priv->natural_height = 1;
if (gtk_widget_get_mapped (GTK_WIDGET (socket)))
{
display = gdk_drawable_get_display (socket->plug_window);
property = gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE");
gdk_error_trap_push ();
status = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
GDK_WINDOW_XWINDOW (socket->plug_window),
property, 0, 2, False, XA_CARDINAL,
&type, &format, &nitems, &bytes_after,
&data);
gdk_error_trap_pop ();
priv->have_natural_size = TRUE;
if (Success != status || !type)
return;
if (type != XA_CARDINAL)
{
g_warning ("_GTK_NATURAL_SIZE property has wrong type: %d\n", (int)type);
return;
}
if (nitems < 2)
{
g_warning ("_GTK_NATURAL_SIZE too short\n");
XFree (data);
return;
}
data_long = (gint32*) data;
priv->natural_width = MAX (1, data_long[0]);
priv->natural_height = MAX (1, data_long[1]);
XFree (data);
}
}
void
_gtk_socket_windowing_send_key_event (GtkSocket *socket,
GdkEvent *gdk_event,
@@ -605,6 +663,10 @@ _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
}
return_val = GDK_FILTER_REMOVE;
}
else if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE"))
{
_gtk_socket_windowing_get_natural_size (socket);
}
}
break;
case ReparentNotify:

View File

@@ -37,6 +37,7 @@
#include "gtksocket.h"
#include "gtksocketprivate.h"
#include "gtkdnd.h"
#include "gtksizerequest.h"
#include "gtkintl.h"
@@ -137,6 +138,13 @@ static void gtk_socket_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
static void gtk_socket_size_request_init (GtkSizeRequestIface *iface);
static void gtk_socket_get_width (GtkSizeRequest *widget,
gint *minimum_size,
gint *natural_size);
static void gtk_socket_get_height (GtkSizeRequest *widget,
gint *minimum_size,
gint *natural_size);
/* Local data */
@@ -168,7 +176,10 @@ _gtk_socket_get_private (GtkSocket *socket)
return G_TYPE_INSTANCE_GET_PRIVATE (socket, GTK_TYPE_SOCKET, GtkSocketPrivate);
}
G_DEFINE_TYPE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER)
G_DEFINE_TYPE_WITH_CODE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_SIZE_REQUEST,
gtk_socket_size_request_init))
static void
gtk_socket_finalize (GObject *object)
@@ -255,6 +266,8 @@ gtk_socket_class_init (GtkSocketClass *class)
static void
gtk_socket_init (GtkSocket *socket)
{
GtkSocketPrivate *priv;
socket->request_width = 0;
socket->request_height = 0;
socket->current_width = 0;
@@ -269,6 +282,9 @@ gtk_socket_init (GtkSocket *socket)
socket->accel_group = gtk_accel_group_new ();
g_object_set_data (G_OBJECT (socket->accel_group), I_("gtk-socket"), socket);
priv = _gtk_socket_get_private (socket);
priv->have_natural_size = FALSE;
}
/**
@@ -1057,3 +1073,81 @@ _gtk_socket_advance_toplevel_focus (GtkSocket *socket,
return;
}
}
static void
gtk_socket_size_request_init (GtkSizeRequestIface *iface)
{
iface->get_width = gtk_socket_get_width;
iface->get_height = gtk_socket_get_height;
}
static void
gtk_socket_get_size (GtkSizeRequest *widget,
GtkOrientation orientation,
gint *minimum_size,
gint *natural_size)
{
GtkSocket *socket = GTK_SOCKET (widget);
GtkSocketPrivate *priv;
if (socket->plug_widget)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_size_request_get_width (GTK_SIZE_REQUEST (socket->plug_widget),
minimum_size, natural_size);
else
gtk_size_request_get_height (GTK_SIZE_REQUEST (socket->plug_widget),
minimum_size, natural_size);
}
else
{
priv = _gtk_socket_get_private (socket);
if (socket->is_mapped && !priv->have_natural_size && socket->plug_window)
{
_gtk_socket_windowing_size_request (socket);
_gtk_socket_windowing_get_natural_size (socket);
}
if (socket->is_mapped && priv->have_natural_size)
{
if (minimum_size)
{
*minimum_size =
(orientation == GTK_ORIENTATION_HORIZONTAL) ?
MAX (socket->request_width, 1) : MAX (socket->request_height, 1);
}
if (natural_size)
{
*natural_size =
(orientation == GTK_ORIENTATION_HORIZONTAL) ?
MAX (priv->natural_width, 1) : MAX (priv->natural_height, 1);
}
}
else
{
if (minimum_size)
*minimum_size = 1;
if (natural_size)
*natural_size = 1;
}
}
}
static void
gtk_socket_get_width (GtkSizeRequest *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_socket_get_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
}
static void
gtk_socket_get_height (GtkSizeRequest *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_socket_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
}

View File

@@ -31,6 +31,9 @@ typedef struct _GtkSocketPrivate GtkSocketPrivate;
struct _GtkSocketPrivate
{
gint resize_count;
gint natural_width;
gint natural_height;
gboolean have_natural_size;
};
/* In gtksocket.c: */
@@ -83,6 +86,7 @@ void _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket);
*/
void _gtk_socket_windowing_size_request (GtkSocket *socket);
void _gtk_socket_windowing_get_natural_size (GtkSocket *socket);
/*
* _gtk_socket_windowing_send_key_event:
*

View File

@@ -77,6 +77,8 @@ enum
*/
#define TREE_VIEW_COLUMN_DRAG_DEAD_MULTIPLIER(tree_view) (10*TREE_VIEW_HEADER_HEIGHT(tree_view))
#define GTK_TREE_VIEW_COLUMN_GET_PRIVATE(column) (G_TYPE_INSTANCE_GET_PRIVATE ((column), GTK_TYPE_TREE_VIEW_COLUMN, GtkTreeViewColumnPrivate))
typedef struct _GtkTreeViewColumnReorder GtkTreeViewColumnReorder;
struct _GtkTreeViewColumnReorder
{
@@ -99,6 +101,14 @@ struct _GtkTreeViewPrivate
gint width;
gint height;
/* Track parent scrolled window size to
* avoid feed back loops with scrollbar allocations
* and h4w cell renderers in the layout.
*/
gint prev_parent_width;
gint prev_parent_height;
gint consecutive_allocations;
/* Adjustments */
GtkAdjustment *hadjustment;
GtkAdjustment *vadjustment;
@@ -300,6 +310,16 @@ struct _GtkTreeViewPrivate
/* Whether our key press handler is to avoid sending an unhandled binding to the search entry */
guint search_entry_avoid_unhandled_binding : 1;
/* Mark dirty state for resizes that originate from changes in
* the full rendered content size, from resizes that originate
* from */
guint content_size_dirty : 1;
};
struct _GtkTreeViewColumnPrivate
{
gint natural_width;
};
#ifdef __GNUC__
@@ -459,6 +479,7 @@ void _gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column,
const GdkRectangle *expose_area,
guint flags);
void _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
gboolean recalculate_width,
gboolean install_handler);
void _gtk_tree_view_column_get_neighbor_sizes (GtkTreeViewColumn *column,
GtkCellRenderer *cell,

File diff suppressed because it is too large Load Diff

View File

@@ -26,9 +26,12 @@
#include "gtkbutton.h"
#include "gtkalignment.h"
#include "gtklabel.h"
#include "gtkcellsizerequest.h"
#include "gtksizerequest.h"
#include "gtkhbox.h"
#include "gtkmarshalers.h"
#include "gtkarrow.h"
#include "gtkdebug.h"
#include "gtkprivate.h"
#include "gtkintl.h"
@@ -70,6 +73,7 @@ struct _GtkTreeViewColumnCellInfo
gpointer func_data;
GDestroyNotify destroy;
gint requested_width;
gint natural_width;
gint real_width;
guint expand : 1;
guint pack : 1;
@@ -164,6 +168,7 @@ G_DEFINE_TYPE_WITH_CODE (GtkTreeViewColumn, gtk_tree_view_column, GTK_TYPE_OBJEC
gtk_tree_view_column_buildable_init))
static void
gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
{
@@ -344,6 +349,8 @@ gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
G_MAXINT,
-1,
GTK_PARAM_READWRITE));
g_type_class_add_private (class, sizeof (GtkTreeViewColumnPrivate));
}
static void
@@ -370,6 +377,8 @@ gtk_tree_view_column_cell_layout_init (GtkCellLayoutIface *iface)
static void
gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
{
GtkTreeViewColumnPrivate *priv;
tree_column->button = NULL;
tree_column->xalign = 0.0;
tree_column->width = 0;
@@ -395,6 +404,9 @@ gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
tree_column->fixed_width = 1;
tree_column->use_resized_width = FALSE;
tree_column->title = g_strdup ("");
priv = GTK_TREE_VIEW_COLUMN_GET_PRIVATE (tree_column);
priv->natural_width = -1;
}
static void
@@ -719,7 +731,7 @@ gtk_tree_view_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
info->attributes = g_slist_prepend (info->attributes, g_strdup (attribute));
if (tree_column->tree_view)
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE, TRUE);
}
static void
@@ -751,7 +763,7 @@ gtk_tree_view_column_cell_layout_set_cell_data_func (GtkCellLayout *cell
info->destroy = destroy;
if (column->tree_view)
_gtk_tree_view_column_cell_set_dirty (column, TRUE);
_gtk_tree_view_column_cell_set_dirty (column, TRUE, TRUE);
}
static void
@@ -814,7 +826,7 @@ gtk_tree_view_column_clear_attributes_by_info (GtkTreeViewColumn *tree_column,
info->attributes = NULL;
if (tree_column->tree_view)
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE, TRUE);
}
/* Helper functions
@@ -1732,7 +1744,7 @@ gtk_tree_view_column_set_spacing (GtkTreeViewColumn *tree_column,
tree_column->spacing = spacing;
if (tree_column->tree_view)
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE, TRUE);
}
/**
@@ -1774,7 +1786,7 @@ gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
tree_column->visible = visible;
if (tree_column->visible)
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE, TRUE);
gtk_tree_view_column_update_button (tree_column);
g_object_notify (G_OBJECT (tree_column), "visible");
@@ -2602,14 +2614,17 @@ gtk_tree_view_column_cell_set_cell_data (GtkTreeViewColumn *tree_column,
*
* Obtains the width and height needed to render the column. This is used
* primarily by the #GtkTreeView.
*
* Deprecated: 3.0: Use gtk_tree_view_column_get_natural_width() and
* gtk_tree_view_column_get_height_for_width() instead.
**/
void
gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
const GdkRectangle *cell_area,
gint *x_offset,
gint *y_offset,
gint *width,
gint *height)
gint *width,
gint *height)
{
GList *list;
gboolean first_cell = TRUE;
@@ -2699,6 +2714,7 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column,
/* If we have rtl text, we need to transform our areas */
GdkRectangle rtl_cell_area;
GdkRectangle rtl_background_area;
GtkPackType packing;
min_x = G_MAXINT;
min_y = G_MAXINT;
@@ -2776,343 +2792,188 @@ gtk_tree_view_column_cell_process_action (GtkTreeViewColumn *tree_column,
else if (extra_space > 0 && expand_cell_count > 0)
extra_space /= expand_cell_count;
/* iterate list for GTK_PACK_START cells */
for (list = tree_column->cell_list; list; list = list->next)
for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
if (info->pack == GTK_PACK_END)
continue;
if (!gtk_cell_renderer_get_visible (info->cell))
continue;
if ((info->has_focus || special_cells == 1) && cursor_row)
flags |= GTK_CELL_RENDERER_FOCUSED;
else
flags &= ~GTK_CELL_RENDERER_FOCUSED;
info->real_width = info->requested_width + (info->expand?extra_space:0);
/* We constrain ourselves to only the width available */
if (real_cell_area.x - focus_line_width + info->real_width > cell_area->x + cell_area->width)
for (list = tree_column->cell_list; list; list = list->next)
{
info->real_width = cell_area->x + cell_area->width - real_cell_area.x;
}
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
gboolean visible;
if (real_cell_area.x > cell_area->x + cell_area->width)
break;
g_object_get (info->cell, "visible", &visible, NULL);
real_cell_area.width = info->real_width;
real_cell_area.width -= 2 * focus_line_width;
if (info->pack != packing)
continue;
if (list->next)
{
real_background_area.width = info->real_width + depth;
}
else
{
/* fill the rest of background for the last cell */
real_background_area.width = background_area->x + background_area->width - real_background_area.x;
}
if (! visible)
continue;
rtl_cell_area = real_cell_area;
rtl_background_area = real_background_area;
if ((info->has_focus || special_cells == 1) && cursor_row)
flags |= GTK_CELL_RENDERER_FOCUSED;
else
flags &= ~GTK_CELL_RENDERER_FOCUSED;
/* We constrain ourselves to only the width available */
if (real_cell_area.x - focus_line_width + info->real_width > cell_area->x + cell_area->width)
{
info->real_width = cell_area->x + cell_area->width - real_cell_area.x;
}
/* Break out of the inner loop once we itterate out of our allocation
* (and possibly start the other packing direction) */
if (real_cell_area.x > cell_area->x + cell_area->width)
break;
real_cell_area.width = info->real_width;
real_cell_area.width -= 2 * focus_line_width;
if (list->next)
{
real_background_area.width = info->real_width + depth;
}
else
{
/* fill the rest of background for the last cell */
real_background_area.width = background_area->x + background_area->width - real_background_area.x;
}
rtl_cell_area = real_cell_area;
rtl_background_area = real_background_area;
if (rtl)
{
rtl_cell_area.x = cell_area->x + cell_area->width - (real_cell_area.x - cell_area->x) - real_cell_area.width;
rtl_background_area.x = background_area->x + background_area->width - (real_background_area.x - background_area->x) - real_background_area.width;
}
/* RENDER */
if (action == CELL_ACTION_RENDER)
{
gtk_cell_renderer_render (info->cell,
window,
tree_column->tree_view,
&rtl_background_area,
&rtl_cell_area,
&real_expose_area,
flags);
}
/* FOCUS */
else if (action == CELL_ACTION_FOCUS)
{
gint x_offset, y_offset, width, height;
gtk_cell_renderer_get_size (info->cell,
tree_column->tree_view,
&rtl_cell_area,
&x_offset, &y_offset,
&width, &height);
if (special_cells > 1)
if (rtl)
{
if (info->has_focus)
{
min_x = rtl_cell_area.x + x_offset;
max_x = min_x + width;
min_y = rtl_cell_area.y + y_offset;
max_y = min_y + height;
}
rtl_cell_area.x = cell_area->x + cell_area->width - (real_cell_area.x - cell_area->x) - real_cell_area.width;
rtl_background_area.x = background_area->x + background_area->width - (real_background_area.x - background_area->x) - real_background_area.width;
}
else
/* RENDER */
if (action == CELL_ACTION_RENDER)
{
if (min_x > (rtl_cell_area.x + x_offset))
min_x = rtl_cell_area.x + x_offset;
if (max_x < rtl_cell_area.x + x_offset + width)
max_x = rtl_cell_area.x + x_offset + width;
if (min_y > (rtl_cell_area.y + y_offset))
min_y = rtl_cell_area.y + y_offset;
if (max_y < rtl_cell_area.y + y_offset + height)
max_y = rtl_cell_area.y + y_offset + height;
gtk_cell_renderer_render (info->cell,
window,
tree_column->tree_view,
&rtl_background_area,
&rtl_cell_area,
&real_expose_area,
flags);
}
}
/* EVENT */
else if (action == CELL_ACTION_EVENT)
{
gboolean try_event = FALSE;
if (event)
/* FOCUS */
else if (action == CELL_ACTION_FOCUS)
{
if (special_cells == 1)
{
/* only 1 activatable cell -> whole column can activate */
if (cell_area->x <= ((GdkEventButton *)event)->x &&
cell_area->x + cell_area->width > ((GdkEventButton *)event)->x)
try_event = TRUE;
}
else if (rtl_cell_area.x <= ((GdkEventButton *)event)->x &&
rtl_cell_area.x + rtl_cell_area.width > ((GdkEventButton *)event)->x)
/* only activate cell if the user clicked on an individual
* cell
*/
try_event = TRUE;
}
else if (special_cells > 1 && info->has_focus)
try_event = TRUE;
else if (special_cells == 1)
try_event = TRUE;
if (try_event)
{
gboolean visible, mode;
g_object_get (info->cell,
"visible", &visible,
"mode", &mode,
NULL);
if (visible && mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
gint x_offset, y_offset;
GtkRequisition min_size;
gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (info->cell),
tree_column->tree_view,
&min_size, NULL);
_gtk_cell_renderer_calc_offset (info->cell, &rtl_cell_area,
gtk_widget_get_direction (tree_column->tree_view),
min_size.width, min_size.height, &x_offset, &y_offset);
if (special_cells > 1)
{
if (gtk_cell_renderer_activate (info->cell,
event,
tree_column->tree_view,
path_string,
&rtl_background_area,
&rtl_cell_area,
flags))
if (info->has_focus)
{
flags &= ~GTK_CELL_RENDERER_FOCUSED;
return TRUE;
min_x = rtl_cell_area.x + x_offset;
max_x = min_x + min_size.width;
min_y = rtl_cell_area.y + y_offset;
max_y = min_y + min_size.height;
}
}
else if (visible && mode == GTK_CELL_RENDERER_MODE_EDITABLE)
else
{
*editable_widget =
gtk_cell_renderer_start_editing (info->cell,
event,
tree_column->tree_view,
path_string,
&rtl_background_area,
&rtl_cell_area,
flags);
if (*editable_widget != NULL)
if (min_x > (rtl_cell_area.x + x_offset))
min_x = rtl_cell_area.x + x_offset;
if (max_x < rtl_cell_area.x + x_offset + min_size.width)
max_x = rtl_cell_area.x + x_offset + min_size.width;
if (min_y > (rtl_cell_area.y + y_offset))
min_y = rtl_cell_area.y + y_offset;
if (max_y < rtl_cell_area.y + y_offset + min_size.height)
max_y = rtl_cell_area.y + y_offset + min_size.height;
}
}
/* EVENT */
else if (action == CELL_ACTION_EVENT)
{
gboolean try_event = FALSE;
if (event)
{
if (special_cells == 1)
{
g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE);
info->in_editing_mode = TRUE;
gtk_tree_view_column_focus_cell (tree_column, info->cell);
/* only 1 activatable cell -> whole column can activate */
if (cell_area->x <= ((GdkEventButton *)event)->x &&
cell_area->x + cell_area->width > ((GdkEventButton *)event)->x)
try_event = TRUE;
}
else if (rtl_cell_area.x <= ((GdkEventButton *)event)->x &&
rtl_cell_area.x + rtl_cell_area.width > ((GdkEventButton *)event)->x)
/* only activate cell if the user clicked on an individual
* cell
*/
try_event = TRUE;
}
else if (special_cells > 1 && info->has_focus)
try_event = TRUE;
else if (special_cells == 1)
try_event = TRUE;
if (try_event)
{
gboolean visible, mode;
g_object_get (info->cell,
"visible", &visible,
"mode", &mode,
NULL);
if (visible && mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
{
if (gtk_cell_renderer_activate (info->cell,
event,
tree_column->tree_view,
path_string,
&rtl_background_area,
&rtl_cell_area,
flags))
{
flags &= ~GTK_CELL_RENDERER_FOCUSED;
return TRUE;
}
}
else if (visible && mode == GTK_CELL_RENDERER_MODE_EDITABLE)
{
*editable_widget =
gtk_cell_renderer_start_editing (info->cell,
event,
tree_column->tree_view,
path_string,
&rtl_background_area,
&rtl_cell_area,
flags);
flags &= ~GTK_CELL_RENDERER_FOCUSED;
return TRUE;
if (*editable_widget != NULL)
{
g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE);
info->in_editing_mode = TRUE;
gtk_tree_view_column_focus_cell (tree_column, info->cell);
flags &= ~GTK_CELL_RENDERER_FOCUSED;
return TRUE;
}
}
}
}
flags &= ~GTK_CELL_RENDERER_FOCUSED;
real_cell_area.x += (real_cell_area.width + 2 * focus_line_width + tree_column->spacing);
real_background_area.x += real_background_area.width + tree_column->spacing;
/* Only needed for first cell */
depth = 0;
}
flags &= ~GTK_CELL_RENDERER_FOCUSED;
real_cell_area.x += (real_cell_area.width + 2 * focus_line_width + tree_column->spacing);
real_background_area.x += real_background_area.width + tree_column->spacing;
/* Only needed for first cell */
depth = 0;
}
/* iterate list for PACK_END cells */
for (list = g_list_last (tree_column->cell_list); list; list = list->prev)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
if (info->pack == GTK_PACK_START)
continue;
if (!gtk_cell_renderer_get_visible(info->cell))
continue;
if ((info->has_focus || special_cells == 1) && cursor_row)
flags |= GTK_CELL_RENDERER_FOCUSED;
else
flags &= ~GTK_CELL_RENDERER_FOCUSED;
info->real_width = info->requested_width + (info->expand?extra_space:0);
/* We constrain ourselves to only the width available */
if (real_cell_area.x - focus_line_width + info->real_width > cell_area->x + cell_area->width)
{
info->real_width = cell_area->x + cell_area->width - real_cell_area.x;
}
if (real_cell_area.x > cell_area->x + cell_area->width)
break;
real_cell_area.width = info->real_width;
real_cell_area.width -= 2 * focus_line_width;
real_background_area.width = info->real_width + depth;
rtl_cell_area = real_cell_area;
rtl_background_area = real_background_area;
if (rtl)
{
rtl_cell_area.x = cell_area->x + cell_area->width - (real_cell_area.x - cell_area->x) - real_cell_area.width;
rtl_background_area.x = background_area->x + background_area->width - (real_background_area.x - background_area->x) - real_background_area.width;
}
/* RENDER */
if (action == CELL_ACTION_RENDER)
{
gtk_cell_renderer_render (info->cell,
window,
tree_column->tree_view,
&rtl_background_area,
&rtl_cell_area,
&real_expose_area,
flags);
}
/* FOCUS */
else if (action == CELL_ACTION_FOCUS)
{
gint x_offset, y_offset, width, height;
gtk_cell_renderer_get_size (info->cell,
tree_column->tree_view,
&rtl_cell_area,
&x_offset, &y_offset,
&width, &height);
if (special_cells > 1)
{
if (info->has_focus)
{
min_x = rtl_cell_area.x + x_offset;
max_x = min_x + width;
min_y = rtl_cell_area.y + y_offset;
max_y = min_y + height;
}
}
else
{
if (min_x > (rtl_cell_area.x + x_offset))
min_x = rtl_cell_area.x + x_offset;
if (max_x < rtl_cell_area.x + x_offset + width)
max_x = rtl_cell_area.x + x_offset + width;
if (min_y > (rtl_cell_area.y + y_offset))
min_y = rtl_cell_area.y + y_offset;
if (max_y < rtl_cell_area.y + y_offset + height)
max_y = rtl_cell_area.y + y_offset + height;
}
}
/* EVENT */
else if (action == CELL_ACTION_EVENT)
{
gboolean try_event = FALSE;
if (event)
{
if (special_cells == 1)
{
/* only 1 activatable cell -> whole column can activate */
if (cell_area->x <= ((GdkEventButton *)event)->x &&
cell_area->x + cell_area->width > ((GdkEventButton *)event)->x)
try_event = TRUE;
}
else if (rtl_cell_area.x <= ((GdkEventButton *)event)->x &&
rtl_cell_area.x + rtl_cell_area.width > ((GdkEventButton *)event)->x)
/* only activate cell if the user clicked on an individual
* cell
*/
try_event = TRUE;
}
else if (special_cells > 1 && info->has_focus)
try_event = TRUE;
else if (special_cells == 1)
try_event = TRUE;
if (try_event)
{
gboolean visible, mode;
g_object_get (info->cell,
"visible", &visible,
"mode", &mode,
NULL);
if (visible && mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
{
if (gtk_cell_renderer_activate (info->cell,
event,
tree_column->tree_view,
path_string,
&rtl_background_area,
&rtl_cell_area,
flags))
{
flags &= ~GTK_CELL_RENDERER_FOCUSED;
return TRUE;
}
}
else if (visible && mode == GTK_CELL_RENDERER_MODE_EDITABLE)
{
*editable_widget =
gtk_cell_renderer_start_editing (info->cell,
event,
tree_column->tree_view,
path_string,
&rtl_background_area,
&rtl_cell_area,
flags);
if (*editable_widget != NULL)
{
g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE);
info->in_editing_mode = TRUE;
gtk_tree_view_column_focus_cell (tree_column, info->cell);
flags &= ~GTK_CELL_RENDERER_FOCUSED;
return TRUE;
}
}
}
}
flags &= ~GTK_CELL_RENDERER_FOCUSED;
real_cell_area.x += (real_cell_area.width + 2 * focus_line_width + tree_column->spacing);
real_background_area.x += (real_background_area.width + tree_column->spacing);
/* Only needed for first cell */
depth = 0;
}
/* fill focus_rectangle when required */
@@ -3599,19 +3460,28 @@ gtk_tree_view_column_focus_cell (GtkTreeViewColumn *tree_column,
void
_gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
gboolean recalculate_width,
gboolean install_handler)
{
GList *list;
GtkTreeViewColumnPrivate *priv;
for (list = tree_column->cell_list; list; list = list->next)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
priv = GTK_TREE_VIEW_COLUMN_GET_PRIVATE (tree_column);
info->requested_width = 0;
}
tree_column->dirty = TRUE;
tree_column->requested_width = -1;
tree_column->width = 0;
if (recalculate_width)
{
for (list = tree_column->cell_list; list; list = list->next)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
info->requested_width = 0;
info->natural_width = 0;
}
tree_column->requested_width = -1;
priv->natural_width = -1;
}
if (tree_column->tree_view &&
gtk_widget_get_realized (tree_column->tree_view))
@@ -3624,6 +3494,7 @@ _gtk_tree_view_column_cell_set_dirty (GtkTreeViewColumn *tree_column,
}
}
void
_gtk_tree_view_column_start_editing (GtkTreeViewColumn *tree_column,
GtkCellEditable *cell_editable)
@@ -3756,7 +3627,7 @@ gtk_tree_view_column_queue_resize (GtkTreeViewColumn *tree_column)
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
if (tree_column->tree_view)
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
_gtk_tree_view_column_cell_set_dirty (tree_column, TRUE, TRUE);
}
/**
@@ -3779,3 +3650,284 @@ gtk_tree_view_column_get_tree_view (GtkTreeViewColumn *tree_column)
return tree_column->tree_view;
}
/**
* gtk_tree_view_column_get_natural_width:
* @tree_column: A #GtkTreeViewColumn
* @minimum_width: location for storing the minimum width, or %NULL
* @natural_width: location for storing the natural width, or %NULL
*
* Retreives @tree_column's minimum and natural width.
*
* Since: 3.0
*/
void
gtk_tree_view_column_get_natural_width (GtkTreeViewColumn *column,
gint *minimum_width,
gint *natural_width)
{
GList *list;
gboolean first_cell = TRUE;
gint focus_line_width;
gint min = 0, nat = 0;
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (column));
gtk_widget_style_get (column->tree_view, "focus-line-width", &focus_line_width, NULL);
for (list = column->cell_list; list; list = list->next)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
gint cell_min, cell_nat;
gboolean visible;
g_object_get (info->cell, "visible", &visible, NULL);
if (visible == FALSE)
continue;
if (first_cell == FALSE)
{
min += column->spacing;
nat += column->spacing;
}
gtk_cell_size_request_get_width (GTK_CELL_SIZE_REQUEST (info->cell),
column->tree_view, &cell_min, &cell_nat);
cell_min += focus_line_width * 2;
cell_nat += focus_line_width * 2;
/* Store 'requested_width' and 'natural_width' to cache all the requests
* for every row in the column; natural space distribution is only calculated
* once for the whole column for now. */
info->requested_width = MAX (info->requested_width, cell_min);
info->natural_width = MAX (info->natural_width, cell_nat);
/* Return the collective minimum/natural width of all
* cached sizes */
min += info->requested_width;
nat += info->natural_width;
first_cell = FALSE;
}
if (minimum_width)
*minimum_width = min;
if (natural_width)
*natural_width = nat;
}
/**
* gtk_tree_view_column_get_height_for_width:
* @tree_column: A #GtkTreeViewColumn
* @width: the width available for allocation
* @minimum_height: location for storing the minimum height, or %NULL
* @natural_height: location for storing the natural height, or %NULL
*
* Retreives @tree_column's minimum and natural height if it were rendered to
* @widget with the specified @height.
*
* Since: 3.0
*/
void
gtk_tree_view_column_get_height_for_width (GtkTreeViewColumn *column,
gint width,
gint *minimum_height,
gint *natural_height)
{
GList *list;
GArray *array;
gint size = width;
gint focus_line_width;
gint expand_cell_count = 0, i;
gboolean first_cell = TRUE;
gint min_height = 0, nat_height = 0;
GtkRequestedSize *sizes;
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (column));
gtk_widget_style_get (column->tree_view, "focus-line-width", &focus_line_width, NULL);
array = g_array_new (0, TRUE, sizeof (GtkRequestedSize));
/* First get the overall expand space and collect the cell requests */
for (list = column->cell_list; list; list = list->next)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
gboolean visible;
GtkRequestedSize requested;
g_object_get (info->cell, "visible", &visible, NULL);
if (visible == FALSE)
continue;
if (info->expand == TRUE)
expand_cell_count++;
if (first_cell == FALSE)
size -= column->spacing;
size -= focus_line_width * 2;
size -= info->requested_width;
/* Here the collective minimum/natural width for all rows
* has necessarily been cached by gtk_tree_view_column_get_natural_width().
*
* As the allocated width is based on the collective widths of all rows,
* the allocated width for a cell will be the same in each row.
*
* However the height-for-width must also be calculated for each
* row based on the aligned width in order to determine the row height.
*
* OPTIMIZE ME: It would be better to calculate the allocations of the cells once
* and caching an extra info->allocated_width in order to avoid this
* calculation for every row.
*
* Note we would use the real minimums/naturals as reported
* by the cells for each row here if we were to display
* the cells unaligned (which is more expensive to calculate
* but would allow cells to flow more naturally inside columns).
*/
requested.data = info;
requested.minimum_size = info->requested_width;
requested.natural_size = info->natural_width;
g_array_append_val (array, requested);
first_cell = FALSE;
}
/* Distribute as much of remaining 'size' as possible before sharing expand space */
sizes = (GtkRequestedSize *)array->data;
size = gtk_distribute_natural_allocation (MAX (0, size), array->len, sizes);
/* The rest gets split up evenly among expanding cells */
if (expand_cell_count)
size /= expand_cell_count;
/* Collect the minimum and natural height for the allocations of cells */
for (i = 0, list = column->cell_list; list; list = list->next)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
gint cell_min, cell_nat;
gboolean visible;
g_object_get (info->cell, "visible", &visible, NULL);
if (visible == FALSE)
continue;
gtk_cell_size_request_get_height_for_width (GTK_CELL_SIZE_REQUEST (info->cell),
column->tree_view,
sizes[i].minimum_size + (info->expand ? size : 0),
&cell_min, &cell_nat);
min_height = MAX (min_height, cell_min);
nat_height = MAX (nat_height, cell_nat);
i++;
}
g_array_free (array, TRUE);
if (minimum_height)
*minimum_height = min_height;
if (natural_height)
*natural_height = nat_height;
}
/**
* gtk_tree_view_column_allocate_width:
* @tree_column: A #GtkTreeViewColumn
* @width: the overall width of the column
*
* This allocates a good size for each cell in the column
* based on the overall minimum and natural widths of the
* cells after having been tested for each column.
*
* A width must be allocated after the request phase
* and before handling events
*
* Since: 3.0
*/
void
gtk_tree_view_column_allocate_width (GtkTreeViewColumn *column,
gint width)
{
GList *list;
GArray *array;
gint size = width;
gint focus_line_width;
gint expand_cell_count = 0, i;
gboolean first_cell = TRUE;
GtkRequestedSize *sizes;
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (column));
column->width = width;
gtk_widget_style_get (column->tree_view, "focus-line-width", &focus_line_width, NULL);
array = g_array_new (0, TRUE, sizeof (GtkRequestedSize));
/* First get the overall expand space and collect the cell requests */
for (list = column->cell_list; list; list = list->next)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
gboolean visible;
GtkRequestedSize requested;
g_object_get (info->cell, "visible", &visible, NULL);
if (visible == FALSE)
continue;
if (info->expand == TRUE)
expand_cell_count++;
if (first_cell == FALSE)
size -= column->spacing;
size -= focus_line_width * 2;
size -= info->requested_width;
requested.data = info;
requested.minimum_size = info->requested_width;
requested.natural_size = info->natural_width;
g_array_append_val (array, requested);
first_cell = FALSE;
}
/* Distribute as much of remaining 'size' as possible before sharing expand space */
sizes = (GtkRequestedSize *)array->data;
size = gtk_distribute_natural_allocation (MAX (0, size), array->len, sizes);
/* The rest gets split up evenly among expanding cells */
if (expand_cell_count > 0)
size /= expand_cell_count;
/* Allocate/assign info->real_width based in minimum/natural size + expand space */
for (i = 0, list = column->cell_list; list; list = list->next)
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
gboolean visible;
g_object_get (info->cell, "visible", &visible, NULL);
if (visible == FALSE)
continue;
info->real_width = sizes[i].minimum_size + (info->expand ? size : 0);
i++;
}
g_array_free (array, TRUE);
g_object_notify (G_OBJECT (column), "width");
}

View File

@@ -51,6 +51,7 @@ typedef enum
typedef struct _GtkTreeViewColumn GtkTreeViewColumn;
typedef struct _GtkTreeViewColumnClass GtkTreeViewColumnClass;
typedef struct _GtkTreeViewColumnPrivate GtkTreeViewColumnPrivate;
typedef void (* GtkTreeCellDataFunc) (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
@@ -225,6 +226,17 @@ void gtk_tree_view_column_cell_get_size (GtkTreeViewCol
gint *y_offset,
gint *width,
gint *height);
void gtk_tree_view_column_get_natural_width (GtkTreeViewColumn *column,
gint *minimum_width,
gint *natural_width);
void gtk_tree_view_column_get_height_for_width(GtkTreeViewColumn *column,
gint width,
gint *minimum_height,
gint *natural_height);
void gtk_tree_view_column_allocate_width (GtkTreeViewColumn *column,
gint width);
gboolean gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column);
void gtk_tree_view_column_focus_cell (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell);

View File

@@ -912,6 +912,360 @@ TestInterface interfaces[] = {
"</interface>",
NULL
},
{
"Ellipsizing Treeview",
"Demonstrates how natural size can be shared across treeview columns and renderers.",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<interface>"
" <requires lib=\"gtk+\" version=\"2.20\"/>"
" <!-- interface-naming-policy project-wide -->"
" <object class=\"GtkWindow\" id=\"window\">"
" <property name=\"default_width\">500</property>"
" <child>"
" <object class=\"GtkHPaned\" id=\"hpaned1\">"
" <property name=\"visible\">True</property>"
" <property name=\"can_focus\">True</property>"
" <property name=\"position\">400</property>"
" <child>"
" <object class=\"GtkTreeView\" id=\"treeview1\">"
" <property name=\"visible\">True</property>"
" <property name=\"can_focus\">True</property>"
" <property name=\"model\">liststore1</property>"
" <property name=\"headers_clickable\">False</property>"
" <property name=\"search_column\">0</property>"
" <child>"
" <object class=\"GtkTreeViewColumn\" id=\"treeviewcolumn1\">"
" <property name=\"sizing\">autosize</property>"
" <property name=\"title\" translatable=\"yes\">#1</property>"
" <property name=\"expand\">True</property>"
" <child>"
" <object class=\"GtkCellRendererText\" id=\"cellrenderertext1\">"
" <property name=\"ellipsize\">end</property>"
" </object>"
" <attributes>"
" <attribute name=\"text\">0</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\"GtkCellRendererPixbuf\" id=\"cellrendererpixbuf1\"/>"
" <attributes>"
" <attribute name=\"icon-name\">1</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" <child>"
" <object class=\"GtkTreeViewColumn\" id=\"treeviewcolumn2\">"
" <property name=\"sizing\">autosize</property>"
" <property name=\"title\" translatable=\"yes\">#2</property>"
" <property name=\"expand\">True</property>"
" <child>"
" <object class=\"GtkCellRendererPixbuf\" id=\"cellrendererpixbuf2\"/>"
" <attributes>"
" <attribute name=\"icon-name\">1</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\"GtkCellRendererText\" id=\"cellrenderertext2\">"
" <property name=\"ellipsize\">start</property>"
" </object>"
" <attributes>"
" <attribute name=\"text\">2</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\"GtkCellRendererText\" id=\"cellrenderertext3\">"
" <property name=\"ellipsize\">end</property>"
" </object>"
" <attributes>"
" <attribute name=\"text\">3</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
" <packing>"
" <property name=\"resize\">False</property>"
" <property name=\"shrink\">False</property>"
" </packing>"
" </child>"
" <child>"
" <object class=\"GtkLabel\" id=\"label1\">"
" <property name=\"visible\">True</property>"
" <property name=\"label\" translatable=\"yes\">static\n"
"text\n"
"here</property>"
" </object>"
" <packing>"
" <property name=\"resize\">True</property>"
" <property name=\"shrink\">False</property>"
" </packing>"
" </child>"
" </object>"
" </child>"
" </object>"
" <object class=\"GtkListStore\" id=\"liststore1\">"
" <columns>"
" <!-- column-name first-text -->"
" <column type=\"gchararray\"/>"
" <!-- column-name icon-name -->"
" <column type=\"gchararray\"/>"
" <!-- column-name second-text -->"
" <column type=\"gchararray\"/>"
" <!-- column-name third-text -->"
" <column type=\"gchararray\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\"0\" translatable=\"yes\">both columns</col>"
" <col id=\"1\" translatable=\"yes\">gtk-ok</col>"
" <col id=\"2\" translatable=\"yes\">this</col>"
" <col id=\"3\" translatable=\"yes\">this</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">contain ellipsizing cell renderers</col>"
" <col id=\"1\" translatable=\"yes\">gtk-cancel</col>"
" <col id=\"2\" translatable=\"yes\">renderer</col>"
" <col id=\"3\" translatable=\"yes\">renderer</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">to demonstrate natural</col>"
" <col id=\"1\" translatable=\"yes\">gtk-execute</col>"
" <col id=\"2\" translatable=\"yes\">is not</col>"
" <col id=\"3\" translatable=\"yes\">can</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">distribution of size</col>"
" <col id=\"1\" translatable=\"yes\">gtk-apply</col>"
" <col id=\"2\" translatable=\"yes\">wide</col>"
" <col id=\"3\" translatable=\"yes\">be</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">across columns</col>"
" <col id=\"1\" translatable=\"yes\">gtk-dialog-warning</col>"
" <col id=\"2\" translatable=\"yes\">at all</col>"
" <col id=\"3\" translatable=\"yes\">wide because of this long text.</col>"
" </row>"
" </data>"
" </object>"
"</interface>",
NULL
},
{
"Wrapping Treeview",
"Demonstrates how treeviews can recalculate row heights based on allocated widths.",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<interface>"
" <requires lib=\"gtk+\" version=\"2.20\"/>"
" <!-- interface-naming-policy project-wide -->"
" <object class=\"GtkListStore\" id=\"liststore1\">"
" <columns>"
" <!-- column-name first-text -->"
" <column type=\"gchararray\"/>"
" <!-- column-name icon-name -->"
" <column type=\"gchararray\"/>"
" <!-- column-name second-text -->"
" <column type=\"gchararray\"/>"
" <!-- column-name third-text -->"
" <column type=\"gchararray\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\"0\" translatable=\"yes\">both columns contain word-wrapping</col>"
" <col id=\"1\" translatable=\"yes\">gtk-ok</col>"
" <col id=\"2\" translatable=\"yes\">this</col>"
" <col id=\"3\" translatable=\"yes\">this</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">cell renderers</col>"
" <col id=\"1\" translatable=\"yes\">gtk-cancel</col>"
" <col id=\"2\" translatable=\"yes\">renderer</col>"
" <col id=\"3\" translatable=\"yes\">renderer</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">to demonstrate height-for-width</col>"
" <col id=\"1\" translatable=\"yes\">gtk-execute</col>"
" <col id=\"2\" translatable=\"yes\">is not</col>"
" <col id=\"3\" translatable=\"yes\">can</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">trading</col>"
" <col id=\"1\" translatable=\"yes\">gtk-apply</col>"
" <col id=\"2\" translatable=\"yes\">wide</col>"
" <col id=\"3\" translatable=\"yes\">be</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">for individual rows</col>"
" <col id=\"1\" translatable=\"yes\">gtk-dialog-warning</col>"
" <col id=\"2\" translatable=\"yes\">at all</col>"
" <col id=\"3\" translatable=\"yes\">wide because of this long text.</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">---------------</col>"
" <col id=\"1\" translatable=\"yes\"></col>"
" <col id=\"2\" translatable=\"yes\">-------</col>"
" <col id=\"3\" translatable=\"yes\">-------------</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">here we add some</col>"
" <col id=\"1\" translatable=\"yes\">gtk-bold</col>"
" <col id=\"2\" translatable=\"yes\">more</col>"
" <col id=\"3\" translatable=\"yes\">lets put some more</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">more text just</col>"
" <col id=\"1\" translatable=\"yes\">gtk-execute</col>"
" <col id=\"2\" translatable=\"yes\">and</col>"
" <col id=\"3\" translatable=\"yes\">text in all these</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">to show the scrolled window</col>"
" <col id=\"1\" translatable=\"yes\">gtk-add</col>"
" <col id=\"2\" translatable=\"yes\">more</col>"
" <col id=\"3\" translatable=\"yes\">columns</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">resizing and scrolling</col>"
" <col id=\"1\" translatable=\"yes\">gtk-remove</col>"
" <col id=\"2\" translatable=\"yes\">text</col>"
" <col id=\"3\" translatable=\"yes\">damn there are alot</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">more and more</col>"
" <col id=\"1\" translatable=\"yes\">gtk-copy</col>"
" <col id=\"2\" translatable=\"yes\">here</col>"
" <col id=\"3\" translatable=\"yes\">of columns to fill</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">text to enter</col>"
" <col id=\"1\" translatable=\"yes\">gtk-paste</col>"
" <col id=\"2\" translatable=\"yes\">more</col>"
" <col id=\"3\" translatable=\"yes\">in this liststore !</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">bla bla bla...</col>"
" <col id=\"1\" translatable=\"yes\">gtk-edit</col>"
" <col id=\"2\" translatable=\"yes\">text</col>"
" <col id=\"3\" translatable=\"yes\">ok here it comes</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">almost getting to the last column here</col>"
" <col id=\"1\" translatable=\"yes\">gtk-italic</col>"
" <col id=\"2\" translatable=\"yes\">more</col>"
" <col id=\"3\" translatable=\"yes\">its getting closer</col>"
" </row>"
" <row>"
" <col id=\"0\" translatable=\"yes\">stop its the last row !</col>"
" <col id=\"1\" translatable=\"yes\">gtk-save</col>"
" <col id=\"2\" translatable=\"yes\">text</col>"
" <col id=\"3\" translatable=\"yes\">and tada we reached the last damn row</col>"
" </row>"
" </data>"
" </object>"
" <object class=\"GtkWindow\" id=\"window\">"
" <property name=\"default_width\">700</property>"
" <property name=\"default_height\">400</property>"
" <child>"
" <object class=\"GtkHPaned\" id=\"hpaned1\">"
" <property name=\"visible\">True</property>"
" <property name=\"can_focus\">True</property>"
" <property name=\"position\">400</property>"
" <child>"
" <object class=\"GtkScrolledWindow\" id=\"scrolledwindow1\">"
" <property name=\"visible\">True</property>"
" <property name=\"can_focus\">True</property>"
" <property name=\"hscrollbar_policy\">automatic</property>"
" <property name=\"vscrollbar_policy\">automatic</property>"
" <property name=\"shadow_type\">in</property>"
" <child>"
" <object class=\"GtkTreeView\" id=\"treeview1\">"
" <property name=\"visible\">True</property>"
" <property name=\"can_focus\">True</property>"
" <property name=\"model\">liststore1</property>"
" <property name=\"headers_clickable\">False</property>"
" <property name=\"search_column\">0</property>"
" <child>"
" <object class=\"GtkTreeViewColumn\" id=\"treeviewcolumn1\">"
" <property name=\"sizing\">autosize</property>"
" <property name=\"title\" translatable=\"yes\">#1</property>"
" <property name=\"expand\">True</property>"
" <child>"
" <object class=\"GtkCellRendererText\" id=\"cellrenderertext1\">"
" <property name=\"width_chars\">10</property>"
" <property name=\"wrap_mode\">word</property>"
" <property name=\"wrap_width\">300</property>"
" </object>"
" <attributes>"
" <attribute name=\"text\">0</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\"GtkCellRendererPixbuf\" id=\"cellrendererpixbuf1\"/>"
" <attributes>"
" <attribute name=\"icon-name\">1</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" <child>"
" <object class=\"GtkTreeViewColumn\" id=\"treeviewcolumn2\">"
" <property name=\"sizing\">autosize</property>"
" <property name=\"title\" translatable=\"yes\">#2</property>"
" <property name=\"expand\">True</property>"
" <child>"
" <object class=\"GtkCellRendererPixbuf\" id=\"cellrendererpixbuf2\"/>"
" <attributes>"
" <attribute name=\"icon-name\">1</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\"GtkCellRendererText\" id=\"cellrenderertext2\">"
" <property name=\"ellipsize\">start</property>"
" </object>"
" <attributes>"
" <attribute name=\"text\">2</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\"GtkCellRendererText\" id=\"cellrenderertext3\">"
" <property name=\"width_chars\">10</property>"
" <property name=\"wrap_mode\">word</property>"
" <property name=\"wrap_width\">300</property>"
" </object>"
" <attributes>"
" <attribute name=\"text\">3</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
" </child>"
" </object>"
" <packing>"
" <property name=\"resize\">False</property>"
" <property name=\"shrink\">False</property>"
" </packing>"
" </child>"
" <child>"
" <object class=\"GtkLabel\" id=\"label1\">"
" <property name=\"visible\">True</property>"
" <property name=\"label\" translatable=\"yes\">static\n"
"text\n"
"here\n</property>"
" </object>"
" <packing>"
" <property name=\"resize\">True</property>"
" <property name=\"shrink\">False</property>"
" </packing>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>",
NULL
},
};