Blame demos/gtk-demo/toolpalette.c

Packit 98cdb6
/* Tool Palette
Packit 98cdb6
 *
Packit 98cdb6
 * A tool palette widget shows groups of toolbar items as a grid of icons
Packit 98cdb6
 * or a list of names.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include <string.h>
Packit 98cdb6
#include <gtk/gtk.h>
Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include "demo-common.h"
Packit 98cdb6
Packit 98cdb6
static GtkWidget *window = NULL;
Packit 98cdb6
Packit 98cdb6
static void load_stock_items (GtkToolPalette *palette);
Packit 98cdb6
static void load_toggle_items (GtkToolPalette *palette);
Packit 98cdb6
static void load_special_items (GtkToolPalette *palette);
Packit 98cdb6
Packit 98cdb6
typedef struct _CanvasItem CanvasItem;
Packit 98cdb6
Packit 98cdb6
struct _CanvasItem
Packit 98cdb6
{
Packit 98cdb6
  GdkPixbuf *pixbuf;
Packit 98cdb6
  gdouble x, y;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
static CanvasItem *drop_item = NULL;
Packit 98cdb6
static GList *canvas_items = NULL;
Packit 98cdb6
Packit 98cdb6
/********************************/
Packit 98cdb6
/* ====== Canvas drawing ====== */
Packit 98cdb6
/********************************/
Packit 98cdb6
Packit 98cdb6
static CanvasItem*
Packit 98cdb6
canvas_item_new (GtkWidget     *widget,
Packit 98cdb6
                 GtkToolButton *button,
Packit 98cdb6
                 gdouble        x,
Packit 98cdb6
                 gdouble        y)
