static void gtk_boolean_cell_accessible_update_cache (GtkCellAccessible *cell) { GtkBooleanCellAccessible *boolean_cell = GTK_BOOLEAN_CELL_ACCESSIBLE (cell); gboolean active; gboolean sensitive; g_object_get (G_OBJECT (GTK_RENDERER_CELL_ACCESSIBLE (cell)->renderer), "active", &active, "sensitive", &sensitive, NULL); if (boolean_cell->cell_value != active) { boolean_cell->cell_value = !boolean_cell->cell_value; atk_object_notify_state_change (ATK_OBJECT (cell), ATK_STATE_CHECKED, active); } if (boolean_cell->cell_sensitive != sensitive) { boolean_cell->cell_sensitive = !boolean_cell->cell_sensitive; atk_object_notify_state_change (ATK_OBJECT (cell), ATK_STATE_CHECKED, sensitive); } }
static void gtk_text_cell_accessible_update_cache (GtkCellAccessible *cell) { GtkTextCellAccessible *text_cell = GTK_TEXT_CELL_ACCESSIBLE (cell); AtkObject *obj = ATK_OBJECT (cell); gboolean rv = FALSE; gint temp_length; gchar *text; g_object_get (G_OBJECT (GTK_RENDERER_CELL_ACCESSIBLE (cell)->renderer), "text", &text, NULL); if (text_cell->cell_text) { if (text == NULL || g_strcmp0 (text_cell->cell_text, text) != 0) { g_free (text_cell->cell_text); temp_length = text_cell->cell_length; text_cell->cell_text = NULL; text_cell->cell_length = 0; g_signal_emit_by_name (cell, "text-changed::delete", 0, temp_length); if (obj->name == NULL) g_object_notify (G_OBJECT (obj), "accessible-name"); if (text) rv = TRUE; } } else rv = TRUE; if (rv) { if (text == NULL) { text_cell->cell_text = g_strdup (""); text_cell->cell_length = 0; } else { text_cell->cell_text = g_strdup (text); text_cell->cell_length = g_utf8_strlen (text, -1); } } g_free (text); if (rv) { g_signal_emit_by_name (cell, "text-changed::insert", 0, text_cell->cell_length); if (obj->name == NULL) g_object_notify (G_OBJECT (obj), "accessible-name"); } }
static gint gtk_text_cell_accessible_get_offset_at_point (AtkText *text, gint x, gint y, AtkCoordType coords) { AtkObject *parent; GtkRendererCellAccessible *gail_renderer; GtkCellRendererText *gtk_renderer; GtkRequisition min_size; GtkWidget *widget; GdkRectangle rendered_rect; PangoLayout *layout; gchar *renderer_text; gfloat xalign, yalign; gint x_offset, y_offset, index; gint xpad, ypad; gint x_window, y_window, x_toplevel, y_toplevel; gint x_temp, y_temp; gboolean ret; if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text) return -1; gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text); gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer); parent = atk_object_get_parent (ATK_OBJECT (text)); g_object_get (gtk_renderer, "text", &renderer_text, NULL); if (text == NULL) { g_free (renderer_text); return -1; } if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent)) parent = atk_object_get_parent (parent); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)); g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent), -1); _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent), GTK_CELL_ACCESSIBLE (text), &rendered_rect); gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer), widget, &min_size, NULL); gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) xalign = 1.0 - xalign; x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width)); y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height)); layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text)); gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad); get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel); x_temp = x - (x_offset + rendered_rect.x + xpad) - x_window; y_temp = y - (y_offset + rendered_rect.y + ypad) - y_window; if (coords == ATK_XY_WINDOW) { x_temp += x_toplevel; y_temp += y_toplevel; } else if (coords != ATK_XY_SCREEN) index = -1; ret = pango_layout_xy_to_index (layout, x_temp * PANGO_SCALE, y_temp * PANGO_SCALE, &index, NULL); if (!ret) { if (x_temp < 0 || y_temp < 0) index = 0; else index = -1; } g_object_unref (layout); if (index == -1) { if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN) { glong length; length = g_utf8_strlen (renderer_text, -1); g_free (renderer_text); return length; } g_free (renderer_text); return index; } else { glong offset; offset = g_utf8_pointer_to_offset (renderer_text, renderer_text + index); g_free (renderer_text); return offset; } }
static void gtk_text_cell_accessible_get_character_extents (AtkText *text, gint offset, gint *x, gint *y, gint *width, gint *height, AtkCoordType coords) { GtkRendererCellAccessible *gail_renderer; GtkRequisition min_size; GtkCellRendererText *gtk_renderer; GdkRectangle rendered_rect; GtkWidget *widget; AtkObject *parent; PangoRectangle char_rect; PangoLayout *layout; gchar *renderer_text; gfloat xalign, yalign; gint x_offset, y_offset, index; gint xpad, ypad; gint x_window, y_window, x_toplevel, y_toplevel; if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text) { *x = *y = *height = *width = 0; return; } if (offset < 0 || offset >= GTK_TEXT_CELL_ACCESSIBLE (text)->cell_length) { *x = *y = *height = *width = 0; return; } gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text); gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer); g_object_get (gtk_renderer, "text", &renderer_text, NULL); if (text == NULL) { g_free (renderer_text); return; } parent = atk_object_get_parent (ATK_OBJECT (text)); if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent)) parent = atk_object_get_parent (parent); widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)); g_return_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent)); _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent), GTK_CELL_ACCESSIBLE (text), &rendered_rect); gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer), widget, &min_size, NULL); gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) xalign = 1.0 - xalign; x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width)); y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height)); layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text)); index = g_utf8_offset_to_pointer (renderer_text, offset) - renderer_text; pango_layout_index_to_pos (layout, index, &char_rect); gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad); get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel); *x = (char_rect.x / PANGO_SCALE) + x_offset + rendered_rect.x + xpad + x_window; *y = (char_rect.y / PANGO_SCALE) + y_offset + rendered_rect.y + ypad + y_window; *height = char_rect.height / PANGO_SCALE; *width = char_rect.width / PANGO_SCALE; if (coords == ATK_XY_WINDOW) { *x -= x_toplevel; *y -= y_toplevel; } else if (coords != ATK_XY_SCREEN) { *x = 0; *y = 0; *height = 0; *width = 0; } g_free (renderer_text); g_object_unref (layout); }
/* This function is used by gtk_text_cell_accessible_get_offset_at_point() * and gtk_text_cell_accessible_get_character_extents(). There is no * cached PangoLayout so we must create a temporary one using this function. */ static PangoLayout * create_pango_layout (GtkTextCellAccessible *text) { GdkRGBA *foreground_rgba; PangoAttrList *attr_list, *attributes; PangoLayout *layout; PangoUnderline uline, underline; PangoFontMask mask; PangoFontDescription *font_desc; gboolean foreground_set, strikethrough_set, strikethrough; gboolean scale_set, underline_set, rise_set; gchar *renderer_text; gdouble scale; gint rise; GtkRendererCellAccessible *gail_renderer; GtkCellRendererText *gtk_renderer; gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text); gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer); g_object_get (gtk_renderer, "text", &renderer_text, "attributes", &attributes, "foreground-set", &foreground_set, "foreground-rgba", &foreground_rgba, "strikethrough-set", &strikethrough_set, "strikethrough", &strikethrough, "font-desc", &font_desc, "scale-set", &scale_set, "scale", &scale, "underline-set", &underline_set, "underline", &underline, "rise-set", &rise_set, "rise", &rise, NULL); layout = gtk_widget_create_pango_layout (get_widget (text), renderer_text); if (attributes) attr_list = pango_attr_list_copy (attributes); else attr_list = pango_attr_list_new (); if (foreground_set) { add_attr (attr_list, pango_attr_foreground_new (foreground_rgba->red * 65535, foreground_rgba->green * 65535, foreground_rgba->blue * 65535)); } if (strikethrough_set) add_attr (attr_list, pango_attr_strikethrough_new (strikethrough)); mask = pango_font_description_get_set_fields (font_desc); if (mask & PANGO_FONT_MASK_FAMILY) add_attr (attr_list, pango_attr_family_new (pango_font_description_get_family (font_desc))); if (mask & PANGO_FONT_MASK_STYLE) add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (font_desc))); if (mask & PANGO_FONT_MASK_VARIANT) add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (font_desc))); if (mask & PANGO_FONT_MASK_WEIGHT) add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (font_desc))); if (mask & PANGO_FONT_MASK_STRETCH) add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (font_desc))); if (mask & PANGO_FONT_MASK_SIZE) add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (font_desc))); if (scale_set && scale != 1.0) add_attr (attr_list, pango_attr_scale_new (scale)); if (underline_set) uline = underline; else uline = PANGO_UNDERLINE_NONE; if (uline != PANGO_UNDERLINE_NONE) add_attr (attr_list, pango_attr_underline_new (underline)); if (rise_set) add_attr (attr_list, pango_attr_rise_new (rise)); pango_layout_set_attributes (layout, attr_list); pango_layout_set_width (layout, -1); pango_attr_list_unref (attr_list); pango_font_description_free (font_desc); pango_attr_list_unref (attributes); g_free (renderer_text); gdk_rgba_free (foreground_rgba); return layout; }