Hi, I did a little exercise a while ago of screenshotting some apps that seemed to be doing moderately complex layout and trying to write down what would be intuitive / no-redundant-typing sequences of commands to pack the layouts. Don't know if this will make sense to anyone else but I do think it's useful to take some real-world layouts and see how much typing they'd require and how clear the resulting code is. I didn't really finish the exercise so there's probably some mistakes in here. Some preliminary theories from the exercise: * it's right to have certain layouts require recursive (child) grids or size groups. it's easy to go down the road of trying to have too many features in order to do complex layouts all in one container. * just naming methods/props with "left and right" might be clearest, even though in RTL mode these might flip and if GtkOrientable they might become top and bottom * it seems to work well when packing by hand in code to have a "cursor" (current row/column/sibling - and possibly properties to apply to child) * per-row/column homogeneous flag doesn't seem necessary because you can just nest another table. make these table-wide? The primitives I came up with that seemed natural were: * add_row(child): adds child spanning an entire row, move cursor to next row * next_row(): move cursor to next row * add_left(), add_right(): add child on left or on right end of current row note add_right() appends on right, rather than appending on "inside" like pack_end, which is clearer for reading code * push_props() pushes align or expand or margin props to apply to all newly-added widgets * table-wide h-homogeneous and v-homogeneous flags The model I was messing with here would involve saving each row in a list, and then to layout you would go over the lists to find the max number of cells, then size the table automatically and assign widgets to cells. I guess I didn't really figure out the "span" question (children spanning columns). I made add_row() span all the columns and add_left/right span only one, and for these layouts I was looking at I guess never used any other setting. Also I never came up with how columns would work I guess. (can you add_column() or add_top() / add_bottom() ? maybe too complex) Things that may be true, I didn't think through: * can you always use a size group or nested grid rather than an arbitrary column span? * can you always use a nested grid rather than allowing arbitrary row span? If those are true then you could say each child is a whole row OR a single cell, and each child is always only one row high. That'd simplify both implementation and API quite a bit. Then you have essentially a stack of boxes where the items in the boxes are aligned on columns. To do anything more complex you use nested grids or size groups. However, at least in the sample layouts I was looking at, basically you just want hboxes but you want to line up the stuff in the hboxes instead of having each hbox all by itself. So ended up optimizing for that 90% case. One useful API might be an add_spacer(size) which would just fill a cell with a fixed spacer, so you could have some rows indented for example. Anyway from this exercise, a grid is more "stack of boxes" than it is GtkTable. Havoc On Wed, Oct 6, 2010 at 11:58 PM, Matthias Clasen <matthias clasen gmail com> wrote: > On Wed, Oct 6, 2010 at 11:36 PM, Tristan Van Berkom > <tristanvb openismus com> wrote: > >> Any takers ? thoughts ? >> > > One thing that I would like to save from this whole experiment is your > experience in wfh containers... I've started writing a grid widget > like Havoc was describing a while ago. I have put what I have on the > 'grid-widget' branch. Currently, it just uses the GtkTable size > allocation. Getting it to do hfw is the last thing needed to ensure > that has a full superset of GtkBox and GtkTable functionality.
About gedit === push_props(h-align=center) add_row(logo) add_row(name) add_row(description) add_row(copyright) add_row(url) pop_props() add_left(credits_button) add_right(close_button) Calculator === add_row(entry) add_left(degrees) add_left(gradians) add_left(radians) add_right(eng) add_right(fix) add_right(sci) add_row(inv_hyp_grid) inv_hyp_grid.add(inv) inv_hyp_grid.add(hyp) add_row(keypad_grid) keypad_grid.h-homogeneous=true keypad_grid.v-homogeneous=true push_props(h-expand=true,v-expand=true) keypad_grid.add_left(ln) keypad_grid.add_left(log) keypad_grid.add_left(log2) keypad_grid.add_left(xy) keypad_grid.add_left(x!) keypad_grid.add_right(acc) keypad_grid.next_row() keypad_grid.add_left(con) // ... etc. pop_props() Monitor Preferences === add_left(left_grid) add_right(right_grid) add_row(buttons_grid) buttons_grid.h-align=end buttons_grid.add(apply) buttons_grid.add(close) left_grid.add_row(monitors_picture) left_grid.next_row() left_grid.add_left(same_image_check) left_grid.add_right(detect_monitors) left_grid.add_row(panel_icon_frame) right_grid.add_row(laptop_label) right_grid.add_row(radio_grid) radio_grid.add(on) radio_grid.add(off) right_grid.next_row() right_grid.add_left(resolution) right_grid.add_right(resolution_menu) right_grid.next_row() right_grid.add_left(refresh) right_grid.add_right(refresh_menu) right_grid.next_row() right_grid.add_left(rotation) right_grid.add_right(rotation_menu)
Attachment:
About gedit.png
Description: PNG image
Attachment:
Calculator.png
Description: PNG image
Attachment:
Monitor Preferences.png
Description: PNG image