Packit 98cdb6
{
Packit 98cdb6
  CanvasItem *item = NULL;
Packit 98cdb6
  const gchar *stock_id;
Packit 98cdb6
  GdkPixbuf *pixbuf;
Packit 98cdb6
Packit 98cdb6
  stock_id = gtk_tool_button_get_stock_id (button);
Packit 98cdb6
  pixbuf = gtk_widget_render_icon (widget, stock_id, GTK_ICON_SIZE_DIALOG, NULL);
Packit 98cdb6
Packit 98cdb6
  if (pixbuf)
Packit 98cdb6
    {
Packit 98cdb6
      item = g_slice_new0 (CanvasItem);
Packit 98cdb6
      item->pixbuf = pixbuf;
Packit 98cdb6
      item->x = x;
Packit 98cdb6
      item->y = y;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return item;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
canvas_item_free (CanvasItem *item)
Packit 98cdb6
{
Packit 98cdb6
  g_object_unref (item->pixbuf);
Packit 98cdb6
  g_slice_free (CanvasItem, item);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
canvas_item_draw (const CanvasItem *item,
Packit 98cdb6
                  cairo_t          *cr,
Packit 98cdb6
                  gboolean          preview)
Packit 98cdb6
{
Packit 98cdb6
  gdouble cx = gdk_pixbuf_get_width (item->pixbuf);
Packit 98cdb6
  gdouble cy = gdk_pixbuf_get_height (item->pixbuf);
Packit 98cdb6
Packit 98cdb6
  gdk_cairo_set_source_pixbuf (cr,
Packit 98cdb6
                               item->pixbuf,
Packit 98cdb6
                               item->x - cx * 0.5,
Packit 98cdb6
                               item->y - cy * 0.5);
Packit 98cdb6
Packit 98cdb6
  if (preview)
Packit 98cdb6
    cairo_paint_with_alpha (cr, 0.6);
Packit 98cdb6
  else
Packit 98cdb6
    cairo_paint (cr);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
canvas_expose_event (GtkWidget      *widget,
Packit 98cdb6
                     GdkEventExpose *event)
Packit 98cdb6
{
Packit 98cdb6
  cairo_t *cr;
Packit 98cdb6
  GList *iter;
Packit 98cdb6
  GtkAllocation allocation;
Packit 98cdb6
Packit 98cdb6
  cr = gdk_cairo_create (gtk_widget_get_window (widget));
Packit 98cdb6
  gdk_cairo_region (cr, event->region);
Packit 98cdb6
  cairo_clip (cr);
Packit 98cdb6
Packit 98cdb6
  gtk_widget_get_allocation (widget, &allocation);
Packit 98cdb6
  cairo_set_source_rgb (cr, 1, 1, 1);
Packit 98cdb6
  cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
Packit 98cdb6
  cairo_fill (cr);
Packit 98cdb6
Packit 98cdb6
  for (iter = canvas_items; iter; iter = iter->next)
Packit 98cdb6
    canvas_item_draw (iter->data, cr, FALSE);
Packit 98cdb6
Packit 98cdb6
  if (drop_item)
Packit 98cdb6
    canvas_item_draw (drop_item, cr, TRUE);
Packit 98cdb6
Packit 98cdb6
  cairo_destroy (cr);
Packit 98cdb6
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/*****************************/
Packit 98cdb6
/* ====== Palette DnD ====== */
Packit 98cdb6
/*****************************/
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
palette_drop_item (GtkToolItem      *drag_item,
Packit 98cdb6
                   GtkToolItemGroup *drop_group,
Packit 98cdb6
                   gint              x,
Packit 98cdb6
                   gint              y)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *drag_group = gtk_widget_get_parent (GTK_WIDGET (drag_item));
Packit 98cdb6
  GtkToolItem *drop_item = gtk_tool_item_group_get_drop_item (drop_group, x, y);
Packit 98cdb6
  gint drop_position = -1;
Packit 98cdb6
Packit 98cdb6
  if (drop_item)
Packit 98cdb6
    drop_position = gtk_tool_item_group_get_item_position (GTK_TOOL_ITEM_GROUP (drop_group), drop_item);
Packit 98cdb6
Packit 98cdb6
  if (GTK_TOOL_ITEM_GROUP (drag_group) != drop_group)
Packit 98cdb6
    {
Packit 98cdb6
      gboolean homogeneous, expand, fill, new_row;
Packit 98cdb6
Packit 98cdb6
      g_object_ref (drag_item);
Packit 98cdb6
      gtk_container_child_get (GTK_CONTAINER (drag_group), GTK_WIDGET (drag_item),
Packit 98cdb6
                               "homogeneous", &homogeneous,
Packit 98cdb6
                               "expand", &expand,
Packit 98cdb6
                               "fill", &fill,
Packit 98cdb6
                               "new-row", &new_row,
Packit 98cdb6
                               NULL);
Packit 98cdb6
      gtk_container_remove (GTK_CONTAINER (drag_group), GTK_WIDGET (drag_item));
Packit 98cdb6
      gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (drop_group),
Packit 98cdb6
                                  drag_item, drop_position);
Packit 98cdb6
      gtk_container_child_set (GTK_CONTAINER (drop_group), GTK_WIDGET (drag_item),
Packit 98cdb6
                               "homogeneous", homogeneous,
Packit 98cdb6
                               "expand", expand,
Packit 98cdb6
                               "fill", fill,
Packit 98cdb6
                               "new-row", new_row,
Packit 98cdb6
                               NULL);
Packit 98cdb6
      g_object_unref (drag_item);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    gtk_tool_item_group_set_item_position (GTK_TOOL_ITEM_GROUP (drop_group),
Packit 98cdb6
                                           drag_item, drop_position);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
palette_drop_group (GtkToolPalette   *palette,
Packit 98cdb6
                    GtkToolItemGroup *drag_group,
Packit 98cdb6
                    GtkToolItemGroup *drop_group)
Packit 98cdb6
{
Packit 98cdb6
  gint drop_position = -1;
Packit 98cdb6
Packit 98cdb6
  if (drop_group)
Packit 98cdb6
    drop_position = gtk_tool_palette_get_group_position (palette, drop_group);
Packit 98cdb6
Packit 98cdb6
  gtk_tool_palette_set_group_position (palette, drag_group, drop_position);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
palette_drag_data_received (GtkWidget        *widget,
Packit 98cdb6
                            GdkDragContext   *context,
Packit 98cdb6
                            gint              x,
Packit 98cdb6
                            gint              y,
Packit 98cdb6
                            GtkSelectionData *selection,
Packit 98cdb6
                            guint             info,
Packit 98cdb6
                            guint             time,
Packit 98cdb6
                            gpointer          data)
Packit 98cdb6
{
Packit 98cdb6
  GtkToolItemGroup *drop_group = NULL;
Packit 98cdb6
  GtkWidget        *drag_palette = gtk_drag_get_source_widget (context);
Packit 98cdb6
  GtkWidget        *drag_item = NULL;
Packit 98cdb6
  GtkAllocation	    allocation;
Packit 98cdb6
Packit 98cdb6
  while (drag_palette && !GTK_IS_TOOL_PALETTE (drag_palette))
Packit 98cdb6
    drag_palette = gtk_widget_get_parent (drag_palette);
Packit 98cdb6
Packit 98cdb6
  if (drag_palette)
Packit 98cdb6
    {
Packit 98cdb6
      drag_item = gtk_tool_palette_get_drag_item (GTK_TOOL_PALETTE (drag_palette),
Packit 98cdb6
                                                  selection);
Packit 98cdb6
      drop_group = gtk_tool_palette_get_drop_group (GTK_TOOL_PALETTE (widget),
Packit 98cdb6
                                                    x, y);
Packit 98cdb6
      gtk_widget_get_allocation (GTK_WIDGET (drop_group), &allocation);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (GTK_IS_TOOL_ITEM_GROUP (drag_item))
Packit 98cdb6
    palette_drop_group (GTK_TOOL_PALETTE (drag_palette),
Packit 98cdb6
                        GTK_TOOL_ITEM_GROUP (drag_item),
Packit 98cdb6
                        drop_group);
Packit 98cdb6
  else if (GTK_IS_TOOL_ITEM (drag_item) && drop_group)
Packit 98cdb6
    palette_drop_item (GTK_TOOL_ITEM (drag_item),
Packit 98cdb6
                       drop_group,
Packit 98cdb6
                       x - allocation.x,
Packit 98cdb6
                       y - allocation.y);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/********************************/
Packit 98cdb6
/* ====== Passive Canvas ====== */
Packit 98cdb6
/********************************/
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
passive_canvas_drag_data_received (GtkWidget        *widget,
Packit 98cdb6
                                   GdkDragContext   *context,
Packit 98cdb6
                                   gint              x,
Packit 98cdb6
                                   gint              y,
Packit 98cdb6
                                   GtkSelectionData *selection,
Packit 98cdb6
                                   guint             info,
Packit 98cdb6
                                   guint             time,
Packit 98cdb6
                                   gpointer          data)
Packit 98cdb6
{
Packit 98cdb6
  /* find the tool button, which is the source of this DnD operation */
Packit 98cdb6
Packit 98cdb6
  GtkWidget *palette = gtk_drag_get_source_widget (context);
Packit 98cdb6
  CanvasItem *canvas_item = NULL;
Packit 98cdb6
  GtkWidget *tool_item = NULL;
Packit 98cdb6
Packit 98cdb6
  while (palette && !GTK_IS_TOOL_PALETTE (palette))
Packit 98cdb6
    palette = gtk_widget_get_parent (palette);
Packit 98cdb6
Packit 98cdb6
  if (palette)
Packit 98cdb6
    tool_item = gtk_tool_palette_get_drag_item (GTK_TOOL_PALETTE (palette),
Packit 98cdb6
                                                selection);
Packit 98cdb6
Packit 98cdb6
  g_assert (NULL == drop_item);
Packit 98cdb6
Packit 98cdb6
  /* append a new canvas item when a tool button was found */
Packit 98cdb6
Packit 98cdb6
  if (GTK_IS_TOOL_ITEM (tool_item))
Packit 98cdb6
    canvas_item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
Packit 98cdb6
Packit 98cdb6
  if (canvas_item)
Packit 98cdb6
    {
Packit 98cdb6
      canvas_items = g_list_append (canvas_items, canvas_item);
Packit 98cdb6
      gtk_widget_queue_draw (widget);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/************************************/
Packit 98cdb6
/* ====== Interactive Canvas ====== */
Packit 98cdb6
/************************************/
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
interactive_canvas_drag_motion (GtkWidget      *widget,
Packit 98cdb6
                                GdkDragContext *context,
Packit 98cdb6
                                gint            x,
Packit 98cdb6
                                gint            y,
Packit 98cdb6
                                guint           time,
Packit 98cdb6
                                gpointer        data)
Packit 98cdb6
{
Packit 98cdb6
  if (drop_item)
Packit 98cdb6
    {
Packit 98cdb6
      /* already have a drop indicator - just update position */
Packit 98cdb6
Packit 98cdb6
      drop_item->x = x;
Packit 98cdb6
      drop_item->y = y;
Packit 98cdb6
Packit 98cdb6
      gtk_widget_queue_draw (widget);
Packit 98cdb6
      gdk_drag_status (context, GDK_ACTION_COPY, time);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      /* request DnD data for creating a drop indicator */
Packit 98cdb6
Packit 98cdb6
      GdkAtom target = gtk_drag_dest_find_target (widget, context, NULL);
Packit 98cdb6
Packit 98cdb6
      if (!target)
Packit 98cdb6
        return FALSE;
Packit 98cdb6
Packit 98cdb6
      gtk_drag_get_data (widget, context, target, time);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
interactive_canvas_drag_data_received (GtkWidget        *widget,
Packit 98cdb6
                                       GdkDragContext   *context,
Packit 98cdb6
                                       gint              x,
Packit 98cdb6
                                       gint              y,
Packit 98cdb6
                                       GtkSelectionData *selection,
Packit 98cdb6
                                       guint             info,
Packit 98cdb6
                                       guint             time,
Packit 98cdb6
                                       gpointer          data)
Packit 98cdb6
Packit 98cdb6
{
Packit 98cdb6
  /* find the tool button which is the source of this DnD operation */
Packit 98cdb6
Packit 98cdb6
  GtkWidget *palette = gtk_drag_get_source_widget (context);
Packit 98cdb6
  GtkWidget *tool_item = NULL;
Packit 98cdb6
Packit 98cdb6
  while (palette && !GTK_IS_TOOL_PALETTE (palette))
Packit 98cdb6
    palette = gtk_widget_get_parent (palette);
Packit 98cdb6
Packit 98cdb6
  if (palette)
Packit 98cdb6
    tool_item = gtk_tool_palette_get_drag_item (GTK_TOOL_PALETTE (palette),
Packit 98cdb6
                                                selection);
Packit 98cdb6
Packit 98cdb6
  /* create a drop indicator when a tool button was found */
Packit 98cdb6
Packit 98cdb6
  g_assert (NULL == drop_item);
Packit 98cdb6
Packit 98cdb6
  if (GTK_IS_TOOL_ITEM (tool_item))
Packit 98cdb6
    {
Packit 98cdb6
      drop_item = canvas_item_new (widget, GTK_TOOL_BUTTON (tool_item), x, y);
Packit 98cdb6
      gdk_drag_status (context, GDK_ACTION_COPY, time);
Packit 98cdb6
      gtk_widget_queue_draw (widget);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
interactive_canvas_drag_drop (GtkWidget      *widget,
Packit 98cdb6
                              GdkDragContext *context,
Packit 98cdb6
                              gint            x,
Packit 98cdb6
                              gint            y,
Packit 98cdb6
                              guint           time,
Packit 98cdb6
                              gpointer        data)
Packit 98cdb6
{
Packit 98cdb6
  if (drop_item)
Packit 98cdb6
    {
Packit 98cdb6
      /* turn the drop indicator into a real canvas item */
Packit 98cdb6
Packit 98cdb6
      drop_item->x = x;
Packit 98cdb6
      drop_item->y = y;
Packit 98cdb6
Packit 98cdb6
      canvas_items = g_list_append (canvas_items, drop_item);
Packit 98cdb6
      drop_item = NULL;
Packit 98cdb6
Packit 98cdb6
      /* signal the item was accepted and redraw */
Packit 98cdb6
Packit 98cdb6
      gtk_drag_finish (context, TRUE, FALSE, time);
Packit 98cdb6
      gtk_widget_queue_draw (widget);
Packit 98cdb6
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
interactive_canvas_real_drag_leave (gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  if (drop_item)
Packit 98cdb6
    {
Packit 98cdb6
      GtkWidget *widget = GTK_WIDGET (data);
Packit 98cdb6
Packit 98cdb6
      canvas_item_free (drop_item);
Packit 98cdb6
      drop_item = NULL;
Packit 98cdb6
Packit 98cdb6
      gtk_widget_queue_draw (widget);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
interactive_canvas_drag_leave (GtkWidget      *widget,
Packit 98cdb6
                               GdkDragContext *context,
Packit 98cdb6
                               guint           time,
Packit 98cdb6
                               gpointer        data)
Packit 98cdb6
{
Packit 98cdb6
  /* defer cleanup until a potential "drag-drop" signal was received */
Packit 98cdb6
  g_idle_add (interactive_canvas_real_drag_leave, widget);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
on_combo_orientation_changed (GtkComboBox *combo_box,
Packit 98cdb6
                              gpointer     user_data)
Packit 98cdb6
{
Packit 98cdb6
  GtkToolPalette *palette = GTK_TOOL_PALETTE (user_data);
Packit 98cdb6
  GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW (gtk_widget_get_parent (GTK_WIDGET (palette)));
Packit 98cdb6
  GtkTreeModel *model = gtk_combo_box_get_model (combo_box);
Packit 98cdb6
  GtkTreeIter iter;
Packit 98cdb6
  gint val = 0;
Packit 98cdb6
Packit 98cdb6
  if (!gtk_combo_box_get_active_iter (combo_box, &iter))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  gtk_tree_model_get (model, &iter, 1, &val, -1);
Packit 98cdb6
Packit 98cdb6
  gtk_orientable_set_orientation (GTK_ORIENTABLE (palette), val);
Packit 98cdb6
Packit 98cdb6
  if (val == GTK_ORIENTATION_HORIZONTAL)
Packit 98cdb6
    gtk_scrolled_window_set_policy (sw, GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
Packit 98cdb6
  else
Packit 98cdb6
    gtk_scrolled_window_set_policy (sw, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
on_combo_style_changed (GtkComboBox *combo_box,
Packit 98cdb6
                        gpointer     user_data)
Packit 98cdb6
{
Packit 98cdb6
  GtkToolPalette *palette = GTK_TOOL_PALETTE (user_data);
Packit 98cdb6
  GtkTreeModel *model = gtk_combo_box_get_model (combo_box);
Packit 98cdb6
  GtkTreeIter iter;
Packit 98cdb6
  gint val = 0;
Packit 98cdb6
Packit 98cdb6
  if (!gtk_combo_box_get_active_iter (combo_box, &iter))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  gtk_tree_model_get (model, &iter, 1, &val, -1);
Packit 98cdb6
Packit 98cdb6
  if (val == -1)
Packit 98cdb6
    gtk_tool_palette_unset_style (palette);
Packit 98cdb6
  else
Packit 98cdb6
    gtk_tool_palette_set_style (palette, val);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GtkWidget *
Packit 98cdb6
do_toolpalette (GtkWidget *do_widget)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *box = NULL;
Packit 98cdb6
  GtkWidget *hbox = NULL;
Packit 98cdb6
  GtkWidget *combo_orientation = NULL;
Packit 98cdb6
  GtkListStore *orientation_model = NULL;
Packit 98cdb6
  GtkWidget *combo_style = NULL;
Packit 98cdb6
  GtkListStore *style_model = NULL;
Packit 98cdb6
  GtkCellRenderer *cell_renderer = NULL;
Packit 98cdb6
  GtkTreeIter iter;
Packit 98cdb6
  GtkWidget *palette = NULL;
Packit 98cdb6
  GtkWidget *palette_scroller = NULL;
Packit 98cdb6
  GtkWidget *notebook = NULL;
Packit 98cdb6
  GtkWidget *contents = NULL;
Packit 98cdb6
  GtkWidget *contents_scroller = NULL;
Packit 98cdb6
Packit 98cdb6
  if (!window)
Packit 98cdb6
    {
Packit 98cdb6
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
Packit 98cdb6
      gtk_window_set_screen (GTK_WINDOW (window),
Packit 98cdb6
                             gtk_widget_get_screen (do_widget));
Packit 98cdb6
      gtk_window_set_title (GTK_WINDOW (window), "Tool Palette");
Packit 98cdb6
      gtk_window_set_default_size (GTK_WINDOW (window), 200, 600);
Packit 98cdb6
Packit 98cdb6
      g_signal_connect (window, "destroy",
Packit 98cdb6
                        G_CALLBACK (gtk_widget_destroyed), &window);
Packit 98cdb6
      gtk_container_set_border_width (GTK_CONTAINER (window), 8);
Packit 98cdb6
Packit 98cdb6
      /* Add widgets to control the ToolPalette appearance: */
Packit 98cdb6
      box = gtk_vbox_new (FALSE, 6);
Packit 98cdb6
      gtk_container_add (GTK_CONTAINER (window), box);
Packit 98cdb6
Packit 98cdb6
      /* Orientation combo box: */
Packit 98cdb6
      orientation_model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
Packit 98cdb6
      gtk_list_store_append (orientation_model, &iter);
Packit 98cdb6
      gtk_list_store_set (orientation_model, &iter,
Packit 98cdb6
                          0, "Horizontal",
Packit 98cdb6
                          1, GTK_ORIENTATION_HORIZONTAL,
Packit 98cdb6
                          -1);
Packit 98cdb6
      gtk_list_store_append (orientation_model, &iter);
Packit 98cdb6
      gtk_list_store_set (orientation_model, &iter,
Packit 98cdb6
                          0, "Vertical",
Packit 98cdb6
                          1, GTK_ORIENTATION_VERTICAL,
Packit 98cdb6
                          -1);
Packit 98cdb6
Packit 98cdb6
      combo_orientation =
Packit 98cdb6
        gtk_combo_box_new_with_model (GTK_TREE_MODEL (orientation_model));
Packit 98cdb6
      cell_renderer = gtk_cell_renderer_text_new ();
Packit 98cdb6
      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_orientation),
Packit 98cdb6
                                  cell_renderer,
Packit 98cdb6
                                  TRUE);
Packit 98cdb6
      gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_orientation),
Packit 98cdb6
                                      cell_renderer,
Packit 98cdb6
                                      "text", 0,
Packit 98cdb6
                                      NULL);
Packit 98cdb6
      gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_orientation), &iter);
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (box), combo_orientation, FALSE, FALSE, 0);
Packit 98cdb6
Packit 98cdb6
      /* Style combo box: */
Packit 98cdb6
      style_model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
Packit 98cdb6
      gtk_list_store_append (style_model, &iter);
Packit 98cdb6
      gtk_list_store_set (style_model, &iter,
Packit 98cdb6
                          0, "Text",
Packit 98cdb6
                          1, GTK_TOOLBAR_TEXT,
Packit 98cdb6
                          -1);
Packit 98cdb6
      gtk_list_store_append (style_model, &iter);
Packit 98cdb6
      gtk_list_store_set (style_model, &iter,
Packit 98cdb6
                          0, "Both",
Packit 98cdb6
                          1, GTK_TOOLBAR_BOTH,
Packit 98cdb6
                          -1);
Packit 98cdb6
      gtk_list_store_append (style_model, &iter);
Packit 98cdb6
      gtk_list_store_set (style_model, &iter,
Packit 98cdb6
                          0, "Both: Horizontal",
Packit 98cdb6
                          1, GTK_TOOLBAR_BOTH_HORIZ,
Packit 98cdb6
                          -1);
Packit 98cdb6
      gtk_list_store_append (style_model, &iter);
Packit 98cdb6
      gtk_list_store_set (style_model, &iter,
Packit 98cdb6
                          0, "Icons",
Packit 98cdb6
                          1, GTK_TOOLBAR_ICONS,
Packit 98cdb6
                          -1);
Packit 98cdb6
      gtk_list_store_append (style_model, &iter);
Packit 98cdb6
      gtk_list_store_set (style_model, &iter,
Packit 98cdb6
                          0, "Default",
Packit 98cdb6
                          1, -1,  /* A custom meaning for this demo. */
Packit 98cdb6
                          -1);
Packit 98cdb6
      combo_style = gtk_combo_box_new_with_model (GTK_TREE_MODEL (style_model));
Packit 98cdb6
      cell_renderer = gtk_cell_renderer_text_new ();
Packit 98cdb6
      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_style),
Packit 98cdb6
                                  cell_renderer,
Packit 98cdb6
                                  TRUE);
Packit 98cdb6
      gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_style),
Packit 98cdb6
                                      cell_renderer,
Packit 98cdb6
                                      "text", 0,
Packit 98cdb6
                                      NULL);
Packit 98cdb6
      gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_style), &iter);
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (box), combo_style, FALSE, FALSE, 0);
Packit 98cdb6
Packit 98cdb6
      /* Add hbox */
Packit 98cdb6
      hbox = gtk_hbox_new (FALSE, 5);
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (box), hbox, TRUE, TRUE, 0);
Packit 98cdb6
Packit 98cdb6
      /* Add and fill the ToolPalette: */
Packit 98cdb6
      palette = gtk_tool_palette_new ();
Packit 98cdb6
Packit 98cdb6
      load_stock_items (GTK_TOOL_PALETTE (palette));
Packit 98cdb6
      load_toggle_items (GTK_TOOL_PALETTE (palette));
Packit 98cdb6
      load_special_items (GTK_TOOL_PALETTE (palette));
Packit 98cdb6
Packit 98cdb6
      palette_scroller = gtk_scrolled_window_new (NULL, NULL);
Packit 98cdb6
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (palette_scroller),
Packit 98cdb6
                                      GTK_POLICY_NEVER,
Packit 98cdb6
                                      GTK_POLICY_AUTOMATIC);
Packit 98cdb6
      gtk_container_set_border_width (GTK_CONTAINER (palette_scroller), 6);
Packit 98cdb6
Packit 98cdb6
      gtk_container_add (GTK_CONTAINER (palette_scroller), palette);
Packit 98cdb6
      gtk_container_add (GTK_CONTAINER (hbox), palette_scroller);
Packit 98cdb6
Packit 98cdb6
      gtk_widget_show_all (box);
Packit 98cdb6
Packit 98cdb6
      /* Connect signals: */
Packit 98cdb6
      g_signal_connect (combo_orientation, "changed",
Packit 98cdb6
                        G_CALLBACK (on_combo_orientation_changed), palette);
Packit 98cdb6
      g_signal_connect (combo_style, "changed",
Packit 98cdb6
                        G_CALLBACK (on_combo_style_changed), palette);
Packit 98cdb6
Packit 98cdb6
      /* Keep the widgets in sync: */
Packit 98cdb6
      on_combo_orientation_changed (GTK_COMBO_BOX (combo_orientation), palette);
Packit 98cdb6
Packit 98cdb6
      /* ===== notebook ===== */
Packit 98cdb6
Packit 98cdb6
      notebook = gtk_notebook_new ();
Packit 98cdb6
      gtk_container_set_border_width (GTK_CONTAINER (notebook), 6);
Packit 98cdb6
      gtk_box_pack_end (GTK_BOX(hbox), notebook, FALSE, FALSE, 0);
Packit 98cdb6
Packit 98cdb6
      /* ===== DnD for tool items ===== */
Packit 98cdb6
Packit 98cdb6
      g_signal_connect (palette, "drag-data-received",
Packit 98cdb6
                        G_CALLBACK (palette_drag_data_received), NULL);
Packit 98cdb6
Packit 98cdb6
      gtk_tool_palette_add_drag_dest (GTK_TOOL_PALETTE (palette),
Packit 98cdb6
                                      palette,
Packit 98cdb6
                                      GTK_DEST_DEFAULT_ALL,
Packit 98cdb6
                                      GTK_TOOL_PALETTE_DRAG_ITEMS |
Packit 98cdb6
                                      GTK_TOOL_PALETTE_DRAG_GROUPS,
Packit 98cdb6
                                      GDK_ACTION_MOVE);
Packit 98cdb6
Packit 98cdb6
      /* ===== passive DnD dest ===== */
Packit 98cdb6
Packit 98cdb6
      contents = gtk_drawing_area_new ();
Packit 98cdb6
      gtk_widget_set_app_paintable (contents, TRUE);
Packit 98cdb6
Packit 98cdb6
      g_object_connect (contents,
Packit 98cdb6
                        "signal::expose-event", canvas_expose_event, NULL,
Packit 98cdb6
                        "signal::drag-data-received", passive_canvas_drag_data_received, NULL,
Packit 98cdb6
                        NULL);
Packit 98cdb6
Packit 98cdb6
      gtk_tool_palette_add_drag_dest (GTK_TOOL_PALETTE (palette),
Packit 98cdb6
                                      contents,
Packit 98cdb6
                                      GTK_DEST_DEFAULT_ALL,
Packit 98cdb6
                                      GTK_TOOL_PALETTE_DRAG_ITEMS,
Packit 98cdb6
                                      GDK_ACTION_COPY);
Packit 98cdb6
Packit 98cdb6
      contents_scroller = gtk_scrolled_window_new (NULL, NULL);
Packit 98cdb6
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (contents_scroller),
Packit 98cdb6
                                      GTK_POLICY_AUTOMATIC,
Packit 98cdb6
                                      GTK_POLICY_ALWAYS);
Packit 98cdb6
      gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (contents_scroller),
Packit 98cdb6
                                             contents);
Packit 98cdb6
      gtk_container_set_border_width (GTK_CONTAINER (contents_scroller), 6);
Packit 98cdb6
Packit 98cdb6
      gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
Packit 98cdb6
                                contents_scroller,
Packit 98cdb6
                                gtk_label_new ("Passive DnD Mode"));
Packit 98cdb6
Packit 98cdb6
      /* ===== interactive DnD dest ===== */
Packit 98cdb6
Packit 98cdb6
      contents = gtk_drawing_area_new ();
Packit 98cdb6
      gtk_widget_set_app_paintable (contents, TRUE);
Packit 98cdb6
Packit 98cdb6
      g_object_connect (contents,
Packit 98cdb6
                        "signal::expose-event", canvas_expose_event, NULL,
Packit 98cdb6
                        "signal::drag-motion", interactive_canvas_drag_motion, NULL,
Packit 98cdb6
                        "signal::drag-data-received", interactive_canvas_drag_data_received, NULL,
Packit 98cdb6
                        "signal::drag-leave", interactive_canvas_drag_leave, NULL,
Packit 98cdb6
                        "signal::drag-drop", interactive_canvas_drag_drop, NULL,
Packit 98cdb6
                        NULL);
Packit 98cdb6
Packit 98cdb6
      gtk_tool_palette_add_drag_dest (GTK_TOOL_PALETTE (palette),
Packit 98cdb6
                                      contents,
Packit 98cdb6
                                      GTK_DEST_DEFAULT_HIGHLIGHT,
Packit 98cdb6
                                      GTK_TOOL_PALETTE_DRAG_ITEMS,
Packit 98cdb6
                                      GDK_ACTION_COPY);
Packit 98cdb6
Packit 98cdb6
      contents_scroller = gtk_scrolled_window_new (NULL, NULL);
Packit 98cdb6
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (contents_scroller),
Packit 98cdb6
                                      GTK_POLICY_AUTOMATIC,
Packit 98cdb6
                                      GTK_POLICY_ALWAYS);
Packit 98cdb6
      gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (contents_scroller),
Packit 98cdb6
                                             contents);
Packit 98cdb6
      gtk_container_set_border_width (GTK_CONTAINER (contents_scroller), 6);
Packit 98cdb6
Packit 98cdb6
      gtk_notebook_append_page (GTK_NOTEBOOK (notebook), contents_scroller,
Packit 98cdb6
                                gtk_label_new ("Interactive DnD Mode"));
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (!gtk_widget_get_visible (window))
Packit 98cdb6
    {
Packit 98cdb6
      gtk_widget_show_all (window);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      gtk_widget_destroy (window);
Packit 98cdb6
      window = NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return window;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
load_stock_items (GtkToolPalette *palette)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *group_af = gtk_tool_item_group_new ("Stock Icons (A-F)");
Packit 98cdb6
  GtkWidget *group_gn = gtk_tool_item_group_new ("Stock Icons (G-N)");
Packit 98cdb6
  GtkWidget *group_or = gtk_tool_item_group_new ("Stock Icons (O-R)");
Packit 98cdb6
  GtkWidget *group_sz = gtk_tool_item_group_new ("Stock Icons (S-Z)");
Packit 98cdb6
  GtkWidget *group = NULL;
Packit 98cdb6
Packit 98cdb6
  GtkToolItem *item;
Packit 98cdb6
  GSList *stock_ids;
Packit 98cdb6
  GSList *iter;
Packit 98cdb6
Packit 98cdb6
  stock_ids = gtk_stock_list_ids ();
Packit 98cdb6
  stock_ids = g_slist_sort (stock_ids, (GCompareFunc) strcmp);
Packit 98cdb6
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (palette), group_af);
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (palette), group_gn);
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (palette), group_or);
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (palette), group_sz);
Packit 98cdb6
Packit 98cdb6
  for (iter = stock_ids; iter; iter = g_slist_next (iter))
