GNOME Bugzilla – Bug 96374
Change GtkFrame to comply with HIG
Last modified: 2004-12-22 21:47:04 UTC
Apparently the new hig preferences layout (http://developer.gnome.org/projects/gup/hig/1.0/layout.html#layout-dialogs) is hard to implement in both gtk and glade, and requires the use of bad hacks (ie using empty text boxes) currently. It would be nice if gtk provided a widget so that this type of layout could be used in a consistent and easy to maintain fashion among applications.
I think we need an actual design proposal here; I'm not sure exactly what you are looking for? A box with out-dented headers between elements?
I do not know what the original submitter had in mind, but I would like to make the following design proposal: a set of widgets that would simplify the creation of HIG compliant alerts and dialogs. These widgets would allow the application programmer to create such dialogs and alerts without obfuscating his or her code with the various layout "tricks" outlined in the HIG -- separating content from presentation to some degree. I created a set of such widgets for gLabels (http://snaught.com/glabels/) and would like to offer these as a possible starting point -- I will also be attaching the relevant files. Here is a brief outline of these widgets: 1) A HIG inspired alert (GtkHigAlert): this is widget would be very similar to a GtkMessageDialog, except you provide it separate primary and secondary text strings. GtkWidget *gtk_hig_alert_new (GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const gchar *primary_text, const gchar *secondary_text); 2) A HIG inspired Dialog (GtkHigDialog): this widget would be the foundation of all other HIG dialogs. This dialog has the default HIG border and has an internal VBOX with appropriate default spacing. GtkWidget *gtk_hig_dialog_new (void); GtkWidget *gtk_hig_dialog_new_with_buttons (const gchar *title, GtkWindow *parent, GtkDialogFlags flags, const gchar *first_button_text, ...); void gtk_hig_dialog_add_widget (GtkHigDialog *dialog, GtkWidget *widget); 3) A HIG inspired Category widget (GtkHigCategory): this widget implements a category container, with the bold section heading and indented widget area which the HIG suggests using instead of frames. It is very clean looking but extremely tedious to create from scratch. GtkWidget *gtk_hig_category_new (const gchar *header); void gtk_hig_category_add_widget (GtkHigCategory *cat, GtkWidget *widget); 4) HIG versions of VBOX and HBOX (GtkHigVBox and GtkHigHBox): These are simple dervations of their counterparts with proper HIG default. GtkWidget *gtk_hig_vbox_new (void); GtkWidget *gtk_hig_hbox_new (void); void gtk_hig_vbox_add_widget (GtkHigHBox *hig_hbox, GtkWidget *widget); void gtk_hig_hbox_add_widget (GtkHigHBox *hig_hbox, GtkWidget *widget);
Created attachment 11924 [details] hig.h from gLabels
Created attachment 11925 [details] hig.c from gLabels
A couple comments: 1) I think the right thing is to change the default settings of existing widgets, or add convenience constructors such as gtk_message_dialog_new_alert(), rather than creating new classes, for the most part anyway. 2) I'd file a separate bug report for each API addition, rather than putting them all here; they need to be evaluated and tracked independently. 3) I think it's appropriate to add this stuff to GTK, the current situation where GTK is out of sync with HIG is silly. (Although I also think we'd ideally get these things in a GTK release *before* recommending them in the HIG, because with the current situation people such as yourself are hardcoding the HIG recommendations all over the place and other people are not bothering to implement the hard recommendations and the result is UI inconsistency and a big mess.) Anyway, we should not hijack this bug for this purpose, separate bugs should be filed for each problem to be solved (category labels, dialogs, etc.) btw one way to approach the category labels might be a special GtkFrame mode to be set programmatically, or perhaps even via style properties in the theme.
From: http://mail.gnome.org/archives/hig/2002-October/msg00019.html Once you have the toplevel of the indented widgets (typically a vbox) connect to the "size-allocate" signal: g_signal_connect (indented_toplevel, "size_allocate", G_CALLBACK (adjust_allocation), NULL); The adjust_allocation callback is then: static void adjust_allocation (GtkWidget *widget, GtkAllocation *allocation) { allocation->x += INDENTATION_IN_PIXELS; allocation->width -= INDENTATION_IN_PIXELS; GTK_WIDGET_GET_CLASS (widget)->size_allocate (widget, allocation); } I think an INDENTATION_IN_PIXELS value of 24 achieves the desired effect.
(Correction to my last comment: INDENTATION_IN_PIXELS at 18 is closer to the effect of the HIG's suggested method. The desired indentation is 12px.) This is silly. I was playing with GtkFrame to see about making a patch, and it's pretty damn close already. The HIG however needs a stern review with an eye to consistency and code. Depending on what section you read you'll be using a spacing of 6, 12, or 18px. With that in mind, here's one way to do it using GtkFrame. 1) Create a GtkFrame with the group label. 2) Set the GtkFrame's shadow type to GTK_SHADOW_NONE. 2) Make the label's weight bold. 3) Place a GtkContainer widget (HBox, VBox, etc.) in the GtkFrame. 4) Set that widget's border width to 12. That is almost exactly what the HIG calls for. There are three variant distances, two of which are interdependent: 1) The distance from the window edge to the group label will be about 6px greater. 2) The distance from the left edge of the group label to the left edge of the child widgets will be about 6px greater. 3) The distance from the bottom of the group label to the top of the child widgets will be about 12px; but the HIG in different places seems to call for 6, 12, or 18px here. 1 and 2 are interdependent. They are caused by the indentation of a frame label from the edge of the frame. How to proceed? Assuming the HIG is made consistent and that GtkFrame's defaults are to be altered, then GtkFrame's: 1) shadow type will default to GTK_SHADOW_NONE, and 2) its label will not be indented, and 3) its label's default weight attribute will be bold. Changing the default shadow type will annoy those not conforming to the HIG. As we hope those conforming number greater than those not and as the shadow type change is easy, changing the default shadow type should not be a problem. Because GtkFrame's label widget is relatively aligned, it would be very difficult (if not impossible) to restore exactly the few pixels indentation which it now has were that changed. Options here include: 1) To hell with the non-conformists. I don't think this is a good option, but I had to include it. 2) Change the way the label widget is aligned. This does not seem unreasonable to me because left, right, and center are the only alignments I imagine anyone will want. An enum (LEFT, CENTER, RIGHT) with a pixel offset seems reasonable to me if this option is chosen. 3) Change the HIG. This is the easiest for the code. Given how confusing the layout section is now, this may be the elimination of this problem. Setting a default text attribute for a label without a subclass is anathema. I think we need some way to set such attributes thematically - at least Windows and OS/2 allowed this. I have before suggested semantic types like GtkCaption, GtkHeader. This might also be done with something like: GtkWidget *gtk_label_new_with_context (const gchar *label, GtkContextType context); where GtkContextType might include: GTK_CONTEXT_CAPTION, GTK_CONTEXT_HEADER, GTK_CONTEXT_BUTTON, GTK_CONTEXT_MENU, GTK_CONTEXT_TOOLTIP, GTK_CONTEXT_LINK, GTK_CONTEXT_ALERT_PRIMARY_TEXT, GTK_CONTEXT_ALERT_SECONDARY_TEXT, etc. (See Windows or OS/2 and where they allow thematic font changes. My list may seem long, but I'm basing it on recollection of those. As we can already control text within a button, menu, or tooltip, we shouldn't need so many.) Because it makes thematic changes and i18n difficult, the HIG should not be advising use of Pango markup for such things. Rampant subclassing or use of PangoAttrList would be hard to maintain. As much as I like Pango, exposing it at the Gtk+ level for anything other than user input seems like a bad idea. The HIG must be made consistent before any Gtk+ changes are made.
Created attachment 12579 [details] Screenshot of default style, HIG-style, and proposed style.
In the attached shot: window1 is the proposed style using GtkFrame. window2 is the default style of GtkFrame. window3 is the HIG style with wacky-packy. I've left the encoded spacings the same the same in each.
I guess we need to think this one through, but certainly from the screenshots Greg's suggestion doesn't look notably worse than the currently more-convoluted HIG advice, IMHO...
I think all we need is a way to set horizontal and vertical padding within the GtkFrame, somewhat like GtkButtonBox: void gtk_frame_set_child_ipadding (GtkFrame *frame, gint ipad_x, gint ipad_y); void gtk_frame_get_child_ipadding (GtkFrame *frame, gint *ipad_x, gint *ipad_y); Owen, is that reasonable? How soon can it be included? I can write a patch for it.
A summary: 1. GtkFrame should default to GTK_SHADOW_NONE 2. GtkFrame should indent it's contents by x pixels. 3. When using GTK_SHADOW_NONE, GtkFrame's label should not be indented. ? I don't understand why 2. wouldn't be achieved best by just adding a vbox of a fixed size at the left. 3. Seems less important and slightly more difficult. We should go ahead with 1 and 2 in the meantime.
I redid all of gnome-terminal with Gregory's original steps: 1) Create a GtkFrame with the group label. 2) Set the GtkFrame's shadow type to GTK_SHADOW_NONE. 3) Make the label's weight bold. 4) Place a GtkContainer widget (HBox, VBox, etc.) in the GtkFrame. 5) Set that widget's border width to 12. Those are just fine IMO, there's nothing hard about it. The only bad part is having to use markup for the bold label, which is filed separately as a glade bug. Glade could default to the 12-pixel padding and bold frame label etc. even if gtk doesn't.
Created attachment 12820 [details] Various frame child spacings
There's a partial explanation in the image. The last two rows in each column show what could be more easily done with GtkFrame parameters for child padding. Credit to James Cape for pointing out that a single-child HBox can be used now. Both adding fixed size empty containers and using padding with non-Bin containers that have only one child seem to me to be a pain for maintanance. Because of that I've suggested the child padding parameters for GtkFrame. I think the third row looks best.
Havoc, yes it's simpler than the current bizarrre HIG implementation recommendation, but this simple change (or something very similar) still needs to be in GTK+ itself. Gregory, doesn't this solution add unnecessary space at the right as well as the left? This bug is marget for the "future" target. Why doesn't it have the "2.4" target like most of the other GTK+ HIG bugs?
Indeed it does add unnecessary space on the right. I was thinking that wouldn't matter, but indeed it does. What about this for the API? void gtk_frame_set_child_padding (GtkFrame *frame, gint pad_left, gint pad_right, gint pad_top, gint pad_bottom); void gtk_frame_get_child_padding (GtkFrame *frame, gint *pad_left, gint *pad_right, gint *pad_top, gint *pad_bottom); Perhaps those should be {hpad_start, hpad_end, vpad_start, vpad_end}, to allow for RTL changes? Maybe setting end padding shouldn't be allowed at all? E.g., void gtk_frame_set_child_padding (GtkFrame *frame, gint horizontal_padding, gint vertical_padding);
So far I don't see a need to change the API, though people would probably like to be able to customize the new layout. Wouldn't an empty, but fixed size VBox at the left work as an indent?
We have a planned solution for this: http://lists.gnome.org/archives/gtk-devel-list/2003-March/msg00164.html (Added side padding to GtkAlignment).
Bug 110365 now contains a GtkAlignment patch that should make this possible.
Re-adding bug 110365 as a depends, because it does
A new summary: 1. We have a solution for the indenting, using GtkAlignment: Bug 110365. 2. It seems unlikely that the GtkFrame defaults will change, but we can change the defauls in Glade. 3. It might be nice to have some kind of "indent the contents" property for GtkFrame so we don't have to add a GtkAlignment manually.
Do we have a volunteer to implement this now that the GtkAlignment indenting is in GTK+ HEAD?
The GTK+ 2.4 feature-set will be frozen quite soon. Now is the time.
Time is slipping away.
Murray, Owen: What exactly is needed in gtk+? Would this be a new widget? or an alternate gtk_frame_new_frameless adding an indent property to the frame? I'm not a great hacker, but i'd be willing to work on this if someone pointed me in the right direction.
From above: 3. It might be nice to have some kind of "indent the contents" property for GtkFrame so we don't have to add a GtkAlignment manually. Then you just need to set the frame title to bold, set the border to off, and you're HIG-compliant, right? I don't think it makes sense to have a do_it_like_the_hig property or style. Then, we just need to make glade use the HIG settings as default.
This is not going to happen. Owen's (reasonable) decision on the maillng list is "Personally, I don't see any GTK+ API additions that make sense here.". So I am closing this bug. I have opened glade bug 118183. I think that's how we should take this further.