# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1309239254 0 # Node ID 27e9a063fbb5c0f509d44b8da3feb324d7ca72c4 # Parent 5d3acda4acd4a09b9710060292d17637a1e217e4 Committing initial version of dw_box_pack_at_index() for GTK2 and GTK3... This doesn't work yet in most cases (unless packing at the ends) due to how the table resizes... Fixes coming soon but I didn't want to break building in the meantime. diff -r 5d3acda4acd4 -r 27e9a063fbb5 gtk/dw.c --- a/gtk/dw.c Tue Jun 28 04:50:51 2011 +0000 +++ b/gtk/dw.c Tue Jun 28 05:34:14 2011 +0000 @@ -9127,6 +9127,189 @@ #define DW_EXPAND (GTK_EXPAND | GTK_SHRINK | GTK_FILL) /* + * Pack windows (widgets) into a box at an arbitrary location. + * Parameters: + * box: Window handle of the box to be packed into. + * item: Window handle of the item to be back. + * index: 0 based index of packed items. + * width: Width in pixels of the item or -1 to be self determined. + * height: Height in pixels of the item or -1 to be self determined. + * hsize: TRUE if the window (widget) should expand horizontally to fill space given. + * vsize: TRUE if the window (widget) should expand vertically to fill space given. + * pad: Number of pixels of padding around the item. + */ +void dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad) +{ + int warn = FALSE, _locked_by_me = FALSE; + GtkWidget *tmp, *tmpitem, *image = NULL; + char *funcname = "dw_box_pack_at_index()"; + + if(!box) + return; + + /* + * If you try and pack an item into itself VERY bad things can happen; like at least an + * infinite loop on GTK! Lets be safe! + */ + if(box == item) + { + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); + return; + } + + DW_MUTEX_LOCK; + + if((tmp = g_object_get_data(G_OBJECT(box), "_dw_boxhandle"))) + box = tmp; + + if(!item) + { + item = gtk_label_new(""); + gtk_widget_show_all(item); + } + else if((image = g_object_get_data(G_OBJECT(item), "_dw_bitmap"))) + { + GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); + + if(pixbuf) + { + int pwidth = gdk_pixbuf_get_width(pixbuf); + int pheight = gdk_pixbuf_get_height(pixbuf); + + if(pwidth > width || pheight > height) + { + pixbuf = gdk_pixbuf_scale_simple(pixbuf, pwidth > width ? width : pwidth, pheight > height ? height : pheight, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); + } + } + } + + tmpitem = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_boxhandle"); + + if(GTK_IS_TABLE(box)) + { + int boxcount = (int)g_object_get_data(G_OBJECT(box), "_dw_boxcount"); + int boxtype = (int)g_object_get_data(G_OBJECT(box), "_dw_boxtype"); + int x, y; + + /* If the item being packed is a box, then we use it's padding + * instead of the padding specified on the pack line, this is + * due to a bug in the OS/2 and Win32 renderer and a limitation + * of the GtkTable class. + */ + if(GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) + { + GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); + + /* NOTE: I left in the ability to pack boxes with a size, + * this eliminates that by forcing the size to 0. + */ + height = width = 0; + + if(eventbox) + { + int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); + gtk_container_add(GTK_CONTAINER(eventbox), item); + gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); + item = eventbox; + } + } + else + { + /* Only show warning if item is not a box */ + warn = TRUE; + } + + /* Do some sanity bounds checking */ + if(index < 0) + index = 0; + if(index > boxcount) + index = boxcount; + + if(boxtype == DW_VERT) + { + x = 0; + y = index; + gtk_table_resize(GTK_TABLE(box), boxcount + 1, 1); + } + else + { + x = index; + y = 0; + gtk_table_resize(GTK_TABLE(box), 1, boxcount + 1); + } + + gtk_table_attach(GTK_TABLE(box), item, x, x + 1, y, y + 1, hsize ? DW_EXPAND : 0, vsize ? DW_EXPAND : 0, pad, pad); + g_object_set_data(G_OBJECT(box), "_dw_boxcount", GINT_TO_POINTER(boxcount + 1)); + gtk_widget_set_usize(item, width, height); + if(GTK_IS_RADIO_BUTTON(item)) + { + GSList *group; + GtkWidget *groupstart = (GtkWidget *)g_object_get_data(G_OBJECT(box), "_dw_group"); + + if(groupstart) + { + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(groupstart)); + gtk_radio_button_set_group(GTK_RADIO_BUTTON(item), group); + } + else + g_object_set_data(G_OBJECT(box), "_dw_group", (gpointer)item); + } + } + else + { + GtkWidget *vbox = g_object_get_data(G_OBJECT(box), "_dw_vbox"); + + if(!vbox) + { + vbox = gtk_vbox_new(FALSE, 0); + g_object_set_data(G_OBJECT(box), "_dw_vbox", vbox); + gtk_container_add(GTK_CONTAINER(box), vbox); + gtk_widget_show(vbox); + } + + gtk_container_set_border_width(GTK_CONTAINER(box), pad); + + if(GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) + { + GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); + + /* NOTE: I left in the ability to pack boxes with a size, + * this eliminates that by forcing the size to 0. + */ + height = width = 0; + + if(eventbox) + { + int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); + gtk_container_add(GTK_CONTAINER(eventbox), item); + gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); + item = eventbox; + } + } + else + { + /* Only show warning if item is not a box */ + warn = TRUE; + } + + gtk_box_pack_end(GTK_BOX(vbox), item, TRUE, TRUE, 0); + + gtk_widget_set_usize(item, width, height); + g_object_set_data(G_OBJECT(box), "_dw_user", vbox); + } + DW_MUTEX_UNLOCK; + + if(warn) + { + if ( width == 0 && hsize == FALSE ) + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); + if ( height == 0 && vsize == FALSE ) + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); + } +} + +/* * Pack windows (widgets) into a box from the end (or bottom). * Parameters: * box: Window handle of the box to be packed into. @@ -9141,6 +9324,7 @@ { int warn = FALSE, _locked_by_me = FALSE; GtkWidget *tmp, *tmpitem; + char *funcname = "dw_box_pack_end()"; if(!box) return; @@ -9151,7 +9335,7 @@ */ if(box == item) { - dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); return; } @@ -9270,9 +9454,9 @@ if(warn) { if ( width == 0 && hsize == FALSE ) - dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); if ( height == 0 && vsize == FALSE ) - dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); } } @@ -10610,6 +10794,7 @@ { int warn = FALSE, _locked_by_me = FALSE; GtkWidget *tmp, *tmpitem; + char *funcname = "dw_box_pack_start()"; if ( !box ) return; @@ -10620,7 +10805,7 @@ */ if ( box == item ) { - dw_messagebox( "dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!" ); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!" ); return; } @@ -10750,9 +10935,9 @@ if (warn) { if ( width == 0 && hsize == FALSE ) - dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); if ( height == 0 && vsize == FALSE ) - dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); } } diff -r 5d3acda4acd4 -r 27e9a063fbb5 gtk3/dw.c --- a/gtk3/dw.c Tue Jun 28 04:50:51 2011 +0000 +++ b/gtk3/dw.c Tue Jun 28 05:34:14 2011 +0000 @@ -8011,6 +8011,195 @@ #define DW_EXPAND (GTK_EXPAND | GTK_SHRINK | GTK_FILL) /* + * Pack windows (widgets) into a box at an arbitrary location. + * Parameters: + * box: Window handle of the box to be packed into. + * item: Window handle of the item to be back. + * index: 0 based index of packed items. + * width: Width in pixels of the item or -1 to be self determined. + * height: Height in pixels of the item or -1 to be self determined. + * hsize: TRUE if the window (widget) should expand horizontally to fill space given. + * vsize: TRUE if the window (widget) should expand vertically to fill space given. + * pad: Number of pixels of padding around the item. + */ +void dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad) +{ + int warn = FALSE, _locked_by_me = FALSE; + GtkWidget *tmp, *tmpitem, *image = NULL; + char *funcname = "dw_box_pack_at_index()"; + + if(!box) + return; + + /* + * If you try and pack an item into itself VERY bad things can happen; like at least an + * infinite loop on GTK! Lets be safe! + */ + if(box == item) + { + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); + return; + } + + DW_MUTEX_LOCK; + + if((tmp = g_object_get_data(G_OBJECT(box), "_dw_boxhandle"))) + box = tmp; + + if(!item) + { + item = gtk_label_new(""); + gtk_widget_show_all(item); + } + else if((image = g_object_get_data(G_OBJECT(item), "_dw_bitmap"))) + { + GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); + + if(pixbuf) + { + int pwidth = gdk_pixbuf_get_width(pixbuf); + int pheight = gdk_pixbuf_get_height(pixbuf); + + if(pwidth > width || pheight > height) + { + pixbuf = gdk_pixbuf_scale_simple(pixbuf, pwidth > width ? width : pwidth, pheight > height ? height : pheight, GDK_INTERP_BILINEAR); + gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); + } + } + } + + tmpitem = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_boxhandle"); + + if(GTK_IS_TABLE(box)) + { + int boxcount = (int)g_object_get_data(G_OBJECT(box), "_dw_boxcount"); + int boxtype = (int)g_object_get_data(G_OBJECT(box), "_dw_boxtype"); + int x, y; + + /* If the item being packed is a box, then we use it's padding + * instead of the padding specified on the pack line, this is + * due to a bug in the OS/2 and Win32 renderer and a limitation + * of the GtkTable class. + */ + if(GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) + { + GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); + + /* NOTE: I left in the ability to pack boxes with a size, + * this eliminates that by forcing the size to 0. + */ + height = width = 0; + + if(eventbox) + { + int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); + gtk_container_add(GTK_CONTAINER(eventbox), item); + gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); + item = eventbox; + } + } + else + { + /* Only show warning if item is not a box */ + warn = TRUE; + } + + /* Do some sanity bounds checking */ + if(index < 0) + index = 0; + if(index > boxcount) + index = boxcount; + + if(boxtype == DW_VERT) + { + x = 0; + y = index; + gtk_table_resize(GTK_TABLE(box), boxcount + 1, 1); + } + else + { + x = index; + y = 0; + gtk_table_resize(GTK_TABLE(box), 1, boxcount + 1); + } + + gtk_table_attach(GTK_TABLE(box), item, x, x + 1, y, y + 1, hsize ? DW_EXPAND : 0, vsize ? DW_EXPAND : 0, pad, pad); + g_object_set_data(G_OBJECT(box), "_dw_boxcount", GINT_TO_POINTER(boxcount + 1)); + if(GTK_IS_SCROLLED_WINDOW(item)) + { + gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(item), width); + gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(item), height); + } + else + gtk_widget_set_size_request(item, width, height); + if(GTK_IS_RADIO_BUTTON(item)) + { + GSList *group; + GtkWidget *groupstart = (GtkWidget *)g_object_get_data(G_OBJECT(box), "_dw_group"); + + if(groupstart) + { + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(groupstart)); + gtk_radio_button_set_group(GTK_RADIO_BUTTON(item), group); + } + else + g_object_set_data(G_OBJECT(box), "_dw_group", (gpointer)item); + } + } + else + { + GtkWidget *vbox = g_object_get_data(G_OBJECT(box), "_dw_vbox"); + + if(!vbox) + { + vbox = gtk_vbox_new(FALSE, 0); + g_object_set_data(G_OBJECT(box), "_dw_vbox", vbox); + gtk_container_add(GTK_CONTAINER(box), vbox); + gtk_widget_show(vbox); + } + + gtk_container_set_border_width(GTK_CONTAINER(box), pad); + + if(GTK_IS_TABLE(item) || (tmpitem && GTK_IS_TABLE(tmpitem))) + { + GtkWidget *eventbox = (GtkWidget *)g_object_get_data(G_OBJECT(item), "_dw_eventbox"); + + /* NOTE: I left in the ability to pack boxes with a size, + * this eliminates that by forcing the size to 0. + */ + height = width = 0; + + if(eventbox) + { + int boxpad = (int)g_object_get_data(G_OBJECT(item), "_dw_boxpad"); + gtk_container_add(GTK_CONTAINER(eventbox), item); + gtk_container_set_border_width(GTK_CONTAINER(eventbox), boxpad); + item = eventbox; + } + } + else + { + /* Only show warning if item is not a box */ + warn = TRUE; + } + + gtk_box_pack_end(GTK_BOX(vbox), item, TRUE, TRUE, 0); + + gtk_widget_set_size_request(item, width, height); + g_object_set_data(G_OBJECT(box), "_dw_user", vbox); + } + DW_MUTEX_UNLOCK; + + if(warn) + { + if ( width == 0 && hsize == FALSE ) + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); + if ( height == 0 && vsize == FALSE ) + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); + } +} + +/* * Pack windows (widgets) into a box from the end (or bottom). * Parameters: * box: Window handle of the box to be packed into. @@ -8025,6 +8214,7 @@ { int warn = FALSE, _locked_by_me = FALSE; GtkWidget *tmp, *tmpitem, *image = NULL; + char *funcname = "dw_box_pack_end()"; if(!box) return; @@ -8035,7 +8225,7 @@ */ if(box == item) { - dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!"); return; } @@ -8176,9 +8366,9 @@ if(warn) { if ( width == 0 && hsize == FALSE ) - dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); if ( height == 0 && vsize == FALSE ) - dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); } } @@ -9410,6 +9600,7 @@ { int warn = FALSE, _locked_by_me = FALSE; GtkWidget *tmp, *tmpitem, *image = NULL; + char *funcname = "dw_box_pack_start()"; if ( !box ) return; @@ -9420,7 +9611,7 @@ */ if ( box == item ) { - dw_messagebox( "dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!" ); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!" ); return; } @@ -9572,9 +9763,9 @@ if (warn) { if ( width == 0 && hsize == FALSE ) - dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item); if ( height == 0 && vsize == FALSE ) - dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); + dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item); } }