Packit 98cdb6
    {
Packit 98cdb6
      GtkStockItem stock_item;
Packit 98cdb6
      gchar *id = iter->data;
Packit 98cdb6
Packit 98cdb6
      switch (id[4])
Packit 98cdb6
        {
Packit 98cdb6
          case 'a':
Packit 98cdb6
            group = group_af;
Packit 98cdb6
            break;
Packit 98cdb6
Packit 98cdb6
          case 'g':
Packit 98cdb6
            group = group_gn;
Packit 98cdb6
            break;
Packit 98cdb6
Packit 98cdb6
          case 'o':
Packit 98cdb6
            group = group_or;
Packit 98cdb6
            break;
Packit 98cdb6
Packit 98cdb6
          case 's':
Packit 98cdb6
            group = group_sz;
Packit 98cdb6
            break;
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      item = gtk_tool_button_new_from_stock (id);
Packit 98cdb6
      gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM (item), id);
Packit 98cdb6
      gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
Packit 98cdb6
      gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
Packit 98cdb6
      if (!gtk_stock_lookup (id, &stock_item) || !stock_item.label)
Packit 98cdb6
        gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), id);
Packit 98cdb6
Packit 98cdb6
      g_free (id);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  g_slist_free (stock_ids);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
load_toggle_items (GtkToolPalette *palette)
Packit 98cdb6
{
Packit 98cdb6
  GSList *toggle_group = NULL;
Packit 98cdb6
  GtkToolItem *item;
Packit 98cdb6
  GtkWidget *group;
Packit 98cdb6
  char *label;
Packit 98cdb6
  int i;
Packit 98cdb6
Packit 98cdb6
  group = gtk_tool_item_group_new ("Radio Item");
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (palette), group);
Packit 98cdb6
Packit 98cdb6
  for (i = 1; i <= 10; ++i)
