A "better" way of resizing GtkTreeViewColumns... but how do I do it?
I'm trying to create GtkTreeViewColumn resizing functionality like how it is in Thunderbird. Key word here is "trying". So far I haven't succeeded.
The easiest way to understand how this resizing works is to fire up Thunderbird and play with resizing the columns yourself, but basically the way it works in Thunderbird is if you drag, say, column #1 to the right, this increases the width of column #1, at the same time decreasing the width of column #2 by the same amount. This happens until column #2 reaches its minimum width (for example, 0 pixels). At this point, continuing to drag column #1 to the right still increases the width of column #1, but since column #2 cannot be shrunken any further, then column #3 is shrunken until it reaches its minimum width. This continues until all of the columns to the right of column #1 are at their absolute minimum widths; at this point, column #1 can't have its width increased anymore, so continuing to drag the column to the right does nothing.
While the mouse button is still held down, if you were to start dragging column #1 to the left again (to shrink it), what would happen is what happened above, except in reverse order. As column #1 shrinks, the last column in the tree view grows until reaching its width at the time the original drag (when the mouse was first pressed down to start the drag) first started. At this point, the second to last column grows until reaching its width at the time of the original drag... and so on.
Then of course, when column #1 reaches its minimum width, column #0 shrinks until it reaches its minimum width. Since column #0 is the first column, then continuing to drag column #1 to the left won't shrink it anymore; in fact, nothing will happen.
One of the major benefits to handling dragging like this is: the columns will never be resized "out of bounds" and cause the GtkTreeView to grow in width or, if the GtkTreeView containing the GtkTreeViewColumns is packed into a scrolled window, cause horizontal scrollbars to appear. Having these scrollbars appear, or the tree view grow in width (and thus increase the width of the window) is super annoying for the user and makes things look a lot less clean. Which is, I assume, why Thunderbird handles it this way, as do other applications.
So, anyway, my problem is that I just can't figure out how to do this in GTK+. I'm wondering if it's even possible? If it is... how would it be done? I'm clueless here.
As far as I know, the only signal you can connect to to know if a GtkTreeViewColumn has been resized is the notify::width signal. Problem is, you can't return TRUE or FALSE from the signal handler function to tell GTK+ not to allow the resize to go through. It's just a notification signal. So that prevents me from, for example, detecting that all columns to the right of the one being dragged have reached their minimum widths and then telling GTK+ to stop the column from having its width increased anymore.
Another problem: if you call gtk_tree_view_column_set_fixed_width()
-- what I am doing is calling gtk_tree_view_column_set_resizable(column, TRUE)
and then calling gtk_tree_view_column_set_sizing(column, GTK_TREE_开发者_开发问答VIEW_COLUMN_FIXED)
when creating the columns, by the way -- within the notify::width
signal, it creates an infinite loop, which I don't know how to prevent, either.
Again, any help would be much appreciated.
The infinite loop can be broken by temporarily blocking signals, like this:
g_signal_handler_block(...);
/* update width */
g_isgnal_handler_unblock(...)
I got the same problem and my approach was to use 2 functions for the resize signal:
- The first one checked for connected/disconnected of handler; if not connected connect it and save the handler ID.
- The second just resized all columns proportionally and then disconnect the signal with the saved handler ID.
精彩评论