diff options
Diffstat (limited to 'control-center/gnomecc-canvas.c')
-rw-r--r-- | control-center/gnomecc-canvas.c | 1724 |
1 files changed, 0 insertions, 1724 deletions
diff --git a/control-center/gnomecc-canvas.c b/control-center/gnomecc-canvas.c deleted file mode 100644 index 6c02e09f0..000000000 --- a/control-center/gnomecc-canvas.c +++ /dev/null @@ -1,1724 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Copyright (C) 2005 Carlos Garnacho - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: Jody Goldberg <jody@gnome.org> - * Carlos Garnacho Parro <carlosg@gnome.org> - */ - -#include "gnomecc-canvas.h" -#include "gnomecc-event-box.h" -#include "gnomecc-rounded-rect.h" -#include <libgnomecanvas/libgnomecanvas.h> -#include <libgnome/gnome-desktop-item.h> -#include <gconf/gconf-client.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> -#include <atk/atk.h> - -#define GNOMECC_CANVAS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNOMECC_TYPE_CANVAS, GnomeccCanvasPrivate)) - -#define PAD 5 /*when scrolling keep a few pixels above or below if possible */ -#define ABOVE_LINE_SPACING 4 -#define UNDER_LINE_SPACING 0 -#define UNDER_TITLE_SPACING 0 /* manually insert 1 blank line of text */ -#define LINE_HEIGHT 1 -#define BORDERS 7 -#define MAX_ITEM_WIDTH 120 -#define ITEMS_SEPARATION 12 - -typedef struct _GnomeccCanvasPrivate GnomeccCanvasPrivate; - -struct _GnomeccCanvasPrivate { - GnomeCanvasItem *under_cover; - double height; - double width; - - double min_height; - double max_width; - ControlCenterInformation *info; - ControlCenterEntry *selected; - - gboolean rtl; - gint items_per_row; - - /* calculated sizes - for the elements */ - gdouble max_item_width; - gdouble max_item_height; - gdouble max_icon_height; - - /* accessibility stuff */ - GHashTable *accessible_children; -}; - -typedef struct { - GnomeccCanvas *canvas; - - GnomeCanvasGroup *group; - GnomeCanvasItem *text; - GnomeCanvasItem *pixbuf; - GnomeCanvasItem *highlight_pixbuf; - GnomeCanvasItem *cover; - GnomeCanvasItem *selection; - double icon_height; - double icon_width; - double text_height; - guint launching : 1; - guint selected : 1; - guint highlighted : 1; - - gint n_category; - gint n_entry; - gint index; -} EntryInfo; - -typedef struct { - GnomeCanvasGroup *group; - GnomeCanvasItem *title; - GnomeCanvasItem *line; -} CategoryInfo; - -enum { - SELECTION_CHANGED, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_INFO -}; - -static guint gnomecc_canvas_signals [LAST_SIGNAL] = { 0 }; - - -static void gnomecc_canvas_class_init (GnomeccCanvasClass *class); -static void gnomecc_canvas_init (GnomeccCanvas *canvas); -static void gnomecc_canvas_finalize (GObject *object); - -static void gnomecc_canvas_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gnomecc_canvas_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static void gnomecc_canvas_draw_background (GnomeCanvas *canvas, GdkDrawable *drawable, - int x, int y, int width, int height); - -static void gnomecc_canvas_size_allocate (GtkWidget *canvas, - GtkAllocation *allocation); -static void gnomecc_canvas_style_set (GtkWidget *canvas, - GtkStyle *previous_style); -static void gnomecc_canvas_realize (GtkWidget *canvas); - -static AtkObject* gnomecc_canvas_get_accessible (GtkWidget *widget); - - - -G_DEFINE_TYPE (GnomeccCanvas, gnomecc_canvas, GNOME_TYPE_CANVAS); - -static void -gnomecc_canvas_class_init (GnomeccCanvasClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - GnomeCanvasClass *canvas_class = GNOME_CANVAS_CLASS (class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); - - object_class->set_property = gnomecc_canvas_set_property; - object_class->get_property = gnomecc_canvas_get_property; - object_class->finalize = gnomecc_canvas_finalize; - canvas_class->draw_background = gnomecc_canvas_draw_background; - - widget_class->style_set = gnomecc_canvas_style_set; - widget_class->size_allocate = gnomecc_canvas_size_allocate; - widget_class->realize = gnomecc_canvas_realize; - widget_class->get_accessible = gnomecc_canvas_get_accessible; - - class->changed = NULL; - - g_object_class_install_property (object_class, - PROP_INFO, - g_param_spec_pointer ("info", - "information for the canvas", - "information for the canvas", - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); - gnomecc_canvas_signals [SELECTION_CHANGED] = - g_signal_new ("selection-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GnomeccCanvasClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - g_type_class_add_private (object_class, - sizeof (GnomeccCanvasPrivate)); -} - -static void -gnomecc_canvas_init (GnomeccCanvas *canvas) -{ - GnomeccCanvasPrivate *priv; - - g_return_if_fail (GNOMECC_IS_CANVAS (canvas)); - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - priv->max_width = 300; - priv->min_height = 0; - priv->info = NULL; - priv->selected = NULL; - - priv->max_item_width = 0; - priv->max_item_height = 0; - priv->items_per_row = 0; - priv->rtl = (gtk_widget_get_direction (GTK_WIDGET (canvas)) == GTK_TEXT_DIR_RTL); - - priv->accessible_children = g_hash_table_new (g_int_hash, g_int_equal); - - gtk_widget_show_all (GTK_WIDGET (canvas)); -} - -static gboolean -single_click_activates (void) -{ - static gboolean needs_init = TRUE; - static gboolean use_single_click = FALSE; - if (needs_init) { - GConfClient *client = gconf_client_get_default (); - char *policy = gconf_client_get_string (client, "/apps/nautilus/preferences/click_policy", NULL); - g_object_unref (G_OBJECT (client)); - - if (policy != NULL) { - use_single_click = (0 == g_ascii_strcasecmp (policy, "single")); - g_free (policy); - } - needs_init = FALSE; - } - - return use_single_click; -} - -static void -gnome_canvas_item_show_hide (GnomeCanvasItem *item, gboolean show) -{ - if (show) - gnome_canvas_item_show (item); - else - gnome_canvas_item_hide (item); -} - -static void -setup_entry (GnomeccCanvas *canvas, ControlCenterEntry *entry) -{ - GnomeccCanvasPrivate *priv; - EntryInfo *ei; - GtkWidget *widget; - GtkStateType state; - - if (!entry) - return; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - widget = GTK_WIDGET (canvas); - ei = entry->user_data; - - if (ei->pixbuf) { - gnome_canvas_item_show_hide (ei->highlight_pixbuf, ei->highlighted); - gnome_canvas_item_show_hide (ei->pixbuf, !ei->highlighted); - } - if (!ei->selected) - state = GTK_STATE_NORMAL; - else if (gtk_window_has_toplevel_focus (GTK_WINDOW (gtk_widget_get_toplevel (widget)))) - state = GTK_STATE_SELECTED; - else - state = GTK_STATE_ACTIVE; - gnome_canvas_item_show_hide (ei->selection, ei->selected); - g_object_set (ei->selection, - "fill_color_gdk", &widget->style->base [state], - NULL); - g_object_set (ei->text, - "fill_color_gdk", &widget->style->text [state], - NULL); -} - -static gboolean -cb_entry_info_reset (gpointer data) -{ - EntryInfo *ei = data; - ei->launching = FALSE; - return FALSE; -} - -static void -activate_entry (ControlCenterEntry *entry) -{ - EntryInfo *ei = entry->user_data; - - if (!ei->launching) { - GnomeDesktopItem *desktop_item; - - ei->launching = TRUE; - gtk_timeout_add (1000, cb_entry_info_reset, ei); - - desktop_item = gnome_desktop_item_new_from_file (entry->desktop_entry, - GNOME_DESKTOP_ITEM_LOAD_ONLY_IF_EXISTS, - NULL); - if (desktop_item != NULL) { - gnome_desktop_item_launch (desktop_item, NULL, 0, NULL); - gnome_desktop_item_unref (desktop_item); - } - } -} - -static void -select_entry (GnomeccCanvas *canvas, ControlCenterEntry *entry) -{ - GnomeccCanvasPrivate *priv; - EntryInfo *ei = NULL; - GtkAdjustment *pos; - double affine[6]; - ControlCenterEntry *selected; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - selected = priv->selected; - - if (selected == entry) - return; - - if (selected && selected->user_data) - ((EntryInfo *) selected->user_data)->selected = FALSE; - setup_entry (canvas, selected); - - priv->selected = selected = entry; - - if (selected && selected->user_data) - ((EntryInfo *) selected->user_data)->selected = TRUE; - setup_entry (canvas, selected); - - g_signal_emit (canvas, gnomecc_canvas_signals [SELECTION_CHANGED], 0, - (entry) ? entry->comment : NULL); - - if (!entry) - return; - - ei = entry->user_data; - gnome_canvas_item_i2c_affine (GNOME_CANVAS_ITEM (ei->group), affine); - pos = gtk_layout_get_vadjustment (GTK_LAYOUT (ei->cover->canvas)); - - if (affine[5] < pos->value) - gtk_adjustment_set_value (pos, MAX (affine[5] - PAD, 0)); - else if ((affine[5] + priv->max_item_height) > (pos->value+pos->page_size)) - gtk_adjustment_set_value (pos, MAX (MIN (affine[5] + priv->max_item_height + PAD, pos->upper) - pos->page_size, 0)); -} - -static gboolean -cover_event (GnomeCanvasItem *item, GdkEvent *event, ControlCenterEntry *entry) -{ - EntryInfo *ei = entry->user_data; - GnomeccCanvas *canvas = ei->canvas; - - switch (event->type) { - case GDK_ENTER_NOTIFY: - ei->highlighted = TRUE; - setup_entry (canvas, entry); /* highlight even if it is already selected */ - return TRUE; - case GDK_LEAVE_NOTIFY: - ei->highlighted = FALSE; - setup_entry (canvas, entry); - return TRUE; - case GDK_BUTTON_PRESS: - if (single_click_activates ()) { - activate_entry (entry); - } else { - select_entry (canvas, entry); - } - return TRUE; - case GDK_2BUTTON_PRESS: - activate_entry (entry); - return TRUE; - default: - return FALSE; - } -} - -static gboolean -cb_canvas_event (GnomeCanvasItem *item, GdkEvent *event, GnomeccCanvas *canvas) -{ - GnomeccCanvasPrivate *priv; - EntryInfo *ei = NULL; - gint n_category, n_entry; - gint n_categories, n_entries; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - if (event->type == GDK_BUTTON_PRESS) { - select_entry (canvas, NULL); - return TRUE; - } - - if (event->type != GDK_KEY_PRESS) - return FALSE; - - if (priv->selected) - ei = priv->selected->user_data; - - n_entry = 0; - n_category = 0; - n_categories = priv->info->n_categories; - n_entries = priv->info->categories[ei->n_category]->n_entries; - - switch (event->key.keyval) { - case GDK_KP_Right: - case GDK_Right: - if (ei) { - n_entry = (priv->rtl) ? ei->n_entry - 1 : ei->n_entry + 1; - n_category = ei->n_category; - } - break; - case GDK_KP_Left: - case GDK_Left: - if (ei) { - n_entry = (priv->rtl) ? ei->n_entry + 1 : ei->n_entry - 1; - n_category = ei->n_category; - } - break; - case GDK_KP_Down: - case GDK_Down: - if (ei) { - n_category = ei->n_category; - n_entry = ei->n_entry; - - if (ei->n_entry + priv->items_per_row < - priv->info->categories[n_category]->n_entries) - n_entry += priv->items_per_row; - } - break; - case GDK_KP_Up: - case GDK_Up: - if (ei) { - n_category = ei->n_category; - n_entry = ei->n_entry; - - if (ei->n_entry - priv->items_per_row >= 0) - n_entry -= priv->items_per_row; - } - break; - case GDK_Tab: - case GDK_KP_Tab: - if (ei) { - n_entry = 0; - n_category = ei->n_category + 1; - - if (n_category > priv->info->n_categories - 1) - n_category = 0; - } - break; - case GDK_ISO_Left_Tab: - if (ei) { - n_entry = 0; - n_category = ei->n_category - 1; - - if (n_category < 0) - n_category = priv->info->n_categories; - } - break; - case GDK_Return: - case GDK_KP_Enter: - if (priv->selected) - activate_entry (priv->selected); - - return TRUE; - break; - case GDK_Escape: - gtk_main_quit (); - return TRUE; - case 'q': - case 'Q': - if (event->key.state == GDK_CONTROL_MASK) { - gtk_main_quit (); - } - return TRUE; - default: - return FALSE; - } - - n_category = CLAMP (n_category, 0, priv->info->n_categories - 1); - n_entry = CLAMP (n_entry, 0, priv->info->categories[n_category]->n_entries - 1); - - select_entry (canvas, priv->info->categories[n_category]->entries[n_entry]); - return TRUE; -} - -static void -calculate_item_width (GnomeccCanvas *canvas, EntryInfo *ei) -{ - GnomeccCanvasPrivate *priv; - PangoLayout *layout; - PangoRectangle rectangle; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - layout = GNOME_CANVAS_TEXT (ei->text)->layout; - - pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); - pango_layout_set_width (layout, -1); - pango_layout_get_pixel_extents (layout, NULL, &rectangle); - - /* If its too big wrap at the max and regen to find the layout */ - if (rectangle.width > MAX_ITEM_WIDTH) { - pango_layout_set_width (layout, MAX_ITEM_WIDTH * PANGO_SCALE); - pango_layout_get_pixel_extents (layout, NULL, &rectangle); - rectangle.width = MAX_ITEM_WIDTH; - } - - ei->text_height = rectangle.height; - - priv->max_item_width = MAX (priv->max_item_width, rectangle.width); -} - -static void -calculate_item_height (GnomeccCanvas *canvas, EntryInfo *ei) -{ - GnomeccCanvasPrivate *priv; - gint item_height; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - if (ei->pixbuf) - priv->max_icon_height = MAX (priv->max_icon_height, ei->icon_height); - - item_height = ei->icon_height + ei->text_height; - priv->max_item_height = MAX (priv->max_item_height, item_height); -} - -static void -calculate_sizes (GnomeccCanvas *canvas) -{ - GnomeccCanvasPrivate *priv; - int i, j; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - priv->max_item_height = 0; - priv->max_icon_height = 0; - priv->max_item_width = 0; - - for (i = 0; i < priv->info->n_categories; i++) { - for (j = 0; j < priv->info->categories[i]->n_entries; j++) { - EntryInfo *ei = priv->info->categories[i]->entries[j]->user_data; - - calculate_item_width (canvas, ei); - calculate_item_height (canvas, ei); - } - } -} - -static void -gnome_canvas_item_move_absolute (GnomeCanvasItem *item, double dx, double dy) -{ - double translate[6]; - - g_return_if_fail (item != NULL); - g_return_if_fail (GNOME_IS_CANVAS_ITEM (item)); - - art_affine_translate (translate, dx, dy); - - gnome_canvas_item_affine_absolute (item, translate); -} - -static guchar -lighten_component (guchar cur_value) -{ - int new_value = cur_value; - new_value += 24 + (new_value >> 3); - if (new_value > 255) { - new_value = 255; - } - return (guchar) new_value; -} - -static GdkPixbuf * -create_spotlight_pixbuf (GdkPixbuf* src) -{ - GdkPixbuf *dest; - int i, j; - int width, height, has_alpha, src_row_stride, dst_row_stride; - guchar *target_pixels, *original_pixels; - guchar *pixsrc, *pixdest; - - g_return_val_if_fail (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB, NULL); - g_return_val_if_fail ((!gdk_pixbuf_get_has_alpha (src) - && gdk_pixbuf_get_n_channels (src) == 3) - || (gdk_pixbuf_get_has_alpha (src) - && gdk_pixbuf_get_n_channels (src) == 4), NULL); - g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (src) == 8, NULL); - - dest = gdk_pixbuf_copy (src); - - has_alpha = gdk_pixbuf_get_has_alpha (src); - width = gdk_pixbuf_get_width (src); - height = gdk_pixbuf_get_height (src); - dst_row_stride = gdk_pixbuf_get_rowstride (dest); - src_row_stride = gdk_pixbuf_get_rowstride (src); - target_pixels = gdk_pixbuf_get_pixels (dest); - original_pixels = gdk_pixbuf_get_pixels (src); - - for (i = 0; i < height; i++) { - pixdest = target_pixels + i * dst_row_stride; - pixsrc = original_pixels + i * src_row_stride; - for (j = 0; j < width; j++) { - *pixdest++ = lighten_component (*pixsrc++); - *pixdest++ = lighten_component (*pixsrc++); - *pixdest++ = lighten_component (*pixsrc++); - if (has_alpha) { - *pixdest++ = *pixsrc++; - } - } - } - - return dest; -} - -static void -build_canvas (GnomeccCanvas *canvas) -{ - GnomeccCanvasPrivate *priv; - GnomeCanvas *gcanvas; - int i, j, index; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - gcanvas = GNOME_CANVAS (canvas); - index = 0; - - priv->under_cover = gnome_canvas_item_new (gnome_canvas_root (gcanvas), - gnomecc_event_box_get_type(), - NULL); - - gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (gnome_canvas_root (gcanvas))); - g_signal_connect (gnome_canvas_root (gcanvas), "event", - G_CALLBACK (cb_canvas_event), canvas); - - for (i = 0; i < priv->info->n_categories; i++) { - CategoryInfo *catinfo; - - if (priv->info->categories[i]->user_data == NULL) - priv->info->categories[i]->user_data = g_new (CategoryInfo, 1); - - catinfo = priv->info->categories[i]->user_data; - catinfo->group = NULL; - catinfo->title = NULL; - catinfo->line = NULL; - - catinfo->group = - GNOME_CANVAS_GROUP (gnome_canvas_item_new (gnome_canvas_root (gcanvas), - gnome_canvas_group_get_type (), - NULL)); - gnome_canvas_item_move_absolute (GNOME_CANVAS_ITEM (catinfo->group), 0, BORDERS); - - if (i > 0) { - catinfo->line = gnome_canvas_item_new (catinfo->group, - gnome_canvas_rect_get_type (), - "x2", (double) priv->max_width - 2 * BORDERS, - "y2", (double) LINE_HEIGHT, - NULL); - } - - catinfo->title = NULL; - if (priv->info->categories[i] && (priv->info->n_categories != 1 || priv->info->categories[0]->real_category)) { - char *label = g_strdup_printf ("<span weight=\"bold\">%s</span>", priv->info->categories[i]->title); - catinfo->title = gnome_canvas_item_new (catinfo->group, - gnome_canvas_text_get_type (), - "text", priv->info->categories[i]->title, - "markup", label, - "anchor", GTK_ANCHOR_NW, - NULL); - g_free (label); - } - - for (j = 0; j < priv->info->categories[i]->n_entries; j++) { - EntryInfo *ei; - - if (priv->info->categories[i]->entries[j]->user_data == NULL) - priv->info->categories[i]->entries[j]->user_data = g_new0 (EntryInfo, 1); - - ei = priv->info->categories[i]->entries[j]->user_data; - - ei->canvas = canvas; - ei->group = GNOME_CANVAS_GROUP ( - gnome_canvas_item_new (catinfo->group, - gnome_canvas_group_get_type (), - NULL)); - ei->selection = gnome_canvas_item_new ( - ei->group, - GNOMECC_TYPE_ROUNDED_RECT, - NULL); - - if (priv->info->categories[i]->entries[j]->title) { - ei->text = gnome_canvas_item_new (ei->group, - gnome_canvas_text_get_type (), - "anchor", GTK_ANCHOR_NW, - "justification", GTK_JUSTIFY_CENTER, - "clip", TRUE, - NULL); - pango_layout_set_alignment (GNOME_CANVAS_TEXT (ei->text)->layout, - PANGO_ALIGN_CENTER); - pango_layout_set_justify (GNOME_CANVAS_TEXT (ei->text)->layout, - FALSE); - g_object_set (ei->text, - "text", priv->info->categories[i]->entries[j]->title, - NULL); - } else - ei->text = NULL; - - if (priv->info->categories[i]->entries[j]->icon_pixbuf) { - GdkPixbuf *pixbuf = priv->info->categories[i]->entries[j]->icon_pixbuf; - GdkPixbuf *highlight_pixbuf = - create_spotlight_pixbuf (pixbuf); - ei->icon_height = gdk_pixbuf_get_height (pixbuf); - ei->icon_width = gdk_pixbuf_get_width (pixbuf); - ei->pixbuf = gnome_canvas_item_new (ei->group, - gnome_canvas_pixbuf_get_type (), - "pixbuf", pixbuf, - NULL); - g_object_unref (pixbuf); - ei->highlight_pixbuf = gnome_canvas_item_new (ei->group, - gnome_canvas_pixbuf_get_type (), - "pixbuf", highlight_pixbuf, - NULL); - g_object_unref (highlight_pixbuf); - } else { - ei->pixbuf = NULL; - ei->highlight_pixbuf = NULL; - } - - ei->cover = gnome_canvas_item_new (ei->group, - gnomecc_event_box_get_type(), - NULL); - calculate_item_width (canvas, ei); - calculate_item_height (canvas, ei); - - ei->n_category = i; - ei->n_entry = j; - ei->index = index; - - g_signal_connect (ei->cover, "event", - G_CALLBACK (cover_event), - priv->info->categories[i]->entries[j]); - - setup_entry (canvas, priv->info->categories[i]->entries[j]); - index++; - } - } -} - -static void -gnomecc_canvas_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GnomeccCanvasPrivate *priv; - - priv = GNOMECC_CANVAS_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_INFO: - priv->info = g_value_get_pointer (value); - build_canvas (GNOMECC_CANVAS (object)); - break; - } -} - -static void -gnomecc_canvas_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GnomeccCanvasPrivate *priv; - - priv = GNOMECC_CANVAS_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_INFO: - g_value_set_pointer (value, priv->info); - break; - } -} - -static void -gnomecc_canvas_finalize (GObject *object) -{ - if (G_OBJECT_CLASS (gnomecc_canvas_parent_class)->finalize) - (* G_OBJECT_CLASS (gnomecc_canvas_parent_class)->finalize) (object); -} - -static void -gnomecc_canvas_draw_background (GnomeCanvas *canvas, GdkDrawable *drawable, - int x, int y, int width, int height) -{ - /* By default, we use the style base color. */ - gdk_gc_set_foreground (canvas->pixmap_gc, - >K_WIDGET (canvas)->style->base[GTK_STATE_NORMAL]); - gdk_draw_rectangle (drawable, - canvas->pixmap_gc, - TRUE, - 0, 0, - width, height); -} - -/* A category canvas item contains all the elements - * for the category, as well as the title and a separator - */ -static void -relayout_category (GnomeccCanvas *canvas, CategoryInfo *catinfo, - gint vert_pos, gint *category_vert_pos) -{ - GnomeccCanvasPrivate *priv; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - gnome_canvas_item_move_absolute (GNOME_CANVAS_ITEM (catinfo->group), - 0, vert_pos); - - if (catinfo->line) { - gnome_canvas_item_move_absolute (catinfo->line, BORDERS, ABOVE_LINE_SPACING); - - gnome_canvas_item_set (catinfo->line, - "x2", (double) priv->max_width - 2 * BORDERS, - "y2", (double) LINE_HEIGHT, - NULL); - } - - if (catinfo->title) { - double text_height, text_width; - - g_object_get (catinfo->title, - "text_height", &text_height, - "text_width", &text_width, - NULL); - - *category_vert_pos += text_height; /* move it down 1 line */ - gnome_canvas_item_move_absolute (catinfo->title, - (priv->rtl) ? priv->max_width - BORDERS - text_width : BORDERS, - *category_vert_pos); - *category_vert_pos += text_height + text_height/2 + UNDER_TITLE_SPACING; - } -} - -static void -relayout_item (GnomeccCanvas *canvas, EntryInfo *ei, - gint category_horiz_pos, gint category_vert_pos) -{ - GnomeccCanvasPrivate *priv; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - gnome_canvas_item_move_absolute (GNOME_CANVAS_ITEM (ei->group), - category_horiz_pos, - category_vert_pos); - - gnome_canvas_item_set (ei->selection, - "x2", (double) priv->max_item_width + 2 * PAD, - "y2", (double) ei->text_height + 1, /* expand it down slightly */ - NULL); - - gnome_canvas_item_move_absolute (ei->selection, -PAD, priv->max_icon_height); - - if (ei->text) { - /* canvas asks layout for its extent, layout gives real - * size, not fixed width and drawing gets confused. - */ - gnome_canvas_item_set (ei->text, - "clip_width", (double) priv->max_item_width, - "clip_height", (double) priv->max_item_height, - NULL); - - /* text is centered by pango */ - pango_layout_set_width (GNOME_CANVAS_TEXT (ei->text)->layout, - (gint) priv->max_item_width * PANGO_SCALE); - - gnome_canvas_item_move_absolute (ei->text, - 0, priv->max_icon_height); - } - - if (ei->pixbuf) { - /* manually center the icon */ - gnome_canvas_item_move_absolute (ei->pixbuf, - priv->max_item_width / 2 - ei->icon_width / 2, 0); - gnome_canvas_item_move_absolute (ei->highlight_pixbuf, - priv->max_item_width / 2 - ei->icon_width / 2, 0); - } - - /* cover the item */ - gnome_canvas_item_set (ei->cover, - "x2", (double) priv->max_item_width, - "y2", (double) priv->max_item_height, - NULL); -} - -static void -relayout_canvas (GnomeccCanvas *canvas) -{ - gint cat, cat_count, entry, cat_entries; - gint vert_pos, category_vert_pos, category_horiz_pos; - gint real_width; - GnomeccCanvasPrivate *priv; - ControlCenterCategory *category; - CategoryInfo *catinfo; - EntryInfo *ei; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - real_width = priv->max_width - 2 * BORDERS + ITEMS_SEPARATION; - priv->items_per_row = real_width / ((gint) priv->max_item_width + ITEMS_SEPARATION); - - cat_count = priv->info->n_categories; - vert_pos = BORDERS; - - for (cat = 0; cat < cat_count; cat++) { - category_vert_pos = 0; - - category_horiz_pos = (priv->rtl) ? priv->max_width - (gint) priv->max_item_width - BORDERS : BORDERS; - - category = priv->info->categories [cat]; - catinfo = category->user_data; - - cat_entries = category->n_entries; - - relayout_category (canvas, catinfo, vert_pos, &category_vert_pos); - category_vert_pos += UNDER_LINE_SPACING; - - for (entry = 0; entry < cat_entries; entry++) { - /* we don't want the first item to wrap, it would - be too separated from the section title */ - if ((entry > 0) && - ((priv->items_per_row == 0) || - (priv->items_per_row > 0 && (entry % priv->items_per_row == 0)))) { - - category_horiz_pos = (priv->rtl) ? - priv->max_width - (gint) priv->max_item_width - BORDERS : BORDERS; - category_vert_pos += (gint) priv->max_item_height + ITEMS_SEPARATION; - } - - ei = category->entries[entry]->user_data; - - relayout_item (canvas, ei, category_horiz_pos, category_vert_pos); - - if (priv->rtl) - category_horiz_pos -= (gint) priv->max_item_width + ITEMS_SEPARATION; - else - category_horiz_pos += (gint) priv->max_item_width + ITEMS_SEPARATION; - } - - category_vert_pos += (gint) priv->max_item_height; - vert_pos += category_vert_pos + ITEMS_SEPARATION; - } - - /* substract the last ITEMS_SEPARATION to - adjust the canvas size a bit more */ - vert_pos -= ITEMS_SEPARATION; - - priv->height = MAX (vert_pos, priv->min_height); - priv->width = priv->max_width; -} - -static void -gnomecc_canvas_size_allocate(GtkWidget *canvas, GtkAllocation *allocation) -{ - GnomeccCanvasPrivate *priv; - - if (GTK_WIDGET_CLASS (gnomecc_canvas_parent_class)->size_allocate) - (* GTK_WIDGET_CLASS (gnomecc_canvas_parent_class)->size_allocate) (canvas, allocation); - - if (allocation->height == 1 || allocation->width == 1) - return; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - priv->max_width = allocation->width; - priv->min_height = allocation->height; - - relayout_canvas (GNOMECC_CANVAS (canvas)); - - gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), 0, 0, priv->width - 1, priv->height - 1); - g_object_set (priv->under_cover, - "x2", priv->width, - "y2", priv->height, - NULL); -} - -static void -set_style (GnomeccCanvas *canvas, gboolean font_changed) -{ - int i, j; - GnomeccCanvasPrivate *priv; - GtkWidget *widget = GTK_WIDGET (canvas); - - if (!GTK_WIDGET_REALIZED (widget)) - return; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - for (i = 0; i < priv->info->n_categories; i++) { - CategoryInfo *catinfo = priv->info->categories[i]->user_data; - - if (catinfo->line) { - g_object_set (catinfo->line, - "fill_color_gdk", &widget->style->text_aa[GTK_STATE_NORMAL], - NULL); - } - if (catinfo->title) { - g_object_set (catinfo->title, - "fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL], - NULL); - - if (font_changed) - g_object_set (catinfo->title, - "font", NULL, - NULL); - } - - for (j = 0; j < priv->info->categories[i]->n_entries; j++) { - ControlCenterEntry *entry = priv->info->categories[i]->entries[j]; - EntryInfo *entryinfo = entry->user_data; - if (font_changed && entryinfo->text) - g_object_set (entryinfo->text, - "font", NULL, - NULL); - setup_entry (canvas, entry); - } - } - - if (font_changed) { - calculate_sizes (canvas); - relayout_canvas (canvas); - } -} - -static void -gnomecc_canvas_style_set (GtkWidget *canvas, GtkStyle *previous_style) -{ - if (!GTK_WIDGET_REALIZED (canvas)) - return; - - set_style (GNOMECC_CANVAS (canvas), (previous_style && - canvas->style && - !pango_font_description_equal (canvas->style->font_desc, - previous_style->font_desc))); -} - -static void -gnomecc_canvas_realize (GtkWidget *canvas) -{ - if (GTK_WIDGET_CLASS (gnomecc_canvas_parent_class)->realize) - (* GTK_WIDGET_CLASS (gnomecc_canvas_parent_class)->realize) (canvas); - - set_style (GNOMECC_CANVAS (canvas), FALSE); -} - -GtkWidget* -gnomecc_canvas_new (ControlCenterInformation *info) -{ - return g_object_new (GNOMECC_TYPE_CANVAS, - "info", info, - NULL); -} - -/* Accessibility support */ -static gpointer accessible_parent_class; -static gpointer accessible_item_parent_class; - -enum { - ACTION_ACTIVATE, - LAST_ACTION -}; - -typedef struct { - AtkObject parent; - - ControlCenterEntry *entry; - AtkStateSet *state_set; - - guint action_idle_handler; -} GnomeccCanvasItemAccessible; - -typedef struct { - AtkObjectClass parent_class; -} GnomeccCanvasItemAccessibleClass; - -static const gchar *const action_names[] = -{ - "activate", - NULL -}; - -static const gchar *const action_descriptions[] = -{ - "Activate item", - NULL -}; - -static void -gnomecc_canvas_item_accessible_get_extents (AtkComponent *component, - gint *x, - gint *y, - gint *width, - gint *height, - AtkCoordType coord_type) -{ - GnomeccCanvasItemAccessible *item; - GnomeccCanvas *canvas; - GnomeCanvasItem *cover; - AtkObject *parent_object; - gint p_x, p_y; - - item = (GnomeccCanvasItemAccessible *) component; - - canvas = ((EntryInfo *) item->entry->user_data)->canvas; - parent_object = gtk_widget_get_accessible (GTK_WIDGET (canvas)); - atk_component_get_position (ATK_COMPONENT (parent_object), &p_x, &p_y, coord_type); - - /* the cover pretty much represents the item size */ - cover = GNOME_CANVAS_ITEM (((EntryInfo *)item->entry->user_data)->cover); - - *x = p_x + cover->x1; - *y = p_y + cover->y1; - *width = cover->x2 - cover->x1; - *height = cover->y2 - cover->y1; -} - -static void -atk_component_item_interface_init (AtkComponentIface *iface) -{ - iface->get_extents = gnomecc_canvas_item_accessible_get_extents; -} - -static gboolean -idle_do_action (gpointer data) -{ - GnomeccCanvasItemAccessible *item; - - item = (GnomeccCanvasItemAccessible *) data; - - item->action_idle_handler = 0; - activate_entry (item->entry); - - return FALSE; -} - -static gboolean -gnomecc_canvas_item_accessible_action_do_action (AtkAction *action, - gint index) -{ - GnomeccCanvasItemAccessible *item; - - if (index < 0 || index >= LAST_ACTION) - return FALSE; - - item = (GnomeccCanvasItemAccessible *) action; - - switch (index) { - case ACTION_ACTIVATE: - if (!item->action_idle_handler) - item->action_idle_handler = g_idle_add (idle_do_action, item); - break; - default: - g_assert_not_reached (); - return FALSE; - } - - return TRUE; -} - -static gint -gnomecc_canvas_item_accessible_action_get_n_actions (AtkAction *action) -{ - return LAST_ACTION; -} - -static const gchar * -gnomecc_canvas_item_accessible_action_get_description (AtkAction *action, - gint index) -{ - if (index < 0 || index >= LAST_ACTION) - return NULL; - - return action_descriptions[index]; -} - -static const gchar * -gnomecc_canvas_item_accessible_action_get_name (AtkAction *action, - gint index) -{ - if (index < 0 || index >= LAST_ACTION) - return NULL; - - return action_names[index]; -} - -static void -atk_action_item_interface_init (AtkActionIface *iface) -{ - iface->do_action = gnomecc_canvas_item_accessible_action_do_action; - iface->get_n_actions = gnomecc_canvas_item_accessible_action_get_n_actions; - iface->get_description = gnomecc_canvas_item_accessible_action_get_description; - iface->get_name = gnomecc_canvas_item_accessible_action_get_name; -} - -static gint -gnomecc_canvas_item_accessible_get_index_in_parent (AtkObject *object) -{ - GnomeccCanvasItemAccessible *item; - - item = (GnomeccCanvasItemAccessible *) object; - - return ((EntryInfo *) item->entry->user_data)->index; -} - -static G_CONST_RETURN gchar* -gnomecc_canvas_item_accessible_get_name (AtkObject *object) -{ - GnomeccCanvasItemAccessible *item; - - if (object->name) - return object->name; - else { - item = (GnomeccCanvasItemAccessible *) object; - - if (item->entry && item->entry->title) - return item->entry->title; - else - return "Item with no description"; - } -} - -static AtkObject* -gnomecc_canvas_item_accessible_get_parent (AtkObject *object) -{ - GnomeccCanvasItemAccessible *item; - GnomeccCanvas *canvas; - - item = (GnomeccCanvasItemAccessible *) object; - canvas = ((EntryInfo *) item->entry->user_data)->canvas; - - return gtk_widget_get_accessible (GTK_WIDGET (canvas)); -} - -static AtkStateSet* -gnomecc_canvas_item_accessible_ref_state_set (AtkObject *object) -{ - GnomeccCanvasItemAccessible *item; - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - - item = (GnomeccCanvasItemAccessible *) object; - canvas = ((EntryInfo *) item->entry->user_data)->canvas; - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - if (item->entry == priv->selected) - atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSED); - else - atk_state_set_remove_state (item->state_set, ATK_STATE_FOCUSED); - - return g_object_ref (item->state_set); -} - -static void -gnomecc_canvas_item_accessible_class_init (AtkObjectClass *class) -{ - GObjectClass *object_class; - - accessible_item_parent_class = g_type_class_peek_parent (class); - - object_class = (GObjectClass *)class; - - class->get_index_in_parent = gnomecc_canvas_item_accessible_get_index_in_parent; - class->get_name = gnomecc_canvas_item_accessible_get_name; - class->get_parent = gnomecc_canvas_item_accessible_get_parent; - class->ref_state_set = gnomecc_canvas_item_accessible_ref_state_set; -} - -static void -gnomecc_canvas_item_accessible_object_init (GnomeccCanvasItemAccessible *item) -{ - item->state_set = atk_state_set_new (); - - atk_state_set_add_state (item->state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (item->state_set, ATK_STATE_FOCUSABLE); - atk_state_set_add_state (item->state_set, ATK_STATE_SENSITIVE); - atk_state_set_add_state (item->state_set, ATK_STATE_SELECTABLE); - atk_state_set_add_state (item->state_set, ATK_STATE_VISIBLE); - - item->action_idle_handler = 0; -} - -static GType -gnomecc_canvas_item_accessible_get_type (void) -{ - static GType type = 0; - - if (type == 0) { - static const GTypeInfo info = { - sizeof (GnomeccCanvasItemAccessibleClass), - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) gnomecc_canvas_item_accessible_class_init, /* class init */ - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - sizeof (GnomeccCanvasItemAccessible), /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) gnomecc_canvas_item_accessible_object_init, /* instance init */ - NULL /* value table */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) atk_component_item_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - static const GInterfaceInfo atk_action_info = { - (GInterfaceInitFunc) atk_action_item_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - type = g_type_register_static (ATK_TYPE_OBJECT, - "GnomeccCanvasItemAccessible", &info, 0); - - g_type_add_interface_static (type, ATK_TYPE_COMPONENT, - &atk_component_info); - g_type_add_interface_static (type, ATK_TYPE_ACTION, - &atk_action_info); - } - - return type; -} - -static gint -gnomecc_canvas_accessible_get_n_children (AtkObject *accessible) -{ - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - GtkWidget *widget; - gint i, count; - - widget = GTK_ACCESSIBLE (accessible)->widget; - - if (!widget) - return 0; - - canvas = GNOMECC_CANVAS (widget); - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - count = 0; - - for (i = 0; i < priv->info->n_categories; i++) - count += priv->info->categories[i]->n_entries; - - return count; -} - -static ControlCenterEntry* -gnomecc_canvas_accessible_get_entry (GnomeccCanvas *canvas, gint index) -{ - GnomeccCanvasPrivate *priv; - gint i, count; - - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - count = 0; - - for (i = 0; i < priv->info->n_categories; i++) { - if (index >= count && - index < count + priv->info->categories[i]->n_entries) { - return priv->info->categories[i]->entries[index - count]; - } else - count += priv->info->categories [i]->n_entries; - } - - return NULL; -} - -static AtkObject* -gnomecc_canvas_accessible_ref_child (AtkObject *accessible, gint index) -{ - GnomeccCanvasItemAccessible *item; - ControlCenterEntry *entry; - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - GtkWidget *widget; - AtkObject *object; - - widget = GTK_ACCESSIBLE (accessible)->widget; - - if (!widget) - return NULL; - - canvas = GNOMECC_CANVAS (widget); - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - entry = gnomecc_canvas_accessible_get_entry (canvas, index); - - if (!entry) - return NULL; - - object = g_hash_table_lookup (priv->accessible_children, &index); - - if (!object) { - object = g_object_new (gnomecc_canvas_item_accessible_get_type (), NULL); - item = (GnomeccCanvasItemAccessible *) object; - - object->role = ATK_ROLE_ICON; - item->entry = entry; - - g_hash_table_insert (priv->accessible_children, - &((EntryInfo *) entry->user_data)->index, object); - } - - return g_object_ref (object); -} - -static void -gnomecc_canvas_accessible_initialize (AtkObject *accessible, gpointer data) -{ - if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize) - ATK_OBJECT_CLASS (accessible_parent_class)->initialize (accessible, data); - - accessible->role = ATK_ROLE_LAYERED_PANE; -} - -static void -gnomecc_canvas_accessible_class_init (AtkObjectClass *class) -{ - GObjectClass *object_class; - GtkAccessibleClass *accessible_class; - - accessible_parent_class = g_type_class_peek_parent (class); - - object_class = (GObjectClass *)class; - accessible_class = (GtkAccessibleClass *)class; - - class->get_n_children = gnomecc_canvas_accessible_get_n_children; - class->ref_child = gnomecc_canvas_accessible_ref_child; - class->initialize = gnomecc_canvas_accessible_initialize; -} - -static gboolean -gnomecc_canvas_accessible_add_selection (AtkSelection *selection, gint i) -{ - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - GtkWidget *widget; - ControlCenterEntry *entry; - - widget = GTK_ACCESSIBLE (selection)->widget; - - if (!widget) - return FALSE; - - canvas = GNOMECC_CANVAS (widget); - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - entry = gnomecc_canvas_accessible_get_entry (canvas, i); - select_entry (canvas, entry); - - return TRUE; -} - -static gboolean -gnomecc_canvas_accessible_clear_selection (AtkSelection *selection) -{ - GnomeccCanvas *canvas; - GtkWidget *widget; - - widget = GTK_ACCESSIBLE (selection)->widget; - - if (!widget) - return FALSE; - - canvas = GNOMECC_CANVAS (widget); - select_entry (canvas, NULL); - - return TRUE; -} - -static AtkObject* -gnomecc_canvas_accessible_ref_selection (AtkSelection *selection, gint i) -{ - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - GtkWidget *widget; - - widget = GTK_ACCESSIBLE (selection)->widget; - - if (!widget) - return NULL; - - canvas = GNOMECC_CANVAS (widget); - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - if (priv->selected) - return atk_object_ref_accessible_child (gtk_widget_get_accessible (widget), - ((EntryInfo *)priv->selected->user_data)->index); - return NULL; -} - -static gint -gnomecc_canvas_accessible_get_selection_count (AtkSelection *selection) -{ - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - GtkWidget *widget; - - widget = GTK_ACCESSIBLE (selection)->widget; - - if (!widget) - return 0; - - canvas = GNOMECC_CANVAS (widget); - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - return (priv->selected) ? 1 : 0; -} - -static gboolean -gnomecc_canvas_accessible_is_child_selected (AtkSelection *selection, gint i) -{ - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - GtkWidget *widget; - - widget = GTK_ACCESSIBLE (selection)->widget; - - if (!widget) - return FALSE; - - canvas = GNOMECC_CANVAS (widget); - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - return (priv->selected == gnomecc_canvas_accessible_get_entry (canvas, i)); -} - -static gboolean -gnomecc_canvas_accessible_remove_selection (AtkSelection *selection, gint i) -{ - /* There can be only one item selected */ - return gnomecc_canvas_accessible_clear_selection (selection); -} - -static gboolean -gnomecc_canvas_accessible_select_all_selection (AtkSelection *selection) -{ - /* This can't happen */ - return FALSE; -} - -static void -gnomecc_canvas_accessible_selection_interface_init (AtkSelectionIface *iface) -{ - iface->add_selection = gnomecc_canvas_accessible_add_selection; - iface->clear_selection = gnomecc_canvas_accessible_clear_selection; - iface->ref_selection = gnomecc_canvas_accessible_ref_selection; - iface->get_selection_count = gnomecc_canvas_accessible_get_selection_count; - iface->is_child_selected = gnomecc_canvas_accessible_is_child_selected; - iface->remove_selection = gnomecc_canvas_accessible_remove_selection; - iface->select_all_selection = gnomecc_canvas_accessible_select_all_selection; -} - -static AtkObject* -gnomecc_canvas_accessible_ref_accessible_at_point (AtkComponent *component, - gint x, - gint y, - AtkCoordType coord_type) -{ - GtkWidget *widget; - GnomeccCanvasPrivate *priv; - GnomeccCanvas *canvas; - EntryInfo *entry; - gint x_pos, y_pos, x_w, y_w; - gint i, j; - - widget = GTK_ACCESSIBLE (component)->widget; - - if (widget == NULL) - return NULL; - - canvas = GNOMECC_CANVAS (widget); - priv = GNOMECC_CANVAS_GET_PRIVATE (canvas); - - atk_component_get_extents (component, &x_pos, &y_pos, NULL, NULL, coord_type); - x_w = x - x_pos; - y_w = y - y_pos; - - for (i = 0; i < priv->info->n_categories; i++) { - for (j = 0; j < priv->info->categories[i]->n_entries; j++) { - entry = (EntryInfo *) priv->info->categories[i]->entries[j]; - - if (x_w > entry->cover->x1 && - x_w < entry->cover->x2 && - y_w > entry->cover->y1 && - y_w < entry->cover->y2) - return gnomecc_canvas_accessible_ref_child (ATK_OBJECT (component), entry->index); - } - } - - return NULL; -} - -static void -atk_component_interface_init (AtkComponentIface *iface) -{ - iface->ref_accessible_at_point = gnomecc_canvas_accessible_ref_accessible_at_point; -} - -static GType -gnomecc_canvas_accessible_get_type (void) -{ - static GType type = 0; - AtkObjectFactory *factory; - GType derived_type; - GTypeQuery query; - GType derived_atk_type; - - if (type == 0) { - static GTypeInfo info = { - 0, /* class size */ - (GBaseInitFunc) NULL, /* base init */ - (GBaseFinalizeFunc) NULL, /* base finalize */ - (GClassInitFunc) gnomecc_canvas_accessible_class_init, - (GClassFinalizeFunc) NULL, /* class finalize */ - NULL, /* class data */ - 0, /* instance size */ - 0, /* nb preallocs */ - (GInstanceInitFunc) NULL, /* instance init */ - NULL /* value table */ - }; - - static const GInterfaceInfo atk_component_info = { - (GInterfaceInitFunc) atk_component_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - static const GInterfaceInfo atk_selection_info = { - (GInterfaceInitFunc) gnomecc_canvas_accessible_selection_interface_init, - (GInterfaceFinalizeFunc) NULL, - NULL - }; - - derived_type = g_type_parent (GNOMECC_TYPE_CANVAS); - factory = atk_registry_get_factory (atk_get_default_registry (), - derived_type); - - derived_atk_type = atk_object_factory_get_accessible_type (factory); - g_type_query (derived_atk_type, &query); - - info.class_size = query.class_size; - info.instance_size = query.instance_size; - - type = g_type_register_static (derived_atk_type, - "GnomeccCanvasAccessible", - &info, 0); - - g_type_add_interface_static (type, - ATK_TYPE_COMPONENT, - &atk_component_info); - g_type_add_interface_static (type, - ATK_TYPE_SELECTION, - &atk_selection_info); - } - - return type; -} - -static AtkObject* -gnomecc_canvas_accessible_new (GObject *object) -{ - AtkObject *accessible; - - accessible = g_object_new (gnomecc_canvas_accessible_get_type (), NULL); - atk_object_initialize (accessible, object); - - return accessible; -} - -static AtkObject* -gnomecc_canvas_accessible_factory_create_accessible (GObject *object) -{ - return gnomecc_canvas_accessible_new (object); -} - -static void -gnomecc_canvas_accessible_factory_class_init (AtkObjectFactoryClass *class) -{ - class->create_accessible = gnomecc_canvas_accessible_factory_create_accessible; - class->get_accessible_type = gnomecc_canvas_accessible_get_type; -} - -static GType -gnomecc_canvas_accessible_factory_get_type (void) -{ - static GType type = 0; - - if (type == 0) { - static const GTypeInfo info = { - sizeof (AtkObjectFactoryClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gnomecc_canvas_accessible_factory_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (AtkObjectFactory), - 0, /* n_preallocs */ - NULL, NULL - }; - - type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, - "GnomeccCanvasAccessibleFactory", - &info, 0); - } - - return type; -} - -static AtkObject* -gnomecc_canvas_get_accessible (GtkWidget *widget) -{ - static gboolean already_here = FALSE; - - if (!already_here) { - AtkObjectFactory *factory; - AtkRegistry *registry; - GType derived_type; - GType derived_atk_type; - - already_here = TRUE; - - derived_type = g_type_parent (GNOMECC_TYPE_CANVAS); - - registry = atk_get_default_registry (); - factory = atk_registry_get_factory (registry, derived_type); - - derived_atk_type = atk_object_factory_get_accessible_type (factory); - - if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE)) { - atk_registry_set_factory_type (registry, - GNOMECC_TYPE_CANVAS, - gnomecc_canvas_accessible_factory_get_type ()); - } - } - - return (* GTK_WIDGET_CLASS (gnomecc_canvas_parent_class)->get_accessible) (widget); -} |