Packit 98cdb6
    {
Packit 98cdb6
      label = g_strdup_printf ("#%d", i);
Packit 98cdb6
      item = gtk_radio_tool_button_new (toggle_group);
Packit 98cdb6
      gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), label);
Packit 98cdb6
      g_free (label);
Packit 98cdb6
Packit 98cdb6
      gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
      toggle_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (item));
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GtkToolItem *
Packit 98cdb6
create_entry_item (const char *text)
Packit 98cdb6
{
Packit 98cdb6
  GtkToolItem *item;
Packit 98cdb6
  GtkWidget *entry;
Packit 98cdb6
Packit 98cdb6
  entry = gtk_entry_new ();
Packit 98cdb6
  gtk_entry_set_text (GTK_ENTRY (entry), text);
Packit 98cdb6
  gtk_entry_set_width_chars (GTK_ENTRY (entry), 5);
Packit 98cdb6
Packit 98cdb6
  item = gtk_tool_item_new ();
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (item), entry);
Packit 98cdb6
Packit 98cdb6
  return item;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
load_special_items (GtkToolPalette *palette)
Packit 98cdb6
{
Packit 98cdb6
  GtkToolItem *item;
Packit 98cdb6
  GtkWidget *group;
Packit 98cdb6
  GtkWidget *label_button;
Packit 98cdb6
Packit 98cdb6
  group = gtk_tool_item_group_new (NULL);
Packit 98cdb6
  label_button = gtk_button_new_with_label ("Advanced Features");
Packit 98cdb6
  gtk_widget_show (label_button);
Packit 98cdb6
  gtk_tool_item_group_set_label_widget (GTK_TOOL_ITEM_GROUP (group),
Packit 98cdb6
                                        label_button);
Packit 98cdb6
  gtk_container_add (GTK_CONTAINER (palette), group);
Packit 98cdb6
Packit 98cdb6
  item = create_entry_item ("homogeneous=FALSE");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
Packit 98cdb6
                           "homogeneous", FALSE, NULL);
