diff options
author | Dave Camp <dave@ximian.com> | 2002-08-14 21:55:01 +0000 |
---|---|---|
committer | Dave Camp <campd@src.gnome.org> | 2002-08-14 21:55:01 +0000 |
commit | b373e215dd85409a7f524006d872283fad38c0e9 (patch) | |
tree | 11eb7932555d5ddf8c1b41177944b82d556c09d1 /libnautilus-private | |
parent | 527fa64843a32cfc48d573915919088dd649a102 (diff) | |
download | nautilus-b373e215dd85409a7f524006d872283fad38c0e9.tar.gz |
Install a frame_text gtk style property, so that accessible themes can
2002-08-14 Dave Camp <dave@ximian.com>
* libnautilus-private/nautilus-icon-container.c:
(nautilus_icon_container_class_init): Install a frame_text gtk
style property, so that accessible themes can force the icon
container to put a frame around unselected text.
(setup_label_gcs): Use text[SELECTED] for the highlight text
color, since it is now displayed against base[SELECTED]. If
frame_text is set, use text[NORMAL] for normal text, since it will
be displayed against base[NORMAL].
(nautilus_icon_container_set_use_drop_shadows): If frame_text is
set, don't enable drop shadows, but save that they were requested.
(style_set): Update use_drop_shadows based on whether frame_text
is set and whether drop shadows were requested.
(nautilus_icon_container_theme_changed): Call setup_label_gcs().
* libnautilus-private/nautilus-icon-canvas-item.c: (draw_frame):
New function.
(draw_or_measure_label_text): Rearranged for clarity, make it work
when it is called for draw without being called for measure (ugh).
Fixed a PangoLayout leak. If frame_text is set on the icon
container, draw a background rectangle.
(draw_label_layout): Don't drop shadow selected text. Drawing
with text[SELECTED] on base[SELECTED] should look just fine
without a drop shadow.
* libnautilus-private/nautilus-icon-private.h: Added a
drop_shadow_requested member.
Diffstat (limited to 'libnautilus-private')
-rw-r--r-- | libnautilus-private/nautilus-icon-canvas-item.c | 286 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-container.c | 77 | ||||
-rw-r--r-- | libnautilus-private/nautilus-icon-private.h | 1 |
3 files changed, 219 insertions, 145 deletions
diff --git a/libnautilus-private/nautilus-icon-canvas-item.c b/libnautilus-private/nautilus-icon-canvas-item.c index e1bd8b441..b559b4eb8 100644 --- a/libnautilus-private/nautilus-icon-canvas-item.c +++ b/libnautilus-private/nautilus-icon-canvas-item.c @@ -631,8 +631,46 @@ multiply_pixbuf_rgba (GdkPixbuf *pixbuf, guint rgba) } } -/* Keep these for a bit while we work on performance of draw_or_measure_label_text. */ +static void +draw_frame (NautilusIconCanvasItem *item, + GdkDrawable *drawable, + guint color, + int x, + int y, + int width, + int height) +{ + GdkPixbuf *selection_pixbuf; + NautilusIconContainer *container; + container = NAUTILUS_ICON_CONTAINER (GNOME_CANVAS_ITEM (item)->canvas); + + if (ANTIALIAS_SELECTION_RECTANGLE) { + selection_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, + TRUE, + 8, + width, + height); + eel_gdk_pixbuf_fill_rectangle_with_color (selection_pixbuf, + eel_gdk_pixbuf_whole_pixbuf, + 0xffffffff); + clear_rounded_corners (selection_pixbuf, + container->details->highlight_frame, + 5); + multiply_pixbuf_rgba (selection_pixbuf, + color); + + draw_pixbuf (selection_pixbuf, drawable, x, y); + g_object_unref (selection_pixbuf); + } else { + gdk_draw_rectangle + (drawable, + GTK_WIDGET (container)->style->black_gc, TRUE, + x, y, width, height); + } +} + +/* Keep these for a bit while we work on performance of draw_or_measure_label_text. */ /* #define PERFORMANCE_TEST_DRAW_DISABLE #define PERFORMANCE_TEST_MEASURE_DISABLE @@ -646,14 +684,14 @@ draw_or_measure_label_text (NautilusIconCanvasItem *item, { NautilusIconCanvasItemDetails *details; NautilusIconContainer *container; - guint width_so_far, height_so_far; + guint editable_height, editable_width; + guint additional_height, additional_width; GnomeCanvasItem *canvas_item; - GdkPixbuf *selection_pixbuf; - PangoLayout *layout; + PangoLayout *editable_layout; + PangoLayout *additional_layout; GdkColor *label_color; - int layout_width, layout_height; int icon_width; - gboolean have_editable, have_additional, needs_highlight; + gboolean have_editable, have_additional, needs_highlight, needs_frame; int max_text_width, box_left; GdkGC *gc; @@ -700,126 +738,128 @@ draw_or_measure_label_text (NautilusIconCanvasItem *item, icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf); } - width_so_far = 0; - height_so_far = 0; + editable_width = 0; + editable_height = 0; + additional_width = 0; + additional_height = 0; max_text_width = floor (nautilus_icon_canvas_item_get_max_text_width (item)); container = NAUTILUS_ICON_CONTAINER (GNOME_CANVAS_ITEM (item)->canvas); - - /* if the icon is highlighted, do some set-up */ - if (needs_highlight && drawable != NULL && !details->is_renaming && - details->text_width > 0 && details->text_height > 0) { - if (ANTIALIAS_SELECTION_RECTANGLE) { - selection_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - TRUE, - 8, - details->text_width, - details->text_height); - eel_gdk_pixbuf_fill_rectangle_with_color (selection_pixbuf, - eel_gdk_pixbuf_whole_pixbuf, - 0xffffffff); - /* container->details->highlight_color_rgba); */ - clear_rounded_corners (selection_pixbuf, - container->details->highlight_frame, - 5); - multiply_pixbuf_rgba (selection_pixbuf, - container->details->highlight_color_rgba); - draw_pixbuf (selection_pixbuf, drawable, - icon_left + (icon_width - details->text_width) / 2, - icon_bottom); - g_object_unref (selection_pixbuf); - } else { - gdk_draw_rectangle - (drawable, GTK_WIDGET (container)->style->black_gc, TRUE, - icon_left + (icon_width - details->text_width) / 2, - icon_bottom, - details->text_width, details->text_height); - } - - } + editable_layout = NULL; + additional_layout = NULL; if (have_editable) { - layout = get_label_layout (&details->editable_text_layout, item, details->editable_text); - - if (drawable != NULL) { - gc = nautilus_icon_container_get_label_color_and_gc - (NAUTILUS_ICON_CONTAINER (canvas_item->canvas), - &label_color, TRUE, needs_highlight); - - draw_label_layout (item, drawable, - layout, needs_highlight, - label_color, - icon_left + (icon_width - max_text_width) / 2, - icon_bottom, gc); - } + editable_layout = get_label_layout (&details->editable_text_layout, item, details->editable_text); - pango_layout_get_pixel_size (layout, &layout_width, &layout_height); - - width_so_far = MAX (width_so_far, (guint) layout_width); - height_so_far += layout_height + LABEL_LINE_SPACING; - - g_object_unref (layout); + pango_layout_get_pixel_size (editable_layout, + &editable_width, + &editable_height); } - + if (have_additional) { - layout = get_label_layout (&details->additional_text_layout, item, details->additional_text); - - if (drawable != NULL) { - gc = nautilus_icon_container_get_label_color_and_gc - (NAUTILUS_ICON_CONTAINER (canvas_item->canvas), - &label_color, FALSE, needs_highlight); - - draw_label_layout (item, drawable, - layout, needs_highlight, - label_color, - icon_left + (icon_width - max_text_width) / 2, - icon_bottom + height_so_far, gc); - } - - pango_layout_get_pixel_size (layout, &layout_width, &layout_height); + additional_layout = get_label_layout (&details->additional_text_layout, item, details->additional_text); - width_so_far = MAX (width_so_far, (guint) layout_width); - height_so_far += layout_height + LABEL_LINE_SPACING; + pango_layout_get_pixel_size (additional_layout, + &additional_width, + &additional_height); } - + + details->text_width = MAX (editable_width, additional_width); + details->text_height = editable_height + LABEL_LINE_SPACING + additional_height; + if (ANTIALIAS_SELECTION_RECTANGLE) { /* add some extra space for highlighting even when we don't highlight so things won't move */ - height_so_far += 2; /* extra slop for nicer highlighting */ - width_so_far += 8; /* account for emboldening, plus extra to make it look nicer */ + details->text_height += 2; /* extra slop for nicer highlighting */ + details->text_width += 8; /* extra to make it look nicer */ } else { /* add slop used for highlighting, even if we're not highlighting now */ - width_so_far += 4; + details->text_width += 4; } - if (drawable != NULL) { - /* Current calculations should match what we measured before drawing. - * This assumes that we will always make a separate call to measure - * before the call to draw. We might later decide to use this function - * differently and change these asserts. - */ -#if (defined PERFORMANCE_TEST_MEASURE_DISABLE || defined PERFORMANCE_TEST_DRAW_DISABLE) - g_assert ((int) height_so_far == details->text_height); - g_assert ((int) width_so_far == details->text_width); -#endif - box_left = icon_left + (icon_width - details->text_width) / 2; - - if (item->details->is_highlighted_as_keyboard_focus) { - gtk_paint_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas)->style, - drawable, - needs_highlight ? GTK_STATE_SELECTED : GTK_STATE_NORMAL, - NULL, - GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas), - "icon-container", - box_left, - icon_bottom, - details->text_width, - details->text_height); + /* if measuring, we are done */ + if (!drawable) { + if (editable_layout) { + g_object_unref (editable_layout); } - } else { - /* If measuring, remember the width & height. */ - details->text_width = width_so_far; - details->text_height = height_so_far; + + if (additional_layout) { + g_object_unref (additional_layout); + } + + return; + } + + /* if the icon is highlighted, do some set-up */ + if (needs_highlight && !details->is_renaming && + details->text_width > 0 && details->text_height > 0) { + draw_frame (item, + drawable, + container->details->highlight_color_rgba, + icon_left + (icon_width - details->text_width) / 2, + icon_bottom, + details->text_width, + details->text_height); + } + + if (have_editable) { + gtk_widget_style_get (GTK_WIDGET (container), + "frame_text", &needs_frame, + NULL); + if (needs_frame && !needs_highlight && details->text_width > 0 && details->text_height > 0) { + draw_frame (item, + drawable, + eel_gdk_color_to_rgb (>K_WIDGET (container)->style->base[GTK_STATE_NORMAL]), + icon_left + (icon_width - details->text_width) / 2, + icon_bottom, + details->text_width, + details->text_height); + } + + gc = nautilus_icon_container_get_label_color_and_gc + (NAUTILUS_ICON_CONTAINER (canvas_item->canvas), + &label_color, TRUE, needs_highlight); + + draw_label_layout (item, drawable, + editable_layout, needs_highlight, + label_color, + icon_left + (icon_width - max_text_width) / 2, + icon_bottom, gc); + } + + if (have_additional) { + gc = nautilus_icon_container_get_label_color_and_gc + (NAUTILUS_ICON_CONTAINER (canvas_item->canvas), + &label_color, FALSE, needs_highlight); + + draw_label_layout (item, drawable, + additional_layout, needs_highlight, + label_color, + icon_left + (icon_width - max_text_width) / 2, + icon_bottom + editable_height + LABEL_LINE_SPACING, gc); + } + + box_left = icon_left + (icon_width - details->text_width) / 2; + + if (item->details->is_highlighted_as_keyboard_focus) { + gtk_paint_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas)->style, + drawable, + needs_highlight ? GTK_STATE_SELECTED : GTK_STATE_NORMAL, + NULL, + GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas), + "icon-container", + box_left, + icon_bottom, + details->text_width, + details->text_height); + } + + if (editable_layout) { + g_object_unref (editable_layout); + } + + if (additional_layout) { + g_object_unref (additional_layout); } } @@ -1268,33 +1308,17 @@ draw_label_layout (NautilusIconCanvasItem *item, return; } - if (!highlight || !ANTIALIAS_SELECTION_RECTANGLE) { - if (NAUTILUS_ICON_CONTAINER (GNOME_CANVAS_ITEM (item)->canvas)->details->use_drop_shadows) { - /* draw a drop shadow */ - eel_gdk_draw_layout_with_drop_shadow (drawable, gc, - label_color, - >K_WIDGET (GNOME_CANVAS_ITEM (item)->canvas)->style->black, - x, y, - layout); - } else { - gdk_draw_layout (drawable, gc, - x, y, - layout); - } + if (!highlight && (NAUTILUS_ICON_CONTAINER (GNOME_CANVAS_ITEM (item)->canvas)->details->use_drop_shadows)) { + /* draw a drop shadow */ + eel_gdk_draw_layout_with_drop_shadow (drawable, gc, + label_color, + >K_WIDGET (GNOME_CANVAS_ITEM (item)->canvas)->style->black, + x, y, + layout); } else { - /* draw a shadow in black */ - gdk_draw_layout (drawable, - GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas)->style->black_gc, - x + 2, y + 1, - layout); - - /* draw smeared-wide text to "embolden" */ gdk_draw_layout (drawable, gc, x, y, layout); - gdk_draw_layout (drawable, gc, - x+1, y, - layout); } } diff --git a/libnautilus-private/nautilus-icon-container.c b/libnautilus-private/nautilus-icon-container.c index 9382da64e..842f948f3 100644 --- a/libnautilus-private/nautilus-icon-container.c +++ b/libnautilus-private/nautilus-icon-container.c @@ -2433,11 +2433,19 @@ style_set (GtkWidget *widget, GtkStyle *previous_style) { NautilusIconContainer *container; + gboolean frame_text; + + container = NAUTILUS_ICON_CONTAINER (widget); + + gtk_widget_style_get (GTK_WIDGET (container), + "frame_text", &frame_text, + NULL); + + container->details->use_drop_shadows = container->details->drop_shadows_requested && !frame_text; - nautilus_icon_container_theme_changed (NAUTILUS_ICON_CONTAINER (widget)); + nautilus_icon_container_theme_changed (NAUTILUS_ICON_CONTAINER (widget)); if (GTK_WIDGET_REALIZED (widget)) { - container = NAUTILUS_ICON_CONTAINER (widget); invalidate_label_sizes (container); nautilus_icon_container_request_update_all (container); } @@ -3381,6 +3389,13 @@ nautilus_icon_container_class_init (NautilusIconContainerClass *class) eel_preferences_add_auto_enum (NAUTILUS_PREFERENCES_CLICK_POLICY, &click_policy_auto_value); + + gtk_widget_class_install_style_property (widget_class, + g_param_spec_boolean ("frame_text", + _("Frame Text"), + _("Draw a frame around unselected text"), + FALSE, + G_PARAM_READABLE)); } static gboolean @@ -5089,12 +5104,16 @@ static void setup_label_gcs (NautilusIconContainer *container) { EelBackground *background; + GtkWidget *widget; char *light_info_color, *dark_info_color; - uint light_info_value, dark_info_value; - + guint light_info_value, dark_info_value; + gboolean frame_text; + if (!GTK_WIDGET_REALIZED (container)) return; + widget = GTK_WIDGET (container); + g_assert (NAUTILUS_IS_ICON_CONTAINER (container)); background = eel_get_widget_background (GTK_WIDGET (container)); @@ -5119,15 +5138,36 @@ setup_label_gcs (NautilusIconContainer *container) g_free (dark_info_color); } - setup_gc_with_fg (container, LABEL_COLOR_HIGHLIGHT, 0xFFFFFF); - setup_gc_with_fg (container, LABEL_INFO_COLOR_HIGHLIGHT, 0xCCCCCC); + setup_gc_with_fg (container, LABEL_COLOR_HIGHLIGHT, eel_gdk_color_to_rgb (&widget->style->text[GTK_STATE_SELECTED])); + setup_gc_with_fg (container, + LABEL_INFO_COLOR_HIGHLIGHT, + eel_gdk_color_is_dark (&widget->style->base[GTK_STATE_SELECTED]) ? light_info_value : dark_info_value); - if (container->details->use_drop_shadows || eel_background_is_dark (background)) { - setup_gc_with_fg (container, LABEL_COLOR, 0xEFEFEF); - setup_gc_with_fg (container, LABEL_INFO_COLOR, light_info_value); - } else { /* converse */ - setup_gc_with_fg (container, LABEL_COLOR, 0x000000); - setup_gc_with_fg (container, LABEL_INFO_COLOR, dark_info_value); + /* If NautilusIconContainer::frame_text is set, we can safely + * use the foreground color from the theme, because it will + * always be displayed against the gtk background */ + gtk_widget_style_get (widget, + "frame_text", &frame_text, + NULL); + + if (frame_text) { + setup_gc_with_fg (container, LABEL_COLOR, + eel_gdk_color_to_rgb (&widget->style->text[GTK_STATE_NORMAL])); + setup_gc_with_fg (container, + LABEL_INFO_COLOR, + eel_gdk_color_is_dark (&widget->style->base[GTK_STATE_NORMAL]) ? light_info_value : dark_info_value); + } else { + if (container->details->use_drop_shadows || eel_background_is_dark (background)) { + setup_gc_with_fg (container, LABEL_COLOR, 0xEFEFEF); + setup_gc_with_fg (container, + LABEL_INFO_COLOR, + light_info_value); + } else { /* converse */ + setup_gc_with_fg (container, LABEL_COLOR, 0x000000); + setup_gc_with_fg (container, + LABEL_INFO_COLOR, + dark_info_value); + } } } @@ -5182,11 +5222,18 @@ void nautilus_icon_container_set_use_drop_shadows (NautilusIconContainer *container, gboolean use_drop_shadows) { - if (container->details->use_drop_shadows == use_drop_shadows) { + gboolean frame_text; + + gtk_widget_style_get (GTK_WIDGET (container), + "frame_text", &frame_text, + NULL); + + if (container->details->drop_shadows_requested == use_drop_shadows) { return; } - container->details->use_drop_shadows = use_drop_shadows; + container->details->drop_shadows_requested = use_drop_shadows; + container->details->use_drop_shadows = use_drop_shadows && !frame_text; gtk_widget_queue_draw (GTK_WIDGET (container)); } @@ -5231,6 +5278,8 @@ nautilus_icon_container_theme_changed (gpointer user_data) } container->details->highlight_color = eel_gdk_rgb_to_color ( container->details->highlight_color_rgba); + + setup_label_gcs (container); } void diff --git a/libnautilus-private/nautilus-icon-private.h b/libnautilus-private/nautilus-icon-private.h index b3073a3a4..efad28272 100644 --- a/libnautilus-private/nautilus-icon-private.h +++ b/libnautilus-private/nautilus-icon-private.h @@ -224,6 +224,7 @@ struct NautilusIconContainerDetails { /* Whether we should use drop shadows for the icon labels or not */ gboolean use_drop_shadows; + gboolean drop_shadows_requested; }; /* Private functions shared by mutiple files. */ |