changeset 1080:27e9a063fbb5

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 28 Jun 2011 05:34:14 +0000
parents 5d3acda4acd4
children f9232a52367a
files gtk/dw.c gtk3/dw.c
diffstat 2 files changed, 388 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- 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);
    }
 }
 
--- 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);
    }
 }