Packit 98cdb6
Packit 98cdb6
  item = create_entry_item ("homogeneous=FALSE, expand=TRUE");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
Packit 98cdb6
                           "homogeneous", FALSE, "expand", TRUE,
Packit 98cdb6
                           NULL);
Packit 98cdb6
Packit 98cdb6
  item = create_entry_item ("homogeneous=FALSE, expand=TRUE, fill=FALSE");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
Packit 98cdb6
                           "homogeneous", FALSE, "expand", TRUE,
Packit 98cdb6
                           "fill", FALSE, NULL);
Packit 98cdb6
Packit 98cdb6
  item = create_entry_item ("homogeneous=FALSE, expand=TRUE, new-row=TRUE");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
Packit 98cdb6
                           "homogeneous", FALSE, "expand", TRUE,
Packit 98cdb6
                           "new-row", TRUE, NULL);
Packit 98cdb6
Packit 98cdb6
  item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_UP);
Packit 98cdb6
  gtk_tool_item_set_tooltip_text (item, "Show on vertical palettes only");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_tool_item_set_visible_horizontal (item, FALSE);
Packit 98cdb6
Packit 98cdb6
  item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
Packit 98cdb6
  gtk_tool_item_set_tooltip_text (item, "Show on horizontal palettes only");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_tool_item_set_visible_vertical (item, FALSE);
Packit 98cdb6
Packit 98cdb6
  item = gtk_tool_button_new_from_stock (GTK_STOCK_DELETE);
Packit 98cdb6
  gtk_tool_item_set_tooltip_text (item, "Do not show at all");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_widget_set_no_show_all (GTK_WIDGET (item), TRUE);
Packit 98cdb6
Packit 98cdb6
  item = gtk_tool_button_new_from_stock (GTK_STOCK_FULLSCREEN);
Packit 98cdb6
  gtk_tool_item_set_tooltip_text (item, "Expanded this item");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
  gtk_container_child_set (GTK_CONTAINER (group), GTK_WIDGET (item),
Packit 98cdb6
                           "homogeneous", FALSE,
Packit 98cdb6
                           "expand", TRUE,
Packit 98cdb6
                           NULL);
Packit 98cdb6
Packit 98cdb6
  item = gtk_tool_button_new_from_stock (GTK_STOCK_HELP);
Packit 98cdb6
  gtk_tool_item_set_tooltip_text (item, "A regular item");
Packit 98cdb6
  gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
Packit 98cdb6
}