diff options
author | Darin Adler <darin@src.gnome.org> | 2000-01-10 19:52:24 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2000-01-10 19:52:24 +0000 |
commit | c912e1ef33afc6476e1653667581c8a076e6b1f6 (patch) | |
tree | 53f28d5833aeb1fdf1ef1dc6d101d5e1a76942bf | |
parent | c5864f0483a2e56adc33e8e9c80c47671fec47e0 (diff) | |
download | nautilus-c912e1ef33afc6476e1653667581c8a076e6b1f6.tar.gz |
Added NautilusBackground class, string functions that allow NULL, made
gradient functions allow NULL and treat it as an empty string, added
gdk_color_parse variants that have a default color, cleanup of
NautilusIndexPanel, and some other minor stuff.
52 files changed, 3181 insertions, 1122 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414 index 8cc67a9fa..e2fd316a1 100644 --- a/ChangeLog-20000414 +++ b/ChangeLog-20000414 @@ -1,3 +1,52 @@ +2000-01-10 Darin Adler <darin@eazel.com> + + * libnautilus/Makefile.am, libnautilus/nautilus-background.h, + libnautilus/nautilus-background.c, + libnautilus/nautilus-background-canvas-group.h, + libnautilus/nautilus-background-canvas-group.c, + libnautilus/nautilus-lib-self-check-functions.h, + libnautilus/nautilus-lib-self-check-functions.c: Added first cut + at a new class to manage backgrounds that can be colors, color + gradients, or tiled images. + + * libnautilus/Makefile.am, libnautilus/nautilus-string.h, + libnautilus/nautilus-string.c: Added functions that manipulate + strings that allow NULLs to reduce NULL checks in code that + treats NULL the same as an empty string. + + * libnautilus/gdk_extensions.c: (nautilus_gradient_new): + (nautilus_gradient_is_gradient): + (nautilus_gradient_is_horizontal): + (nautilus_gradient_strip_trailing_direction_if_any): + (nautilus_gradient_get_start_color_spec): + (nautilus_gradient_get_end_color_spec): + (nautilus_gradient_set_edge_color): Changed gradient functions to + allow NULL and treat it the same as an empty string. + + * libnautilus/gdk_extensions.h: libnautilus/gdk_extensions.c: + (nautilus_gdk_color_parse_with_default): + (nautilus_gdk_color_parse_with_white_default): Added alternate + version of gdk_color_parse that uses a default color instead of + just returning false. Added self-checks and updated some existing + self checks at the same time. + + * src/ntl-index-panel.h, src/ntl-index-panel.c: Wholesale + cleanup and reformatting of NautilusIndexPanel. Fixed a number of + bugs, including storage leaks, and took first step toward using + NautilusBackground class. + + * src/ntl-window.c: (nautilus_window_get_requested_uri): + Changed this so it works when window->ni is NULL. + + * src/ntl-window.h: Changed index_panel to be a NautilusIndexPanel + now that the index panel interface uses the class instead of using + GtkWidget everywhere. + + * src/file-manager/.cvsignore: Added *.la. + + * src/file-manager/fm-directory.c: Minor reformatting to match + GNOME code style better. + 2000-01-10 John Sullivan <sullivan@eazel.com> * src/ntl-index-panel.c: (nautilus_index_panel_set_up_label): diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am index 81e6a6b09..47c90e02d 100644 --- a/libnautilus-extensions/Makefile.am +++ b/libnautilus-extensions/Makefile.am @@ -22,10 +22,12 @@ libnautilusinclude_HEADERS= \ gtkflist.h \ gtkscrollframe.h \ nautilus.h \ + nautilus-background.h \ nautilus-file-utilities.h \ nautilus-gtk-extensions.h \ nautilus-lib-self-check-functions.h \ nautilus-self-checks.h \ + nautilus-string.h \ ntl-content-view-client.h \ ntl-meta-view-client.h \ ntl-view-client.h @@ -37,10 +39,13 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \ gnome-icon-container.c \ gtkflist.c \ gtkscrollframe.c \ + nautilus-background.c \ + nautilus-background-canvas-group.c \ nautilus-file-utilities.c \ nautilus-gtk-extensions.c \ nautilus-lib-self-check-functions.c \ nautilus-self-checks.c \ + nautilus-string.c \ ntl-content-view-client.c \ ntl-meta-view-client.c \ ntl-view-client.c \ diff --git a/libnautilus-extensions/gdk-extensions.c b/libnautilus-extensions/gdk-extensions.c index 8f145b5b6..e7f18e36e 100644 --- a/libnautilus-extensions/gdk-extensions.c +++ b/libnautilus-extensions/gdk-extensions.c @@ -29,8 +29,7 @@ #include "gdk-extensions.h" #include "nautilus-lib-self-check-functions.h" - -#include <string.h> +#include "nautilus-string.h" #define GRADIENT_BAND_SIZE 4 @@ -194,9 +193,9 @@ nautilus_gradient_new (const char *start_color, const char *end_color, gboolean is_horizontal) { - g_return_val_if_fail (start_color != NULL, g_strdup ("")); - g_return_val_if_fail (end_color != NULL, g_strdup ("")); - g_return_val_if_fail (is_horizontal == FALSE || is_horizontal == TRUE, g_strdup ("")); + g_return_val_if_fail (start_color != NULL, NULL); + g_return_val_if_fail (end_color != NULL, NULL); + g_return_val_if_fail (is_horizontal == FALSE || is_horizontal == TRUE, NULL); /* Handle the special case where the start and end colors are identical. Handle the special case where the end color is an empty string. @@ -221,9 +220,22 @@ nautilus_gradient_new (const char *start_color, gboolean nautilus_gradient_is_gradient (const char *gradient_spec) { - g_return_val_if_fail (gradient_spec != NULL, FALSE); + return nautilus_strchr (gradient_spec, '-') != NULL; +} + +/** + * nautilus_gradient_is_horizontal + * @gradient_spec: A gradient spec. string. + * + * Return true if the spec. specifies a horizontal gradient. + */ +gboolean +nautilus_gradient_is_horizontal (const char *gradient_spec) +{ + size_t length; - return strchr (gradient_spec, '-') != NULL; + length = nautilus_strlen (gradient_spec); + return length >= 2 && gradient_spec[length - 2] == ':' && gradient_spec[length - 1] == 'h'; } static char * @@ -231,9 +243,7 @@ nautilus_gradient_strip_trailing_direction_if_any (const char *gradient_spec) { size_t length; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - length = strlen (gradient_spec); + length = nautilus_strlen (gradient_spec); if (length >= 2 && gradient_spec[length - 2] == ':' && (gradient_spec[length - 1] == 'v' || gradient_spec[length - 1] == 'h')) length -= 2; @@ -253,9 +263,7 @@ nautilus_gradient_get_start_color_spec (const char *gradient_spec) { const char *separator; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - separator = strchr (gradient_spec, '-'); + separator = nautilus_strchr (gradient_spec, '-'); if (separator == NULL) return nautilus_gradient_strip_trailing_direction_if_any (gradient_spec); @@ -274,9 +282,7 @@ nautilus_gradient_get_end_color_spec (const char *gradient_spec) { const char *separator; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - separator = strchr (gradient_spec, '-'); + separator = nautilus_strchr (gradient_spec, '-'); return nautilus_gradient_strip_trailing_direction_if_any (separator != NULL ? separator + 1 : gradient_spec); } @@ -291,7 +297,6 @@ nautilus_gradient_set_edge_color (const char *gradient_spec, char *opposite_color; char *result; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); g_return_val_if_fail (edge_color != NULL, g_strdup (gradient_spec)); /* Get the color from the existing gradient spec. for the opposite @@ -374,11 +379,35 @@ nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, return nautilus_gradient_set_edge_color (gradient_spec, bottom_color, FALSE, TRUE); } +/** + * nautilus_gdk_color_parse_with_white_default + * @color_spec: A color spec. + * @color: Pointer to place to put resulting color. + * + * The same as gdk_color_parse, except sets the color to white if + * the spec. can't be parsed instead of returning a boolean flag. + */ +void +nautilus_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *color) +{ + if (!gdk_color_parse (color_spec, color)) { + color->red = 0xFFFF; + color->green = 0xFFFF; + color->blue = 0xFFFF; + } +} + #if ! defined (NAUTILUS_OMIT_SELF_CHECK) -#include <stdio.h> +static char * +nautilus_gdk_color_as_hex_string (GdkColor color) +{ + return g_strdup_printf("rgb:%04hX/%04hX/%04hX", + color.red, color.green, color.blue); +} -static GdkColor +static char * nautilus_self_check_interpolate (gdouble ratio, gushort r1, gushort g1, gushort b1, gushort r2, gushort g2, gushort b2) @@ -397,25 +426,30 @@ nautilus_self_check_interpolate (gdouble ratio, nautilus_interpolate_color (ratio, &start_color, &end_color, &interpolated_color); - return interpolated_color; + return nautilus_gdk_color_as_hex_string (interpolated_color); +} + +static char * +nautilus_self_check_parse (const char *color_spec) +{ + GdkColor color; + + nautilus_gdk_color_parse_with_white_default (color_spec, &color); + return nautilus_gdk_color_as_hex_string (color); } void nautilus_self_check_gdk_extensions (void) { /* nautilus_interpolate_color */ - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).red, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).green, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).blue, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0xFFFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0xFFFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0xFFFF); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0), + "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:7FFF/7FFF/7FFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:FFFF/FFFF/FFFF"); /* nautilus_fill_rectangle */ /* Make a GdkImage and fill it, maybe? */ @@ -503,6 +537,13 @@ nautilus_self_check_gdk_extensions (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a-c:v", "b"), "a-b"); NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a-c:v", "c"), "a-c"); NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a:-b:h", "d"), "a:-d"); + + /* nautilus_gdk_color_parse_with_white_default */ + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse (""), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("a"), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("white"), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("black"), "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("rgb:0123/4567/89AB"), "rgb:0123/4567/89AB"); } #endif /* ! NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus-extensions/gdk-extensions.h b/libnautilus-extensions/gdk-extensions.h index 8ecadf853..f5dd0c27b 100644 --- a/libnautilus-extensions/gdk-extensions.h +++ b/libnautilus-extensions/gdk-extensions.h @@ -32,44 +32,53 @@ The gradient is vertical by default and the spec. can end with ":v" to indicate that. If the gradient ends with ":h", the gradient is horizontal. */ -char * nautilus_gradient_new (const char *start_color, - const char *end_color, - gboolean is_horizontal); +char * nautilus_gradient_new (const char *start_color, + const char *end_color, + gboolean is_horizontal); -gboolean nautilus_gradient_is_gradient (const char *gradient_spec); -char * nautilus_gradient_get_start_color_spec (const char *gradient_spec); -char * nautilus_gradient_get_end_color_spec (const char *gradient_spec); -gboolean nautilus_gradient_is_horizontal (const char *gradient_spec); +gboolean nautilus_gradient_is_gradient (const char *gradient_spec); +char * nautilus_gradient_get_start_color_spec (const char *gradient_spec); +char * nautilus_gradient_get_end_color_spec (const char *gradient_spec); +gboolean nautilus_gradient_is_horizontal (const char *gradient_spec); -char * nautilus_gradient_set_left_color_spec (const char *gradient_spec, - const char *left_color); -char * nautilus_gradient_set_top_color_spec (const char *gradient_spec, - const char *top_color); -char * nautilus_gradient_set_right_color_spec (const char *gradient_spec, - const char *right_color); -char * nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, - const char *bottom_color); +char * nautilus_gradient_set_left_color_spec (const char *gradient_spec, + const char *left_color); +char * nautilus_gradient_set_top_color_spec (const char *gradient_spec, + const char *top_color); +char * nautilus_gradient_set_right_color_spec (const char *gradient_spec, + const char *right_color); +char * nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, + const char *bottom_color); -/* Fill routines that take GdkRectangle parameters instead of four coordinates. */ -void nautilus_fill_rectangle (GdkDrawable *drawable, - GdkGC *gc, - const GdkRectangle *rectangle); -void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, - GdkGC *gc, - const GdkRectangle *rectangle, - const GdkColor *color); -void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, - GdkGC *gc, - GdkColormap *colormap, - const GdkRectangle *rectangle, - const GdkColor *start_color, - const GdkColor *end_color, - gboolean horizontal_gradient); +/* A version of parse_color that substitutes a default color instead of returning + a boolean to indicate it cannot be parsed. +*/ +void nautilus_gdk_color_parse_with_default (const char *color_spec, + const GdkColor *default_color, + GdkColor *color); +void nautilus_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *color); + +/* Fill routines that take GdkRectangle parameters instead of four integers. */ +void nautilus_fill_rectangle (GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *rectangle); +void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *rectangle, + const GdkColor *color); +void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle, + const GdkColor *start_color, + const GdkColor *end_color, + gboolean horizontal_gradient); -/* A basic operation needed for drawing gradients is interpolating two colors.*/ -void nautilus_interpolate_color (gdouble ratio, - const GdkColor *start_color, - const GdkColor *end_color, - GdkColor *interpolated_color); +/* A basic operation we use for drawing gradients is interpolating two colors.*/ +void nautilus_interpolate_color (gdouble ratio, + const GdkColor *start_color, + const GdkColor *end_color, + GdkColor *interpolated_color); #endif /* GDK_EXTENSIONS_H */ diff --git a/libnautilus-extensions/nautilus-background-canvas-group.c b/libnautilus-extensions/nautilus-background-canvas-group.c new file mode 100644 index 000000000..d3cef3e2c --- /dev/null +++ b/libnautilus-extensions/nautilus-background-canvas-group.c @@ -0,0 +1,154 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.c: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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. + + Author: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-background-canvas-group.h" + +#include <libgnomeui/gnome-canvas.h> +#include "nautilus-background.h" +#include "nautilus-gtk-macros.h" + +static void nautilus_background_canvas_group_initialize_class (gpointer klass); +static void nautilus_background_canvas_group_initialize (gpointer object, gpointer klass); +static void nautilus_background_canvas_group_destroy (GtkObject *object); +static void nautilus_background_canvas_group_finalize (GtkObject *object); +static void nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable, + int x, int y, int width, int height); + +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusBackgroundCanvasGroup, nautilus_background_canvas_group, GNOME_TYPE_CANVAS_GROUP) + +static GtkObjectClass *parent_class; + +static void +nautilus_background_canvas_group_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + GnomeCanvasItemClass *canvas_item_class; + + object_class = GTK_OBJECT_CLASS (klass); + canvas_item_class = GNOME_CANVAS_ITEM_CLASS (klass); + parent_class = gtk_type_class (GNOME_TYPE_CANVAS_GROUP); + + object_class->destroy = nautilus_background_canvas_group_destroy; + object_class->finalize = nautilus_background_canvas_group_finalize; + + canvas_item_class->draw = nautilus_background_canvas_group_draw; +} + +static void +nautilus_background_canvas_group_initialize (gpointer object, gpointer klass) +{ +} + +static void +nautilus_background_canvas_group_destroy (GtkObject *object) +{ + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_background_canvas_group_finalize (GtkObject *object) +{ + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); +} + +static void +nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable, + int drawable_corner_x, int drawable_corner_y, + int drawable_width, int drawable_height) +{ + NautilusBackground *background; + + /* Draw the background. */ + background = nautilus_background_canvas_group_get_background + (NAUTILUS_BACKGROUND_CANVAS_GROUP (item)); + if (background != NULL) { + GdkGC *gc; + GdkColormap *colormap; + GdkRectangle rectangle; + + /* Create a new gc each time. + If this is a speed problem, we can create one and keep it around, + but it's a bit more complicated to ensure that it's always compatible + with whatever drawable is passed in to use. + */ + gc = gdk_gc_new (drawable); + + colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); + + /* The rectangle is the size of the entire viewed area of the canvas. + The corner is determined by the current scroll position of the + GtkLayout, and the size is determined by the current size of the widget. + Since 0,0 is the corner of the drawable, we need to offset the rectangle + so it's relative to the drawable's coordinates. + */ + rectangle.x = GTK_LAYOUT (item->canvas)->xoffset - drawable_corner_x; + rectangle.y = GTK_LAYOUT (item->canvas)->yoffset - drawable_corner_y; + rectangle.width = GTK_WIDGET (item->canvas)->allocation.width; + rectangle.height = GTK_WIDGET (item->canvas)->allocation.height; + + nautilus_background_draw (background, drawable, gc, colormap, &rectangle); + + gdk_gc_unref (gc); + } + + /* Call through to the GnomeCanvasGroup implementation, which will draw all + the canvas items. + */ + NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, draw, + (item, drawable, + drawable_corner_x, drawable_corner_y, + drawable_width, drawable_height)); +} + +NautilusBackground * +nautilus_background_canvas_group_get_background (NautilusBackgroundCanvasGroup *canvas_group) +{ + gpointer data; + + data = gtk_object_get_data (GTK_OBJECT (canvas_group), "nautilus_background"); + g_assert (data == NULL || NAUTILUS_IS_BACKGROUND (data)); + return data; +} + +void +nautilus_background_canvas_group_set_background (NautilusBackgroundCanvasGroup *canvas_group, + NautilusBackground *background) +{ + NautilusBackground *old_background; + + g_return_if_fail (NAUTILUS_IS_BACKGROUND_CANVAS_GROUP (canvas_group)); + g_return_if_fail (background == NULL || NAUTILUS_IS_BACKGROUND (background)); + + old_background = nautilus_background_canvas_group_get_background (canvas_group); + gtk_object_set_data (GTK_OBJECT (canvas_group), "nautilus_background", background); + + if (background != NULL) + gtk_object_ref (GTK_OBJECT (background)); + if (old_background != NULL) + gtk_object_unref (GTK_OBJECT (old_background)); +} diff --git a/libnautilus-extensions/nautilus-background-canvas-group.h b/libnautilus-extensions/nautilus-background-canvas-group.h new file mode 100644 index 000000000..b0449f786 --- /dev/null +++ b/libnautilus-extensions/nautilus-background-canvas-group.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background-canvas-group.h: Class used internally by + NautilusBackground to add a background to a canvas. + + Copyright (C) 2000 Eazel, Inc. + + 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: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_BACKGROUND_CANVAS_GROUP_H +#define NAUTILUS_BACKGROUND_CANVAS_GROUP_H + +#include "nautilus-background.h" + +/* A NautilusBackgroundCanvasGroup is used internally by NautilusBackground to change + the color of a canvas. The reason we have to change the class of a canvas group is + that the cleanest way to hook into the code that erases the canvas is to be the + root canvas group. But the canvas class creates the root object and doesn't allow + it to be destroyed, so we change the class of the root object in place. + + A future version of GnomeCanvas may allow a nicer way of hooking in to the code + that draws the background, and then we can get rid of this class. + + This class is private to NautilusBackground. +*/ + +typedef GnomeCanvasGroup NautilusBackgroundCanvasGroup; +typedef GnomeCanvasGroupClass NautilusBackgroundCanvasGroupClass; + +#define NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP \ + (nautilus_background_canvas_group_get_type ()) +#define NAUTILUS_BACKGROUND_CANVAS_GROUP(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP, NautilusBackgroundCanvasGroup)) +#define NAUTILUS_BACKGROUND_CANVAS_GROUP_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP, NautilusBackgroundCanvasGroupClass)) +#define NAUTILUS_IS_BACKGROUND_CANVAS_GROUP(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)) +#define NAUTILUS_IS_BACKGROUND_CANVAS_GROUP_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)) + +GtkType nautilus_background_canvas_group_get_type (void); +NautilusBackground *nautilus_background_canvas_group_get_background (NautilusBackgroundCanvasGroup *root); +void nautilus_background_canvas_group_set_background (NautilusBackgroundCanvasGroup *root, + NautilusBackground *background); + +#endif /* NAUTILUS_BACKGROUND_CANVAS_GROUP_H */ diff --git a/libnautilus-extensions/nautilus-background.c b/libnautilus-extensions/nautilus-background.c new file mode 100644 index 000000000..35afd8bc1 --- /dev/null +++ b/libnautilus-extensions/nautilus-background.c @@ -0,0 +1,202 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.c: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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. + + Author: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-background.h" + +#include <gtk/gtksignal.h> +#include "gdk-extensions.h" +#include "nautilus-background-canvas-group.h" +#include "nautilus-lib-self-check-functions.h" +#include "nautilus-gtk-macros.h" + +static void nautilus_background_initialize_class (gpointer klass); +static void nautilus_background_initialize (gpointer object, gpointer klass); +static void nautilus_background_destroy (GtkObject *object); +static void nautilus_background_finalize (GtkObject *object); + +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusBackground, nautilus_background, GTK_TYPE_OBJECT) + +enum { + CHANGED, + LAST_SIGNAL +}; + +static GtkObjectClass *parent_class; +static guint signals[LAST_SIGNAL]; + +struct _NautilusBackgroundDetails +{ + char *color; + char *tile_image_uri; +}; + +static void +nautilus_background_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (klass); + + parent_class = gtk_type_class (GTK_TYPE_OBJECT); + + signals[CHANGED] = + gtk_signal_new ("changed", + GTK_RUN_FIRST | GTK_RUN_NO_RECURSE, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusBackgroundClass, changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, + 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + + object_class->destroy = nautilus_background_destroy; + object_class->finalize = nautilus_background_finalize; +} + +static void +nautilus_background_initialize (gpointer object, gpointer klass) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND(object); + + background->details = g_new0 (NautilusBackgroundDetails, 1); +} + +static void +nautilus_background_destroy (GtkObject *object) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND (object); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_background_finalize (GtkObject *object) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND (object); + g_free (background->details); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); +} + +NautilusBackground * +nautilus_background_new (void) +{ + return NAUTILUS_BACKGROUND (gtk_type_new (NAUTILUS_TYPE_BACKGROUND)); +} + +void +nautilus_background_draw (NautilusBackground *background, + GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle) +{ + char *start_color_spec; + char *end_color_spec; + GdkColor start_color; + GdkColor end_color; + gboolean horizontal_gradient; + + start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color); + end_color_spec = nautilus_gradient_get_end_color_spec (background->details->color); + horizontal_gradient = nautilus_gradient_is_horizontal (background->details->color); + + nautilus_gdk_color_parse_with_white_default (start_color_spec, &start_color); + nautilus_gdk_color_parse_with_white_default (end_color_spec, &end_color); + + g_free (start_color_spec); + g_free (end_color_spec); + + nautilus_fill_rectangle_with_gradient (drawable, gc, colormap, rectangle, + &start_color, &end_color, horizontal_gradient); +} + +void +nautilus_background_set_color (NautilusBackground *background, + const char *color) +{ + g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + + g_free (background->details->color); + background->details->color = g_strdup (color); + + gtk_signal_emit (GTK_OBJECT (background), signals[CHANGED]); +} + +void +nautilus_background_attach_to_canvas (NautilusBackground *background, + GnomeCanvas *canvas) +{ + /* Since there's no signal to override in GnomeCanvas to control + drawing the background, we change the class of the canvas root. + This gives us a chance to draw the background before any of the + objects draw themselves, and has no effect on the bounds or + anything related to scrolling. + + We settled on this after less-than-thrilling results using a + canvas item as the background. The canvas item contributed to + the bounds of the canvas and had to constantly be resized. + */ + + g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + g_return_if_fail (GNOME_IS_CANVAS (canvas)); + + g_assert (GTK_OBJECT (canvas->root)->klass == gtk_type_class (GNOME_TYPE_CANVAS_GROUP) + || GTK_OBJECT (canvas->root)->klass == gtk_type_class (NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)); + + GTK_OBJECT (canvas->root)->klass = gtk_type_class (NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP); + + nautilus_background_canvas_group_set_background (NAUTILUS_BACKGROUND_CANVAS_GROUP (canvas->root), background); +} + +/* self check code */ + +#if !defined (NAUTILUS_OMIT_SELF_CHECK) + +void +nautilus_self_check_background (void) +{ + NautilusBackground *background; + + background = nautilus_background_new (); + + nautilus_background_set_color (background, NULL); + nautilus_background_set_color (background, ""); + nautilus_background_set_color (background, "red"); + nautilus_background_set_color (background, "red-blue"); + nautilus_background_set_color (background, "red-blue:h"); +} + +#endif /* !NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus-extensions/nautilus-background.h b/libnautilus-extensions/nautilus-background.h new file mode 100644 index 000000000..e95a359b1 --- /dev/null +++ b/libnautilus-extensions/nautilus-background.h @@ -0,0 +1,95 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.h: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_BACKGROUND_H +#define NAUTILUS_BACKGROUND_H + +/* Windows for Nautilus can contain backgrounds that are either tiled + with an image, a solid color, or a color gradient. This class manages + the process of loading the image if necessary and parsing the string + that specifies either a color or color gradient. + + The color or gradient is always present, even if there's a tiled image + on top of it. This is used when the tiled image can't be loaded for + some reason (or just has not been loaded yet). +*/ + +#include <gdk/gdktypes.h> +#include <libgnomeui/gnome-canvas.h> + +typedef struct _NautilusBackground NautilusBackground; +typedef struct _NautilusBackgroundClass NautilusBackgroundClass; + +#define NAUTILUS_TYPE_BACKGROUND \ + (nautilus_background_get_type ()) +#define NAUTILUS_BACKGROUND(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_BACKGROUND, NautilusBackground)) +#define NAUTILUS_BACKGROUND_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_BACKGROUND, NautilusBackgroundClass)) +#define NAUTILUS_IS_BACKGROUND(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_BACKGROUND)) +#define NAUTILUS_IS_BACKGROUND_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_BACKGROUND)) + +GtkType nautilus_background_get_type (void); +NautilusBackground *nautilus_background_new (void); + +void nautilus_background_set_color (NautilusBackground *background, + const char *color_or_gradient); +void nautilus_background_set_tile_image_uri (NautilusBackground *background, + const char *image_uri); + +char * nautilus_background_get_color (NautilusBackground *background); +char * nautilus_background_get_tile_image_uri (NautilusBackground *background); + +void nautilus_background_draw (NautilusBackground *background, + GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle); + +void nautilus_background_attach_to_canvas (NautilusBackground *background, + GnomeCanvas *canvas); + + +typedef struct _NautilusBackgroundDetails NautilusBackgroundDetails; + +struct _NautilusBackground +{ + GtkObject object; + NautilusBackgroundDetails *details; +}; + +struct _NautilusBackgroundClass +{ + GtkObjectClass parent_class; + + /* This signal is emitted when the background image is + finished loading. This allows a window to draw with a + color background if the image takes a lot time to load. + */ + void (* changed) (NautilusBackground *); +}; + +#endif /* NAUTILUS_BACKGROUND_H */ diff --git a/libnautilus-extensions/nautilus-lib-self-check-functions.c b/libnautilus-extensions/nautilus-lib-self-check-functions.c index 3e8d2e21e..8fd904042 100644 --- a/libnautilus-extensions/nautilus-lib-self-check-functions.c +++ b/libnautilus-extensions/nautilus-lib-self-check-functions.c @@ -33,6 +33,7 @@ void nautilus_run_lib_self_checks () { + nautilus_self_check_background (); nautilus_self_check_gdk_extensions (); } diff --git a/libnautilus-extensions/nautilus-lib-self-check-functions.h b/libnautilus-extensions/nautilus-lib-self-check-functions.h index dc9ada13a..2b68bd8d6 100644 --- a/libnautilus-extensions/nautilus-lib-self-check-functions.h +++ b/libnautilus-extensions/nautilus-lib-self-check-functions.h @@ -36,3 +36,4 @@ void nautilus_run_lib_self_checks (void); */ void nautilus_self_check_gdk_extensions (void); +void nautilus_self_check_background (void); diff --git a/libnautilus-extensions/nautilus-string.c b/libnautilus-extensions/nautilus-string.c new file mode 100644 index 000000000..02834386b --- /dev/null +++ b/libnautilus-extensions/nautilus-string.c @@ -0,0 +1,48 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-string.c: String routines to augment <string.h>. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-string.h" + +size_t +nautilus_strlen (const char *string_null_allowed) +{ + return string_null_allowed == NULL ? 0 : strlen (string_null_allowed); +} + +char * +nautilus_strchr (const char *haystack_null_allowed, char needle) +{ + return haystack_null_allowed == NULL ? NULL : strchr (haystack_null_allowed, needle); +} + +int +nautilus_strcmp (const char *string_a_null_allowed, const char *string_b_null_allowed) +{ + return strcmp (string_a_null_allowed == NULL ? "" : string_a_null_allowed, + string_b_null_allowed == NULL ? "" : string_b_null_allowed); +} diff --git a/libnautilus-extensions/nautilus-string.h b/libnautilus-extensions/nautilus-string.h new file mode 100644 index 000000000..fc0dbe36c --- /dev/null +++ b/libnautilus-extensions/nautilus-string.h @@ -0,0 +1,37 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-string.h: String routines to augment <string.h>. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_STRING_H +#define NAUTILUS_STRING_H + +#include <string.h> + +/* Versions of basic string functions that allow NULL. */ +size_t nautilus_strlen (const char *string_null_allowed); +char * nautilus_strchr (const char *haystack_null_allowed, + char needle); +int nautilus_strcmp (const char *string_a_null_allowed, + const char *string_b_null_allowed); + +#endif /* NAUTILUS_STRING_H */ diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am index 81e6a6b09..47c90e02d 100644 --- a/libnautilus-private/Makefile.am +++ b/libnautilus-private/Makefile.am @@ -22,10 +22,12 @@ libnautilusinclude_HEADERS= \ gtkflist.h \ gtkscrollframe.h \ nautilus.h \ + nautilus-background.h \ nautilus-file-utilities.h \ nautilus-gtk-extensions.h \ nautilus-lib-self-check-functions.h \ nautilus-self-checks.h \ + nautilus-string.h \ ntl-content-view-client.h \ ntl-meta-view-client.h \ ntl-view-client.h @@ -37,10 +39,13 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \ gnome-icon-container.c \ gtkflist.c \ gtkscrollframe.c \ + nautilus-background.c \ + nautilus-background-canvas-group.c \ nautilus-file-utilities.c \ nautilus-gtk-extensions.c \ nautilus-lib-self-check-functions.c \ nautilus-self-checks.c \ + nautilus-string.c \ ntl-content-view-client.c \ ntl-meta-view-client.c \ ntl-view-client.c \ diff --git a/libnautilus-private/gdk-extensions.c b/libnautilus-private/gdk-extensions.c index 8f145b5b6..e7f18e36e 100644 --- a/libnautilus-private/gdk-extensions.c +++ b/libnautilus-private/gdk-extensions.c @@ -29,8 +29,7 @@ #include "gdk-extensions.h" #include "nautilus-lib-self-check-functions.h" - -#include <string.h> +#include "nautilus-string.h" #define GRADIENT_BAND_SIZE 4 @@ -194,9 +193,9 @@ nautilus_gradient_new (const char *start_color, const char *end_color, gboolean is_horizontal) { - g_return_val_if_fail (start_color != NULL, g_strdup ("")); - g_return_val_if_fail (end_color != NULL, g_strdup ("")); - g_return_val_if_fail (is_horizontal == FALSE || is_horizontal == TRUE, g_strdup ("")); + g_return_val_if_fail (start_color != NULL, NULL); + g_return_val_if_fail (end_color != NULL, NULL); + g_return_val_if_fail (is_horizontal == FALSE || is_horizontal == TRUE, NULL); /* Handle the special case where the start and end colors are identical. Handle the special case where the end color is an empty string. @@ -221,9 +220,22 @@ nautilus_gradient_new (const char *start_color, gboolean nautilus_gradient_is_gradient (const char *gradient_spec) { - g_return_val_if_fail (gradient_spec != NULL, FALSE); + return nautilus_strchr (gradient_spec, '-') != NULL; +} + +/** + * nautilus_gradient_is_horizontal + * @gradient_spec: A gradient spec. string. + * + * Return true if the spec. specifies a horizontal gradient. + */ +gboolean +nautilus_gradient_is_horizontal (const char *gradient_spec) +{ + size_t length; - return strchr (gradient_spec, '-') != NULL; + length = nautilus_strlen (gradient_spec); + return length >= 2 && gradient_spec[length - 2] == ':' && gradient_spec[length - 1] == 'h'; } static char * @@ -231,9 +243,7 @@ nautilus_gradient_strip_trailing_direction_if_any (const char *gradient_spec) { size_t length; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - length = strlen (gradient_spec); + length = nautilus_strlen (gradient_spec); if (length >= 2 && gradient_spec[length - 2] == ':' && (gradient_spec[length - 1] == 'v' || gradient_spec[length - 1] == 'h')) length -= 2; @@ -253,9 +263,7 @@ nautilus_gradient_get_start_color_spec (const char *gradient_spec) { const char *separator; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - separator = strchr (gradient_spec, '-'); + separator = nautilus_strchr (gradient_spec, '-'); if (separator == NULL) return nautilus_gradient_strip_trailing_direction_if_any (gradient_spec); @@ -274,9 +282,7 @@ nautilus_gradient_get_end_color_spec (const char *gradient_spec) { const char *separator; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - separator = strchr (gradient_spec, '-'); + separator = nautilus_strchr (gradient_spec, '-'); return nautilus_gradient_strip_trailing_direction_if_any (separator != NULL ? separator + 1 : gradient_spec); } @@ -291,7 +297,6 @@ nautilus_gradient_set_edge_color (const char *gradient_spec, char *opposite_color; char *result; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); g_return_val_if_fail (edge_color != NULL, g_strdup (gradient_spec)); /* Get the color from the existing gradient spec. for the opposite @@ -374,11 +379,35 @@ nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, return nautilus_gradient_set_edge_color (gradient_spec, bottom_color, FALSE, TRUE); } +/** + * nautilus_gdk_color_parse_with_white_default + * @color_spec: A color spec. + * @color: Pointer to place to put resulting color. + * + * The same as gdk_color_parse, except sets the color to white if + * the spec. can't be parsed instead of returning a boolean flag. + */ +void +nautilus_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *color) +{ + if (!gdk_color_parse (color_spec, color)) { + color->red = 0xFFFF; + color->green = 0xFFFF; + color->blue = 0xFFFF; + } +} + #if ! defined (NAUTILUS_OMIT_SELF_CHECK) -#include <stdio.h> +static char * +nautilus_gdk_color_as_hex_string (GdkColor color) +{ + return g_strdup_printf("rgb:%04hX/%04hX/%04hX", + color.red, color.green, color.blue); +} -static GdkColor +static char * nautilus_self_check_interpolate (gdouble ratio, gushort r1, gushort g1, gushort b1, gushort r2, gushort g2, gushort b2) @@ -397,25 +426,30 @@ nautilus_self_check_interpolate (gdouble ratio, nautilus_interpolate_color (ratio, &start_color, &end_color, &interpolated_color); - return interpolated_color; + return nautilus_gdk_color_as_hex_string (interpolated_color); +} + +static char * +nautilus_self_check_parse (const char *color_spec) +{ + GdkColor color; + + nautilus_gdk_color_parse_with_white_default (color_spec, &color); + return nautilus_gdk_color_as_hex_string (color); } void nautilus_self_check_gdk_extensions (void) { /* nautilus_interpolate_color */ - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).red, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).green, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).blue, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0xFFFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0xFFFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0xFFFF); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0), + "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:7FFF/7FFF/7FFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:FFFF/FFFF/FFFF"); /* nautilus_fill_rectangle */ /* Make a GdkImage and fill it, maybe? */ @@ -503,6 +537,13 @@ nautilus_self_check_gdk_extensions (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a-c:v", "b"), "a-b"); NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a-c:v", "c"), "a-c"); NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a:-b:h", "d"), "a:-d"); + + /* nautilus_gdk_color_parse_with_white_default */ + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse (""), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("a"), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("white"), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("black"), "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("rgb:0123/4567/89AB"), "rgb:0123/4567/89AB"); } #endif /* ! NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus-private/gdk-extensions.h b/libnautilus-private/gdk-extensions.h index 8ecadf853..f5dd0c27b 100644 --- a/libnautilus-private/gdk-extensions.h +++ b/libnautilus-private/gdk-extensions.h @@ -32,44 +32,53 @@ The gradient is vertical by default and the spec. can end with ":v" to indicate that. If the gradient ends with ":h", the gradient is horizontal. */ -char * nautilus_gradient_new (const char *start_color, - const char *end_color, - gboolean is_horizontal); +char * nautilus_gradient_new (const char *start_color, + const char *end_color, + gboolean is_horizontal); -gboolean nautilus_gradient_is_gradient (const char *gradient_spec); -char * nautilus_gradient_get_start_color_spec (const char *gradient_spec); -char * nautilus_gradient_get_end_color_spec (const char *gradient_spec); -gboolean nautilus_gradient_is_horizontal (const char *gradient_spec); +gboolean nautilus_gradient_is_gradient (const char *gradient_spec); +char * nautilus_gradient_get_start_color_spec (const char *gradient_spec); +char * nautilus_gradient_get_end_color_spec (const char *gradient_spec); +gboolean nautilus_gradient_is_horizontal (const char *gradient_spec); -char * nautilus_gradient_set_left_color_spec (const char *gradient_spec, - const char *left_color); -char * nautilus_gradient_set_top_color_spec (const char *gradient_spec, - const char *top_color); -char * nautilus_gradient_set_right_color_spec (const char *gradient_spec, - const char *right_color); -char * nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, - const char *bottom_color); +char * nautilus_gradient_set_left_color_spec (const char *gradient_spec, + const char *left_color); +char * nautilus_gradient_set_top_color_spec (const char *gradient_spec, + const char *top_color); +char * nautilus_gradient_set_right_color_spec (const char *gradient_spec, + const char *right_color); +char * nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, + const char *bottom_color); -/* Fill routines that take GdkRectangle parameters instead of four coordinates. */ -void nautilus_fill_rectangle (GdkDrawable *drawable, - GdkGC *gc, - const GdkRectangle *rectangle); -void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, - GdkGC *gc, - const GdkRectangle *rectangle, - const GdkColor *color); -void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, - GdkGC *gc, - GdkColormap *colormap, - const GdkRectangle *rectangle, - const GdkColor *start_color, - const GdkColor *end_color, - gboolean horizontal_gradient); +/* A version of parse_color that substitutes a default color instead of returning + a boolean to indicate it cannot be parsed. +*/ +void nautilus_gdk_color_parse_with_default (const char *color_spec, + const GdkColor *default_color, + GdkColor *color); +void nautilus_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *color); + +/* Fill routines that take GdkRectangle parameters instead of four integers. */ +void nautilus_fill_rectangle (GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *rectangle); +void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *rectangle, + const GdkColor *color); +void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle, + const GdkColor *start_color, + const GdkColor *end_color, + gboolean horizontal_gradient); -/* A basic operation needed for drawing gradients is interpolating two colors.*/ -void nautilus_interpolate_color (gdouble ratio, - const GdkColor *start_color, - const GdkColor *end_color, - GdkColor *interpolated_color); +/* A basic operation we use for drawing gradients is interpolating two colors.*/ +void nautilus_interpolate_color (gdouble ratio, + const GdkColor *start_color, + const GdkColor *end_color, + GdkColor *interpolated_color); #endif /* GDK_EXTENSIONS_H */ diff --git a/libnautilus-private/nautilus-background-canvas-group.c b/libnautilus-private/nautilus-background-canvas-group.c new file mode 100644 index 000000000..d3cef3e2c --- /dev/null +++ b/libnautilus-private/nautilus-background-canvas-group.c @@ -0,0 +1,154 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.c: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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. + + Author: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-background-canvas-group.h" + +#include <libgnomeui/gnome-canvas.h> +#include "nautilus-background.h" +#include "nautilus-gtk-macros.h" + +static void nautilus_background_canvas_group_initialize_class (gpointer klass); +static void nautilus_background_canvas_group_initialize (gpointer object, gpointer klass); +static void nautilus_background_canvas_group_destroy (GtkObject *object); +static void nautilus_background_canvas_group_finalize (GtkObject *object); +static void nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable, + int x, int y, int width, int height); + +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusBackgroundCanvasGroup, nautilus_background_canvas_group, GNOME_TYPE_CANVAS_GROUP) + +static GtkObjectClass *parent_class; + +static void +nautilus_background_canvas_group_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + GnomeCanvasItemClass *canvas_item_class; + + object_class = GTK_OBJECT_CLASS (klass); + canvas_item_class = GNOME_CANVAS_ITEM_CLASS (klass); + parent_class = gtk_type_class (GNOME_TYPE_CANVAS_GROUP); + + object_class->destroy = nautilus_background_canvas_group_destroy; + object_class->finalize = nautilus_background_canvas_group_finalize; + + canvas_item_class->draw = nautilus_background_canvas_group_draw; +} + +static void +nautilus_background_canvas_group_initialize (gpointer object, gpointer klass) +{ +} + +static void +nautilus_background_canvas_group_destroy (GtkObject *object) +{ + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_background_canvas_group_finalize (GtkObject *object) +{ + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); +} + +static void +nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable, + int drawable_corner_x, int drawable_corner_y, + int drawable_width, int drawable_height) +{ + NautilusBackground *background; + + /* Draw the background. */ + background = nautilus_background_canvas_group_get_background + (NAUTILUS_BACKGROUND_CANVAS_GROUP (item)); + if (background != NULL) { + GdkGC *gc; + GdkColormap *colormap; + GdkRectangle rectangle; + + /* Create a new gc each time. + If this is a speed problem, we can create one and keep it around, + but it's a bit more complicated to ensure that it's always compatible + with whatever drawable is passed in to use. + */ + gc = gdk_gc_new (drawable); + + colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); + + /* The rectangle is the size of the entire viewed area of the canvas. + The corner is determined by the current scroll position of the + GtkLayout, and the size is determined by the current size of the widget. + Since 0,0 is the corner of the drawable, we need to offset the rectangle + so it's relative to the drawable's coordinates. + */ + rectangle.x = GTK_LAYOUT (item->canvas)->xoffset - drawable_corner_x; + rectangle.y = GTK_LAYOUT (item->canvas)->yoffset - drawable_corner_y; + rectangle.width = GTK_WIDGET (item->canvas)->allocation.width; + rectangle.height = GTK_WIDGET (item->canvas)->allocation.height; + + nautilus_background_draw (background, drawable, gc, colormap, &rectangle); + + gdk_gc_unref (gc); + } + + /* Call through to the GnomeCanvasGroup implementation, which will draw all + the canvas items. + */ + NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, draw, + (item, drawable, + drawable_corner_x, drawable_corner_y, + drawable_width, drawable_height)); +} + +NautilusBackground * +nautilus_background_canvas_group_get_background (NautilusBackgroundCanvasGroup *canvas_group) +{ + gpointer data; + + data = gtk_object_get_data (GTK_OBJECT (canvas_group), "nautilus_background"); + g_assert (data == NULL || NAUTILUS_IS_BACKGROUND (data)); + return data; +} + +void +nautilus_background_canvas_group_set_background (NautilusBackgroundCanvasGroup *canvas_group, + NautilusBackground *background) +{ + NautilusBackground *old_background; + + g_return_if_fail (NAUTILUS_IS_BACKGROUND_CANVAS_GROUP (canvas_group)); + g_return_if_fail (background == NULL || NAUTILUS_IS_BACKGROUND (background)); + + old_background = nautilus_background_canvas_group_get_background (canvas_group); + gtk_object_set_data (GTK_OBJECT (canvas_group), "nautilus_background", background); + + if (background != NULL) + gtk_object_ref (GTK_OBJECT (background)); + if (old_background != NULL) + gtk_object_unref (GTK_OBJECT (old_background)); +} diff --git a/libnautilus-private/nautilus-background-canvas-group.h b/libnautilus-private/nautilus-background-canvas-group.h new file mode 100644 index 000000000..b0449f786 --- /dev/null +++ b/libnautilus-private/nautilus-background-canvas-group.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background-canvas-group.h: Class used internally by + NautilusBackground to add a background to a canvas. + + Copyright (C) 2000 Eazel, Inc. + + 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: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_BACKGROUND_CANVAS_GROUP_H +#define NAUTILUS_BACKGROUND_CANVAS_GROUP_H + +#include "nautilus-background.h" + +/* A NautilusBackgroundCanvasGroup is used internally by NautilusBackground to change + the color of a canvas. The reason we have to change the class of a canvas group is + that the cleanest way to hook into the code that erases the canvas is to be the + root canvas group. But the canvas class creates the root object and doesn't allow + it to be destroyed, so we change the class of the root object in place. + + A future version of GnomeCanvas may allow a nicer way of hooking in to the code + that draws the background, and then we can get rid of this class. + + This class is private to NautilusBackground. +*/ + +typedef GnomeCanvasGroup NautilusBackgroundCanvasGroup; +typedef GnomeCanvasGroupClass NautilusBackgroundCanvasGroupClass; + +#define NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP \ + (nautilus_background_canvas_group_get_type ()) +#define NAUTILUS_BACKGROUND_CANVAS_GROUP(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP, NautilusBackgroundCanvasGroup)) +#define NAUTILUS_BACKGROUND_CANVAS_GROUP_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP, NautilusBackgroundCanvasGroupClass)) +#define NAUTILUS_IS_BACKGROUND_CANVAS_GROUP(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)) +#define NAUTILUS_IS_BACKGROUND_CANVAS_GROUP_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)) + +GtkType nautilus_background_canvas_group_get_type (void); +NautilusBackground *nautilus_background_canvas_group_get_background (NautilusBackgroundCanvasGroup *root); +void nautilus_background_canvas_group_set_background (NautilusBackgroundCanvasGroup *root, + NautilusBackground *background); + +#endif /* NAUTILUS_BACKGROUND_CANVAS_GROUP_H */ diff --git a/libnautilus-private/nautilus-background.c b/libnautilus-private/nautilus-background.c new file mode 100644 index 000000000..35afd8bc1 --- /dev/null +++ b/libnautilus-private/nautilus-background.c @@ -0,0 +1,202 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.c: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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. + + Author: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-background.h" + +#include <gtk/gtksignal.h> +#include "gdk-extensions.h" +#include "nautilus-background-canvas-group.h" +#include "nautilus-lib-self-check-functions.h" +#include "nautilus-gtk-macros.h" + +static void nautilus_background_initialize_class (gpointer klass); +static void nautilus_background_initialize (gpointer object, gpointer klass); +static void nautilus_background_destroy (GtkObject *object); +static void nautilus_background_finalize (GtkObject *object); + +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusBackground, nautilus_background, GTK_TYPE_OBJECT) + +enum { + CHANGED, + LAST_SIGNAL +}; + +static GtkObjectClass *parent_class; +static guint signals[LAST_SIGNAL]; + +struct _NautilusBackgroundDetails +{ + char *color; + char *tile_image_uri; +}; + +static void +nautilus_background_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (klass); + + parent_class = gtk_type_class (GTK_TYPE_OBJECT); + + signals[CHANGED] = + gtk_signal_new ("changed", + GTK_RUN_FIRST | GTK_RUN_NO_RECURSE, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusBackgroundClass, changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, + 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + + object_class->destroy = nautilus_background_destroy; + object_class->finalize = nautilus_background_finalize; +} + +static void +nautilus_background_initialize (gpointer object, gpointer klass) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND(object); + + background->details = g_new0 (NautilusBackgroundDetails, 1); +} + +static void +nautilus_background_destroy (GtkObject *object) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND (object); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_background_finalize (GtkObject *object) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND (object); + g_free (background->details); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); +} + +NautilusBackground * +nautilus_background_new (void) +{ + return NAUTILUS_BACKGROUND (gtk_type_new (NAUTILUS_TYPE_BACKGROUND)); +} + +void +nautilus_background_draw (NautilusBackground *background, + GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle) +{ + char *start_color_spec; + char *end_color_spec; + GdkColor start_color; + GdkColor end_color; + gboolean horizontal_gradient; + + start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color); + end_color_spec = nautilus_gradient_get_end_color_spec (background->details->color); + horizontal_gradient = nautilus_gradient_is_horizontal (background->details->color); + + nautilus_gdk_color_parse_with_white_default (start_color_spec, &start_color); + nautilus_gdk_color_parse_with_white_default (end_color_spec, &end_color); + + g_free (start_color_spec); + g_free (end_color_spec); + + nautilus_fill_rectangle_with_gradient (drawable, gc, colormap, rectangle, + &start_color, &end_color, horizontal_gradient); +} + +void +nautilus_background_set_color (NautilusBackground *background, + const char *color) +{ + g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + + g_free (background->details->color); + background->details->color = g_strdup (color); + + gtk_signal_emit (GTK_OBJECT (background), signals[CHANGED]); +} + +void +nautilus_background_attach_to_canvas (NautilusBackground *background, + GnomeCanvas *canvas) +{ + /* Since there's no signal to override in GnomeCanvas to control + drawing the background, we change the class of the canvas root. + This gives us a chance to draw the background before any of the + objects draw themselves, and has no effect on the bounds or + anything related to scrolling. + + We settled on this after less-than-thrilling results using a + canvas item as the background. The canvas item contributed to + the bounds of the canvas and had to constantly be resized. + */ + + g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + g_return_if_fail (GNOME_IS_CANVAS (canvas)); + + g_assert (GTK_OBJECT (canvas->root)->klass == gtk_type_class (GNOME_TYPE_CANVAS_GROUP) + || GTK_OBJECT (canvas->root)->klass == gtk_type_class (NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)); + + GTK_OBJECT (canvas->root)->klass = gtk_type_class (NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP); + + nautilus_background_canvas_group_set_background (NAUTILUS_BACKGROUND_CANVAS_GROUP (canvas->root), background); +} + +/* self check code */ + +#if !defined (NAUTILUS_OMIT_SELF_CHECK) + +void +nautilus_self_check_background (void) +{ + NautilusBackground *background; + + background = nautilus_background_new (); + + nautilus_background_set_color (background, NULL); + nautilus_background_set_color (background, ""); + nautilus_background_set_color (background, "red"); + nautilus_background_set_color (background, "red-blue"); + nautilus_background_set_color (background, "red-blue:h"); +} + +#endif /* !NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus-private/nautilus-background.h b/libnautilus-private/nautilus-background.h new file mode 100644 index 000000000..e95a359b1 --- /dev/null +++ b/libnautilus-private/nautilus-background.h @@ -0,0 +1,95 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.h: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_BACKGROUND_H +#define NAUTILUS_BACKGROUND_H + +/* Windows for Nautilus can contain backgrounds that are either tiled + with an image, a solid color, or a color gradient. This class manages + the process of loading the image if necessary and parsing the string + that specifies either a color or color gradient. + + The color or gradient is always present, even if there's a tiled image + on top of it. This is used when the tiled image can't be loaded for + some reason (or just has not been loaded yet). +*/ + +#include <gdk/gdktypes.h> +#include <libgnomeui/gnome-canvas.h> + +typedef struct _NautilusBackground NautilusBackground; +typedef struct _NautilusBackgroundClass NautilusBackgroundClass; + +#define NAUTILUS_TYPE_BACKGROUND \ + (nautilus_background_get_type ()) +#define NAUTILUS_BACKGROUND(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_BACKGROUND, NautilusBackground)) +#define NAUTILUS_BACKGROUND_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_BACKGROUND, NautilusBackgroundClass)) +#define NAUTILUS_IS_BACKGROUND(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_BACKGROUND)) +#define NAUTILUS_IS_BACKGROUND_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_BACKGROUND)) + +GtkType nautilus_background_get_type (void); +NautilusBackground *nautilus_background_new (void); + +void nautilus_background_set_color (NautilusBackground *background, + const char *color_or_gradient); +void nautilus_background_set_tile_image_uri (NautilusBackground *background, + const char *image_uri); + +char * nautilus_background_get_color (NautilusBackground *background); +char * nautilus_background_get_tile_image_uri (NautilusBackground *background); + +void nautilus_background_draw (NautilusBackground *background, + GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle); + +void nautilus_background_attach_to_canvas (NautilusBackground *background, + GnomeCanvas *canvas); + + +typedef struct _NautilusBackgroundDetails NautilusBackgroundDetails; + +struct _NautilusBackground +{ + GtkObject object; + NautilusBackgroundDetails *details; +}; + +struct _NautilusBackgroundClass +{ + GtkObjectClass parent_class; + + /* This signal is emitted when the background image is + finished loading. This allows a window to draw with a + color background if the image takes a lot time to load. + */ + void (* changed) (NautilusBackground *); +}; + +#endif /* NAUTILUS_BACKGROUND_H */ diff --git a/libnautilus-private/nautilus-lib-self-check-functions.c b/libnautilus-private/nautilus-lib-self-check-functions.c index 3e8d2e21e..8fd904042 100644 --- a/libnautilus-private/nautilus-lib-self-check-functions.c +++ b/libnautilus-private/nautilus-lib-self-check-functions.c @@ -33,6 +33,7 @@ void nautilus_run_lib_self_checks () { + nautilus_self_check_background (); nautilus_self_check_gdk_extensions (); } diff --git a/libnautilus-private/nautilus-lib-self-check-functions.h b/libnautilus-private/nautilus-lib-self-check-functions.h index dc9ada13a..2b68bd8d6 100644 --- a/libnautilus-private/nautilus-lib-self-check-functions.h +++ b/libnautilus-private/nautilus-lib-self-check-functions.h @@ -36,3 +36,4 @@ void nautilus_run_lib_self_checks (void); */ void nautilus_self_check_gdk_extensions (void); +void nautilus_self_check_background (void); diff --git a/libnautilus-private/nautilus-string.c b/libnautilus-private/nautilus-string.c new file mode 100644 index 000000000..02834386b --- /dev/null +++ b/libnautilus-private/nautilus-string.c @@ -0,0 +1,48 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-string.c: String routines to augment <string.h>. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-string.h" + +size_t +nautilus_strlen (const char *string_null_allowed) +{ + return string_null_allowed == NULL ? 0 : strlen (string_null_allowed); +} + +char * +nautilus_strchr (const char *haystack_null_allowed, char needle) +{ + return haystack_null_allowed == NULL ? NULL : strchr (haystack_null_allowed, needle); +} + +int +nautilus_strcmp (const char *string_a_null_allowed, const char *string_b_null_allowed) +{ + return strcmp (string_a_null_allowed == NULL ? "" : string_a_null_allowed, + string_b_null_allowed == NULL ? "" : string_b_null_allowed); +} diff --git a/libnautilus-private/nautilus-string.h b/libnautilus-private/nautilus-string.h new file mode 100644 index 000000000..fc0dbe36c --- /dev/null +++ b/libnautilus-private/nautilus-string.h @@ -0,0 +1,37 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-string.h: String routines to augment <string.h>. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_STRING_H +#define NAUTILUS_STRING_H + +#include <string.h> + +/* Versions of basic string functions that allow NULL. */ +size_t nautilus_strlen (const char *string_null_allowed); +char * nautilus_strchr (const char *haystack_null_allowed, + char needle); +int nautilus_strcmp (const char *string_a_null_allowed, + const char *string_b_null_allowed); + +#endif /* NAUTILUS_STRING_H */ diff --git a/libnautilus/Makefile.am b/libnautilus/Makefile.am index 81e6a6b09..47c90e02d 100644 --- a/libnautilus/Makefile.am +++ b/libnautilus/Makefile.am @@ -22,10 +22,12 @@ libnautilusinclude_HEADERS= \ gtkflist.h \ gtkscrollframe.h \ nautilus.h \ + nautilus-background.h \ nautilus-file-utilities.h \ nautilus-gtk-extensions.h \ nautilus-lib-self-check-functions.h \ nautilus-self-checks.h \ + nautilus-string.h \ ntl-content-view-client.h \ ntl-meta-view-client.h \ ntl-view-client.h @@ -37,10 +39,13 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \ gnome-icon-container.c \ gtkflist.c \ gtkscrollframe.c \ + nautilus-background.c \ + nautilus-background-canvas-group.c \ nautilus-file-utilities.c \ nautilus-gtk-extensions.c \ nautilus-lib-self-check-functions.c \ nautilus-self-checks.c \ + nautilus-string.c \ ntl-content-view-client.c \ ntl-meta-view-client.c \ ntl-view-client.c \ diff --git a/libnautilus/gdk-extensions.c b/libnautilus/gdk-extensions.c index 8f145b5b6..e7f18e36e 100644 --- a/libnautilus/gdk-extensions.c +++ b/libnautilus/gdk-extensions.c @@ -29,8 +29,7 @@ #include "gdk-extensions.h" #include "nautilus-lib-self-check-functions.h" - -#include <string.h> +#include "nautilus-string.h" #define GRADIENT_BAND_SIZE 4 @@ -194,9 +193,9 @@ nautilus_gradient_new (const char *start_color, const char *end_color, gboolean is_horizontal) { - g_return_val_if_fail (start_color != NULL, g_strdup ("")); - g_return_val_if_fail (end_color != NULL, g_strdup ("")); - g_return_val_if_fail (is_horizontal == FALSE || is_horizontal == TRUE, g_strdup ("")); + g_return_val_if_fail (start_color != NULL, NULL); + g_return_val_if_fail (end_color != NULL, NULL); + g_return_val_if_fail (is_horizontal == FALSE || is_horizontal == TRUE, NULL); /* Handle the special case where the start and end colors are identical. Handle the special case where the end color is an empty string. @@ -221,9 +220,22 @@ nautilus_gradient_new (const char *start_color, gboolean nautilus_gradient_is_gradient (const char *gradient_spec) { - g_return_val_if_fail (gradient_spec != NULL, FALSE); + return nautilus_strchr (gradient_spec, '-') != NULL; +} + +/** + * nautilus_gradient_is_horizontal + * @gradient_spec: A gradient spec. string. + * + * Return true if the spec. specifies a horizontal gradient. + */ +gboolean +nautilus_gradient_is_horizontal (const char *gradient_spec) +{ + size_t length; - return strchr (gradient_spec, '-') != NULL; + length = nautilus_strlen (gradient_spec); + return length >= 2 && gradient_spec[length - 2] == ':' && gradient_spec[length - 1] == 'h'; } static char * @@ -231,9 +243,7 @@ nautilus_gradient_strip_trailing_direction_if_any (const char *gradient_spec) { size_t length; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - length = strlen (gradient_spec); + length = nautilus_strlen (gradient_spec); if (length >= 2 && gradient_spec[length - 2] == ':' && (gradient_spec[length - 1] == 'v' || gradient_spec[length - 1] == 'h')) length -= 2; @@ -253,9 +263,7 @@ nautilus_gradient_get_start_color_spec (const char *gradient_spec) { const char *separator; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - separator = strchr (gradient_spec, '-'); + separator = nautilus_strchr (gradient_spec, '-'); if (separator == NULL) return nautilus_gradient_strip_trailing_direction_if_any (gradient_spec); @@ -274,9 +282,7 @@ nautilus_gradient_get_end_color_spec (const char *gradient_spec) { const char *separator; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); - - separator = strchr (gradient_spec, '-'); + separator = nautilus_strchr (gradient_spec, '-'); return nautilus_gradient_strip_trailing_direction_if_any (separator != NULL ? separator + 1 : gradient_spec); } @@ -291,7 +297,6 @@ nautilus_gradient_set_edge_color (const char *gradient_spec, char *opposite_color; char *result; - g_return_val_if_fail (gradient_spec != NULL, g_strdup ("")); g_return_val_if_fail (edge_color != NULL, g_strdup (gradient_spec)); /* Get the color from the existing gradient spec. for the opposite @@ -374,11 +379,35 @@ nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, return nautilus_gradient_set_edge_color (gradient_spec, bottom_color, FALSE, TRUE); } +/** + * nautilus_gdk_color_parse_with_white_default + * @color_spec: A color spec. + * @color: Pointer to place to put resulting color. + * + * The same as gdk_color_parse, except sets the color to white if + * the spec. can't be parsed instead of returning a boolean flag. + */ +void +nautilus_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *color) +{ + if (!gdk_color_parse (color_spec, color)) { + color->red = 0xFFFF; + color->green = 0xFFFF; + color->blue = 0xFFFF; + } +} + #if ! defined (NAUTILUS_OMIT_SELF_CHECK) -#include <stdio.h> +static char * +nautilus_gdk_color_as_hex_string (GdkColor color) +{ + return g_strdup_printf("rgb:%04hX/%04hX/%04hX", + color.red, color.green, color.blue); +} -static GdkColor +static char * nautilus_self_check_interpolate (gdouble ratio, gushort r1, gushort g1, gushort b1, gushort r2, gushort g2, gushort b2) @@ -397,25 +426,30 @@ nautilus_self_check_interpolate (gdouble ratio, nautilus_interpolate_color (ratio, &start_color, &end_color, &interpolated_color); - return interpolated_color; + return nautilus_gdk_color_as_hex_string (interpolated_color); +} + +static char * +nautilus_self_check_parse (const char *color_spec) +{ + GdkColor color; + + nautilus_gdk_color_parse_with_white_default (color_spec, &color); + return nautilus_gdk_color_as_hex_string (color); } void nautilus_self_check_gdk_extensions (void) { /* nautilus_interpolate_color */ - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).red, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).green, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0).blue, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0x7FFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).red, 0xFFFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).green, 0xFFFF); - NAUTILUS_CHECK_INTEGER_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF).blue, 0xFFFF); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0, 0, 0), + "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (0.5, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:7FFF/7FFF/7FFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_interpolate (1.0, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF), + "rgb:FFFF/FFFF/FFFF"); /* nautilus_fill_rectangle */ /* Make a GdkImage and fill it, maybe? */ @@ -503,6 +537,13 @@ nautilus_self_check_gdk_extensions (void) NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a-c:v", "b"), "a-b"); NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a-c:v", "c"), "a-c"); NAUTILUS_CHECK_STRING_RESULT (nautilus_gradient_set_bottom_color_spec ("a:-b:h", "d"), "a:-d"); + + /* nautilus_gdk_color_parse_with_white_default */ + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse (""), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("a"), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("white"), "rgb:FFFF/FFFF/FFFF"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("black"), "rgb:0000/0000/0000"); + NAUTILUS_CHECK_STRING_RESULT (nautilus_self_check_parse ("rgb:0123/4567/89AB"), "rgb:0123/4567/89AB"); } #endif /* ! NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus/gdk-extensions.h b/libnautilus/gdk-extensions.h index 8ecadf853..f5dd0c27b 100644 --- a/libnautilus/gdk-extensions.h +++ b/libnautilus/gdk-extensions.h @@ -32,44 +32,53 @@ The gradient is vertical by default and the spec. can end with ":v" to indicate that. If the gradient ends with ":h", the gradient is horizontal. */ -char * nautilus_gradient_new (const char *start_color, - const char *end_color, - gboolean is_horizontal); +char * nautilus_gradient_new (const char *start_color, + const char *end_color, + gboolean is_horizontal); -gboolean nautilus_gradient_is_gradient (const char *gradient_spec); -char * nautilus_gradient_get_start_color_spec (const char *gradient_spec); -char * nautilus_gradient_get_end_color_spec (const char *gradient_spec); -gboolean nautilus_gradient_is_horizontal (const char *gradient_spec); +gboolean nautilus_gradient_is_gradient (const char *gradient_spec); +char * nautilus_gradient_get_start_color_spec (const char *gradient_spec); +char * nautilus_gradient_get_end_color_spec (const char *gradient_spec); +gboolean nautilus_gradient_is_horizontal (const char *gradient_spec); -char * nautilus_gradient_set_left_color_spec (const char *gradient_spec, - const char *left_color); -char * nautilus_gradient_set_top_color_spec (const char *gradient_spec, - const char *top_color); -char * nautilus_gradient_set_right_color_spec (const char *gradient_spec, - const char *right_color); -char * nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, - const char *bottom_color); +char * nautilus_gradient_set_left_color_spec (const char *gradient_spec, + const char *left_color); +char * nautilus_gradient_set_top_color_spec (const char *gradient_spec, + const char *top_color); +char * nautilus_gradient_set_right_color_spec (const char *gradient_spec, + const char *right_color); +char * nautilus_gradient_set_bottom_color_spec (const char *gradient_spec, + const char *bottom_color); -/* Fill routines that take GdkRectangle parameters instead of four coordinates. */ -void nautilus_fill_rectangle (GdkDrawable *drawable, - GdkGC *gc, - const GdkRectangle *rectangle); -void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, - GdkGC *gc, - const GdkRectangle *rectangle, - const GdkColor *color); -void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, - GdkGC *gc, - GdkColormap *colormap, - const GdkRectangle *rectangle, - const GdkColor *start_color, - const GdkColor *end_color, - gboolean horizontal_gradient); +/* A version of parse_color that substitutes a default color instead of returning + a boolean to indicate it cannot be parsed. +*/ +void nautilus_gdk_color_parse_with_default (const char *color_spec, + const GdkColor *default_color, + GdkColor *color); +void nautilus_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *color); + +/* Fill routines that take GdkRectangle parameters instead of four integers. */ +void nautilus_fill_rectangle (GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *rectangle); +void nautilus_fill_rectangle_with_color (GdkDrawable *drawable, + GdkGC *gc, + const GdkRectangle *rectangle, + const GdkColor *color); +void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle, + const GdkColor *start_color, + const GdkColor *end_color, + gboolean horizontal_gradient); -/* A basic operation needed for drawing gradients is interpolating two colors.*/ -void nautilus_interpolate_color (gdouble ratio, - const GdkColor *start_color, - const GdkColor *end_color, - GdkColor *interpolated_color); +/* A basic operation we use for drawing gradients is interpolating two colors.*/ +void nautilus_interpolate_color (gdouble ratio, + const GdkColor *start_color, + const GdkColor *end_color, + GdkColor *interpolated_color); #endif /* GDK_EXTENSIONS_H */ diff --git a/libnautilus/nautilus-background-canvas-group.c b/libnautilus/nautilus-background-canvas-group.c new file mode 100644 index 000000000..d3cef3e2c --- /dev/null +++ b/libnautilus/nautilus-background-canvas-group.c @@ -0,0 +1,154 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.c: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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. + + Author: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-background-canvas-group.h" + +#include <libgnomeui/gnome-canvas.h> +#include "nautilus-background.h" +#include "nautilus-gtk-macros.h" + +static void nautilus_background_canvas_group_initialize_class (gpointer klass); +static void nautilus_background_canvas_group_initialize (gpointer object, gpointer klass); +static void nautilus_background_canvas_group_destroy (GtkObject *object); +static void nautilus_background_canvas_group_finalize (GtkObject *object); +static void nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable, + int x, int y, int width, int height); + +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusBackgroundCanvasGroup, nautilus_background_canvas_group, GNOME_TYPE_CANVAS_GROUP) + +static GtkObjectClass *parent_class; + +static void +nautilus_background_canvas_group_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + GnomeCanvasItemClass *canvas_item_class; + + object_class = GTK_OBJECT_CLASS (klass); + canvas_item_class = GNOME_CANVAS_ITEM_CLASS (klass); + parent_class = gtk_type_class (GNOME_TYPE_CANVAS_GROUP); + + object_class->destroy = nautilus_background_canvas_group_destroy; + object_class->finalize = nautilus_background_canvas_group_finalize; + + canvas_item_class->draw = nautilus_background_canvas_group_draw; +} + +static void +nautilus_background_canvas_group_initialize (gpointer object, gpointer klass) +{ +} + +static void +nautilus_background_canvas_group_destroy (GtkObject *object) +{ + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_background_canvas_group_finalize (GtkObject *object) +{ + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); +} + +static void +nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable, + int drawable_corner_x, int drawable_corner_y, + int drawable_width, int drawable_height) +{ + NautilusBackground *background; + + /* Draw the background. */ + background = nautilus_background_canvas_group_get_background + (NAUTILUS_BACKGROUND_CANVAS_GROUP (item)); + if (background != NULL) { + GdkGC *gc; + GdkColormap *colormap; + GdkRectangle rectangle; + + /* Create a new gc each time. + If this is a speed problem, we can create one and keep it around, + but it's a bit more complicated to ensure that it's always compatible + with whatever drawable is passed in to use. + */ + gc = gdk_gc_new (drawable); + + colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); + + /* The rectangle is the size of the entire viewed area of the canvas. + The corner is determined by the current scroll position of the + GtkLayout, and the size is determined by the current size of the widget. + Since 0,0 is the corner of the drawable, we need to offset the rectangle + so it's relative to the drawable's coordinates. + */ + rectangle.x = GTK_LAYOUT (item->canvas)->xoffset - drawable_corner_x; + rectangle.y = GTK_LAYOUT (item->canvas)->yoffset - drawable_corner_y; + rectangle.width = GTK_WIDGET (item->canvas)->allocation.width; + rectangle.height = GTK_WIDGET (item->canvas)->allocation.height; + + nautilus_background_draw (background, drawable, gc, colormap, &rectangle); + + gdk_gc_unref (gc); + } + + /* Call through to the GnomeCanvasGroup implementation, which will draw all + the canvas items. + */ + NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, draw, + (item, drawable, + drawable_corner_x, drawable_corner_y, + drawable_width, drawable_height)); +} + +NautilusBackground * +nautilus_background_canvas_group_get_background (NautilusBackgroundCanvasGroup *canvas_group) +{ + gpointer data; + + data = gtk_object_get_data (GTK_OBJECT (canvas_group), "nautilus_background"); + g_assert (data == NULL || NAUTILUS_IS_BACKGROUND (data)); + return data; +} + +void +nautilus_background_canvas_group_set_background (NautilusBackgroundCanvasGroup *canvas_group, + NautilusBackground *background) +{ + NautilusBackground *old_background; + + g_return_if_fail (NAUTILUS_IS_BACKGROUND_CANVAS_GROUP (canvas_group)); + g_return_if_fail (background == NULL || NAUTILUS_IS_BACKGROUND (background)); + + old_background = nautilus_background_canvas_group_get_background (canvas_group); + gtk_object_set_data (GTK_OBJECT (canvas_group), "nautilus_background", background); + + if (background != NULL) + gtk_object_ref (GTK_OBJECT (background)); + if (old_background != NULL) + gtk_object_unref (GTK_OBJECT (old_background)); +} diff --git a/libnautilus/nautilus-background-canvas-group.h b/libnautilus/nautilus-background-canvas-group.h new file mode 100644 index 000000000..b0449f786 --- /dev/null +++ b/libnautilus/nautilus-background-canvas-group.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background-canvas-group.h: Class used internally by + NautilusBackground to add a background to a canvas. + + Copyright (C) 2000 Eazel, Inc. + + 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: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_BACKGROUND_CANVAS_GROUP_H +#define NAUTILUS_BACKGROUND_CANVAS_GROUP_H + +#include "nautilus-background.h" + +/* A NautilusBackgroundCanvasGroup is used internally by NautilusBackground to change + the color of a canvas. The reason we have to change the class of a canvas group is + that the cleanest way to hook into the code that erases the canvas is to be the + root canvas group. But the canvas class creates the root object and doesn't allow + it to be destroyed, so we change the class of the root object in place. + + A future version of GnomeCanvas may allow a nicer way of hooking in to the code + that draws the background, and then we can get rid of this class. + + This class is private to NautilusBackground. +*/ + +typedef GnomeCanvasGroup NautilusBackgroundCanvasGroup; +typedef GnomeCanvasGroupClass NautilusBackgroundCanvasGroupClass; + +#define NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP \ + (nautilus_background_canvas_group_get_type ()) +#define NAUTILUS_BACKGROUND_CANVAS_GROUP(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP, NautilusBackgroundCanvasGroup)) +#define NAUTILUS_BACKGROUND_CANVAS_GROUP_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP, NautilusBackgroundCanvasGroupClass)) +#define NAUTILUS_IS_BACKGROUND_CANVAS_GROUP(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)) +#define NAUTILUS_IS_BACKGROUND_CANVAS_GROUP_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)) + +GtkType nautilus_background_canvas_group_get_type (void); +NautilusBackground *nautilus_background_canvas_group_get_background (NautilusBackgroundCanvasGroup *root); +void nautilus_background_canvas_group_set_background (NautilusBackgroundCanvasGroup *root, + NautilusBackground *background); + +#endif /* NAUTILUS_BACKGROUND_CANVAS_GROUP_H */ diff --git a/libnautilus/nautilus-background.c b/libnautilus/nautilus-background.c new file mode 100644 index 000000000..35afd8bc1 --- /dev/null +++ b/libnautilus/nautilus-background.c @@ -0,0 +1,202 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.c: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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. + + Author: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-background.h" + +#include <gtk/gtksignal.h> +#include "gdk-extensions.h" +#include "nautilus-background-canvas-group.h" +#include "nautilus-lib-self-check-functions.h" +#include "nautilus-gtk-macros.h" + +static void nautilus_background_initialize_class (gpointer klass); +static void nautilus_background_initialize (gpointer object, gpointer klass); +static void nautilus_background_destroy (GtkObject *object); +static void nautilus_background_finalize (GtkObject *object); + +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusBackground, nautilus_background, GTK_TYPE_OBJECT) + +enum { + CHANGED, + LAST_SIGNAL +}; + +static GtkObjectClass *parent_class; +static guint signals[LAST_SIGNAL]; + +struct _NautilusBackgroundDetails +{ + char *color; + char *tile_image_uri; +}; + +static void +nautilus_background_initialize_class (gpointer klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (klass); + + parent_class = gtk_type_class (GTK_TYPE_OBJECT); + + signals[CHANGED] = + gtk_signal_new ("changed", + GTK_RUN_FIRST | GTK_RUN_NO_RECURSE, + object_class->type, + GTK_SIGNAL_OFFSET (NautilusBackgroundClass, changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, + 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + + object_class->destroy = nautilus_background_destroy; + object_class->finalize = nautilus_background_finalize; +} + +static void +nautilus_background_initialize (gpointer object, gpointer klass) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND(object); + + background->details = g_new0 (NautilusBackgroundDetails, 1); +} + +static void +nautilus_background_destroy (GtkObject *object) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND (object); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_background_finalize (GtkObject *object) +{ + NautilusBackground *background; + + background = NAUTILUS_BACKGROUND (object); + g_free (background->details); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); +} + +NautilusBackground * +nautilus_background_new (void) +{ + return NAUTILUS_BACKGROUND (gtk_type_new (NAUTILUS_TYPE_BACKGROUND)); +} + +void +nautilus_background_draw (NautilusBackground *background, + GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle) +{ + char *start_color_spec; + char *end_color_spec; + GdkColor start_color; + GdkColor end_color; + gboolean horizontal_gradient; + + start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color); + end_color_spec = nautilus_gradient_get_end_color_spec (background->details->color); + horizontal_gradient = nautilus_gradient_is_horizontal (background->details->color); + + nautilus_gdk_color_parse_with_white_default (start_color_spec, &start_color); + nautilus_gdk_color_parse_with_white_default (end_color_spec, &end_color); + + g_free (start_color_spec); + g_free (end_color_spec); + + nautilus_fill_rectangle_with_gradient (drawable, gc, colormap, rectangle, + &start_color, &end_color, horizontal_gradient); +} + +void +nautilus_background_set_color (NautilusBackground *background, + const char *color) +{ + g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + + g_free (background->details->color); + background->details->color = g_strdup (color); + + gtk_signal_emit (GTK_OBJECT (background), signals[CHANGED]); +} + +void +nautilus_background_attach_to_canvas (NautilusBackground *background, + GnomeCanvas *canvas) +{ + /* Since there's no signal to override in GnomeCanvas to control + drawing the background, we change the class of the canvas root. + This gives us a chance to draw the background before any of the + objects draw themselves, and has no effect on the bounds or + anything related to scrolling. + + We settled on this after less-than-thrilling results using a + canvas item as the background. The canvas item contributed to + the bounds of the canvas and had to constantly be resized. + */ + + g_return_if_fail (NAUTILUS_IS_BACKGROUND (background)); + g_return_if_fail (GNOME_IS_CANVAS (canvas)); + + g_assert (GTK_OBJECT (canvas->root)->klass == gtk_type_class (GNOME_TYPE_CANVAS_GROUP) + || GTK_OBJECT (canvas->root)->klass == gtk_type_class (NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP)); + + GTK_OBJECT (canvas->root)->klass = gtk_type_class (NAUTILUS_TYPE_BACKGROUND_CANVAS_GROUP); + + nautilus_background_canvas_group_set_background (NAUTILUS_BACKGROUND_CANVAS_GROUP (canvas->root), background); +} + +/* self check code */ + +#if !defined (NAUTILUS_OMIT_SELF_CHECK) + +void +nautilus_self_check_background (void) +{ + NautilusBackground *background; + + background = nautilus_background_new (); + + nautilus_background_set_color (background, NULL); + nautilus_background_set_color (background, ""); + nautilus_background_set_color (background, "red"); + nautilus_background_set_color (background, "red-blue"); + nautilus_background_set_color (background, "red-blue:h"); +} + +#endif /* !NAUTILUS_OMIT_SELF_CHECK */ diff --git a/libnautilus/nautilus-background.h b/libnautilus/nautilus-background.h new file mode 100644 index 000000000..e95a359b1 --- /dev/null +++ b/libnautilus/nautilus-background.h @@ -0,0 +1,95 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-background.h: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + 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: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_BACKGROUND_H +#define NAUTILUS_BACKGROUND_H + +/* Windows for Nautilus can contain backgrounds that are either tiled + with an image, a solid color, or a color gradient. This class manages + the process of loading the image if necessary and parsing the string + that specifies either a color or color gradient. + + The color or gradient is always present, even if there's a tiled image + on top of it. This is used when the tiled image can't be loaded for + some reason (or just has not been loaded yet). +*/ + +#include <gdk/gdktypes.h> +#include <libgnomeui/gnome-canvas.h> + +typedef struct _NautilusBackground NautilusBackground; +typedef struct _NautilusBackgroundClass NautilusBackgroundClass; + +#define NAUTILUS_TYPE_BACKGROUND \ + (nautilus_background_get_type ()) +#define NAUTILUS_BACKGROUND(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_BACKGROUND, NautilusBackground)) +#define NAUTILUS_BACKGROUND_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_BACKGROUND, NautilusBackgroundClass)) +#define NAUTILUS_IS_BACKGROUND(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_BACKGROUND)) +#define NAUTILUS_IS_BACKGROUND_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_BACKGROUND)) + +GtkType nautilus_background_get_type (void); +NautilusBackground *nautilus_background_new (void); + +void nautilus_background_set_color (NautilusBackground *background, + const char *color_or_gradient); +void nautilus_background_set_tile_image_uri (NautilusBackground *background, + const char *image_uri); + +char * nautilus_background_get_color (NautilusBackground *background); +char * nautilus_background_get_tile_image_uri (NautilusBackground *background); + +void nautilus_background_draw (NautilusBackground *background, + GdkDrawable *drawable, + GdkGC *gc, + GdkColormap *colormap, + const GdkRectangle *rectangle); + +void nautilus_background_attach_to_canvas (NautilusBackground *background, + GnomeCanvas *canvas); + + +typedef struct _NautilusBackgroundDetails NautilusBackgroundDetails; + +struct _NautilusBackground +{ + GtkObject object; + NautilusBackgroundDetails *details; +}; + +struct _NautilusBackgroundClass +{ + GtkObjectClass parent_class; + + /* This signal is emitted when the background image is + finished loading. This allows a window to draw with a + color background if the image takes a lot time to load. + */ + void (* changed) (NautilusBackground *); +}; + +#endif /* NAUTILUS_BACKGROUND_H */ diff --git a/libnautilus/nautilus-lib-self-check-functions.c b/libnautilus/nautilus-lib-self-check-functions.c index 3e8d2e21e..8fd904042 100644 --- a/libnautilus/nautilus-lib-self-check-functions.c +++ b/libnautilus/nautilus-lib-self-check-functions.c @@ -33,6 +33,7 @@ void nautilus_run_lib_self_checks () { + nautilus_self_check_background (); nautilus_self_check_gdk_extensions (); } diff --git a/libnautilus/nautilus-lib-self-check-functions.h b/libnautilus/nautilus-lib-self-check-functions.h index dc9ada13a..2b68bd8d6 100644 --- a/libnautilus/nautilus-lib-self-check-functions.h +++ b/libnautilus/nautilus-lib-self-check-functions.h @@ -36,3 +36,4 @@ void nautilus_run_lib_self_checks (void); */ void nautilus_self_check_gdk_extensions (void); +void nautilus_self_check_background (void); diff --git a/libnautilus/nautilus-string.c b/libnautilus/nautilus-string.c new file mode 100644 index 000000000..02834386b --- /dev/null +++ b/libnautilus/nautilus-string.c @@ -0,0 +1,48 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-string.c: String routines to augment <string.h>. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "nautilus-string.h" + +size_t +nautilus_strlen (const char *string_null_allowed) +{ + return string_null_allowed == NULL ? 0 : strlen (string_null_allowed); +} + +char * +nautilus_strchr (const char *haystack_null_allowed, char needle) +{ + return haystack_null_allowed == NULL ? NULL : strchr (haystack_null_allowed, needle); +} + +int +nautilus_strcmp (const char *string_a_null_allowed, const char *string_b_null_allowed) +{ + return strcmp (string_a_null_allowed == NULL ? "" : string_a_null_allowed, + string_b_null_allowed == NULL ? "" : string_b_null_allowed); +} diff --git a/libnautilus/nautilus-string.h b/libnautilus/nautilus-string.h new file mode 100644 index 000000000..fc0dbe36c --- /dev/null +++ b/libnautilus/nautilus-string.h @@ -0,0 +1,37 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-string.h: String routines to augment <string.h>. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler <darin@eazel.com> +*/ + +#ifndef NAUTILUS_STRING_H +#define NAUTILUS_STRING_H + +#include <string.h> + +/* Versions of basic string functions that allow NULL. */ +size_t nautilus_strlen (const char *string_null_allowed); +char * nautilus_strchr (const char *haystack_null_allowed, + char needle); +int nautilus_strcmp (const char *string_a_null_allowed, + const char *string_b_null_allowed); + +#endif /* NAUTILUS_STRING_H */ diff --git a/src/file-manager/.cvsignore b/src/file-manager/.cvsignore index 95385cb6d..3cbeb2c38 100644 --- a/src/file-manager/.cvsignore +++ b/src/file-manager/.cvsignore @@ -1,5 +1,6 @@ .deps .libs +*.la *.lo GNOME_Desktop_FileOperationService-common.c GNOME_Desktop_FileOperationService-skels.c diff --git a/src/file-manager/fm-directory.c b/src/file-manager/fm-directory.c index cb662338d..db359585a 100644 --- a/src/file-manager/fm-directory.c +++ b/src/file-manager/fm-directory.c @@ -100,10 +100,10 @@ fm_directory_finalize (GtkObject *object) g_free (directory->details->hash_table_key); g_free (directory->details); - NAUTILUS_CALL_PARENT_CLASS(GTK_OBJECT_CLASS, finalize, (object)); + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); } -NAUTILUS_DEFINE_GET_TYPE_FUNCTION(FMDirectory, fm_directory, GTK_TYPE_OBJECT) +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (FMDirectory, fm_directory, GTK_TYPE_OBJECT) /** * fm_directory_get: @@ -115,11 +115,11 @@ NAUTILUS_DEFINE_GET_TYPE_FUNCTION(FMDirectory, fm_directory, GTK_TYPE_OBJECT) * If two windows are viewing the same uri, the directory object is shared. */ FMDirectory * -fm_directory_get(const char *uri) +fm_directory_get (const char *uri) { FMDirectory *directory; - g_return_val_if_fail(uri != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); /* FIXME: This currently ignores the issue of two uris that are not identical but point to the same data. @@ -127,36 +127,36 @@ fm_directory_get(const char *uri) /* Create the hash table first time through. */ if (!directory_objects) - directory_objects = g_hash_table_new(g_str_hash, g_str_equal); + directory_objects = g_hash_table_new (g_str_hash, g_str_equal); /* If the object is already in the hash table, look it up. */ - directory = g_hash_table_lookup(directory_objects, uri); + directory = g_hash_table_lookup (directory_objects, uri); if (directory != NULL) { - g_assert(FM_IS_DIRECTORY(directory)); - gtk_object_ref(GTK_OBJECT(directory)); + g_assert (FM_IS_DIRECTORY (directory)); + gtk_object_ref (GTK_OBJECT (directory)); } else { /* Create a new directory object instead. */ - directory = FM_DIRECTORY(fm_vfs_directory_new(uri)); - g_assert(strcmp(directory->details->hash_table_key, uri) == 0); + directory = FM_DIRECTORY (fm_vfs_directory_new (uri)); + g_assert (strcmp (directory->details->hash_table_key, uri) == 0); /* Put it in the hash table. */ - gtk_object_ref(GTK_OBJECT(directory)); - gtk_object_sink(GTK_OBJECT(directory)); - g_hash_table_insert(directory_objects, directory->details->hash_table_key, directory); + gtk_object_ref (GTK_OBJECT (directory)); + gtk_object_sink (GTK_OBJECT (directory)); + g_hash_table_insert (directory_objects, directory->details->hash_table_key, directory); } return directory; } void -fm_directory_get_files(FMDirectory *directory, - FMFileListCallback callback, - gpointer callback_data) +fm_directory_get_files (FMDirectory *directory, + FMFileListCallback callback, + gpointer callback_data) { - g_return_if_fail(FM_IS_DIRECTORY(directory)); - g_return_if_fail(callback); + g_return_if_fail (FM_IS_DIRECTORY (directory)); + g_return_if_fail (callback); - gtk_signal_emit(GTK_OBJECT(directory), signals[GET_FILES], callback, callback_data); + gtk_signal_emit (GTK_OBJECT (directory), signals[GET_FILES], callback, callback_data); } /* self check code */ @@ -167,30 +167,30 @@ static int data_dummy; static guint file_count; static void -get_files_cb(FMDirectory *directory, FMFileList *files, gpointer data) +get_files_cb (FMDirectory *directory, FMFileList *files, gpointer data) { - g_assert(FM_IS_DIRECTORY(directory)); - g_assert(files); - g_assert(data == &data_dummy); + g_assert (FM_IS_DIRECTORY (directory)); + g_assert (files); + g_assert (data == &data_dummy); - file_count += g_list_length(files); + file_count += g_list_length (files); } void -nautilus_self_check_fm_directory(void) +nautilus_self_check_fm_directory (void) { FMDirectory *directory; - directory = fm_directory_get("file:///etc"); + directory = fm_directory_get ("file:///etc"); - g_assert(g_hash_table_size(directory_objects) == 1); + g_assert (g_hash_table_size (directory_objects) == 1); file_count = 0; - fm_directory_get_files(directory, get_files_cb, &data_dummy); + fm_directory_get_files (directory, get_files_cb, &data_dummy); - gtk_object_unref(GTK_OBJECT(directory)); + gtk_object_unref (GTK_OBJECT (directory)); - g_assert(g_hash_table_size(directory_objects) == 0); + g_assert (g_hash_table_size (directory_objects) == 0); } #endif /* !NAUTILUS_OMIT_SELF_CHECK */ diff --git a/src/nautilus-information-panel.c b/src/nautilus-information-panel.c index bd8e61d3f..81209ecc3 100644 --- a/src/nautilus-information-panel.c +++ b/src/nautilus-information-panel.c @@ -1,3 +1,5 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + /* Nautilus * Copyright (C) 1999, 2000 Eazel, Inc. * @@ -31,346 +33,356 @@ #include "nautilus.h" #include "ntl-index-panel.h" #include <libgnomevfs/gnome-vfs-uri.h> +#include <libnautilus/nautilus-gtk-macros.h> +#include <libnautilus/nautilus-string.h> + +#define ARRAY_LENGTH(array) \ + (sizeof (array) / sizeof ((array)[0])) + +static void nautilus_index_panel_initialize_class (gpointer klass); +static void nautilus_index_panel_initialize (gpointer object, gpointer klass); +static void nautilus_index_panel_destroy (GtkObject *object); +static void nautilus_index_panel_finalize (GtkObject *object); -static void nautilus_index_panel_class_init(NautilusIndexPanelClass *klass); -static void nautilus_index_panel_init(NautilusIndexPanel *icon_view); -static void nautilus_index_panel_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time); -void nautilus_index_panel_set_meta_tabs(GtkWidget* widget, GtkWidget* new_tabs); -void nautilus_index_panel_set_uri(GtkWidget *widget, const gchar *new_uri); -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view); +static void nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, + GtkSelectionData *selection_data, + guint info, guint time); -void nautilus_index_panel_set_up_background(GtkWidget* widget, const gchar *background_data); -void nautilus_index_panel_set_up_info(GtkWidget* widget, const gchar* new_uri); -void nautilus_index_panel_set_up_label(GtkWidget* widget, const gchar *uri); -void nautilus_index_panel_set_up_logo(GtkWidget* widget, const gchar *logo_path); +static void nautilus_index_panel_set_up_background (NautilusIndexPanel *index_panel, const gchar *background_data); +static void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri); +static void nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar *uri); +static void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gchar *logo_path); -GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template); +static GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template); + +static GtkObjectClass *parent_class; /* drag and drop definitions */ enum dnd_targets_enum { - TARGET_STRING, - TARGET_COLOR, - TARGET_URI_LIST + TARGET_STRING, + TARGET_COLOR, + TARGET_URI_LIST }; static GtkTargetEntry index_dnd_target_table[] = { - { "application/x-color", 0, TARGET_COLOR }, - { "text/uri-list", 0, TARGET_URI_LIST } + { "application/x-color", 0, TARGET_COLOR }, + { "text/uri-list", 0, TARGET_URI_LIST } }; -/* private globals */ - -/* the get_type routine is boilerplate code that registers the class and returns a unique type integer */ - -guint -nautilus_index_panel_get_type (void) -{ - static guint index_panel_type = 0; - - if (!index_panel_type) - { - static const GtkTypeInfo index_panel_info = - { - "NautilusIndexPanel", - sizeof (NautilusIndexPanel), - sizeof (NautilusIndexPanelClass), - (GtkClassInitFunc) nautilus_index_panel_class_init, - (GtkObjectInitFunc) nautilus_index_panel_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - index_panel_type = gtk_type_unique (gtk_event_box_get_type (), &index_panel_info); - } - - return index_panel_type; -} +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusIndexPanel, nautilus_index_panel, GTK_TYPE_EVENT_BOX); /* initializing the class object by installing the operations we override */ static void -nautilus_index_panel_class_init (NautilusIndexPanelClass *class) +nautilus_index_panel_initialize_class (gpointer klass) { - GtkWidgetClass *widget_class; - widget_class = (GtkWidgetClass*) class; - widget_class->drag_data_received = nautilus_index_panel_drag_data_received; + GtkWidgetClass *widget_class; + + widget_class = GTK_WIDGET_CLASS (klass); + + parent_class = gtk_type_class (GTK_TYPE_EVENT_BOX); + + widget_class->drag_data_received = nautilus_index_panel_drag_data_received; } /* common routine to make the per-uri container */ static void make_per_uri_container(NautilusIndexPanel *index_panel) { - index_panel->per_uri_container = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER (index_panel->per_uri_container), 0); - gtk_widget_show(index_panel->per_uri_container); - gtk_box_pack_start(GTK_BOX(index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0); + index_panel->per_uri_container = gtk_vbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (index_panel->per_uri_container), 0); + gtk_widget_show (index_panel->per_uri_container); + gtk_box_pack_start (GTK_BOX (index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0); } /* initialize the instance's fields, create the necessary subviews, etc. */ static void -nautilus_index_panel_init (NautilusIndexPanel *index_panel) +nautilus_index_panel_initialize (gpointer object, gpointer klass) { - GtkWidget* widget = GTK_WIDGET(index_panel); - - index_panel->index_container = NULL; - index_panel->per_uri_container = NULL; - index_panel->uri = NULL; - - /* set the size of the index panel */ - - gtk_widget_set_usize(widget, 136, 400); + NautilusIndexPanel *index_panel; + GtkWidget* widget; + + index_panel = NAUTILUS_INDEX_PANEL (object); + widget = GTK_WIDGET (object); + + /* set the size of the index panel */ + gtk_widget_set_usize (widget, 136, 400); - /* create the container box */ - - index_panel->index_container = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER (index_panel->index_container), 0); - gtk_widget_show(index_panel->index_container); - gtk_container_add(GTK_CONTAINER(index_panel), index_panel->index_container); + /* create the container box */ + index_panel->index_container = gtk_vbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (index_panel->index_container), 0); + gtk_widget_show (index_panel->index_container); + gtk_container_add (GTK_CONTAINER (index_panel), index_panel->index_container); - /* allocate and install the vbox to hold the per-uri information */ - make_per_uri_container(index_panel); + /* allocate and install the vbox to hold the per-uri information */ + make_per_uri_container (index_panel); - /* allocate and install the meta-tabs (for now it's a notebook) */ + /* allocate and install the meta-tabs (for now it's a notebook) */ - index_panel->meta_tabs = gtk_notebook_new(); - gtk_widget_set_usize(index_panel->meta_tabs, 136, 200); - gtk_widget_show(index_panel->meta_tabs); - gtk_box_pack_end(GTK_BOX(index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0); + index_panel->meta_tabs = gtk_notebook_new (); + gtk_widget_set_usize (index_panel->meta_tabs, 136, 200); + gtk_widget_show (index_panel->meta_tabs); + gtk_box_pack_end (GTK_BOX (index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0); - /* prepare ourselves to receive dropped objects */ - gtk_drag_dest_set (GTK_WIDGET (index_panel), GTK_DEST_DEFAULT_MOTION | - GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, - index_dnd_target_table, 2, GDK_ACTION_COPY); + /* prepare ourselves to receive dropped objects */ + gtk_drag_dest_set (GTK_WIDGET (index_panel), + GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, + index_dnd_target_table, ARRAY_LENGTH (index_dnd_target_table), GDK_ACTION_COPY); + + index_panel->background = nautilus_background_new (); +} + +static void +nautilus_index_panel_destroy (GtkObject *object) +{ + NautilusIndexPanel *index_panel; + + index_panel = NAUTILUS_INDEX_PANEL (object); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_index_panel_finalize (GtkObject *object) +{ + NautilusIndexPanel *index_panel; + + index_panel = NAUTILUS_INDEX_PANEL (object); + + g_free (index_panel->uri); + if (index_panel->background != NULL) + gtk_object_unref (GTK_OBJECT (index_panel->background)); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); } /* create a new instance */ -GtkWidget* +NautilusIndexPanel * nautilus_index_panel_new (void) { - return GTK_WIDGET(gtk_type_new (nautilus_index_panel_get_type ())); + return NAUTILUS_INDEX_PANEL (gtk_type_new (nautilus_index_panel_get_type ())); } /* drag and drop handler for index panel */ static void -nautilus_index_panel_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time) +nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, + GtkSelectionData *selection_data, guint info, guint time) { - gchar temp_str[512]; - guint16 *data = (guint16 *)selection_data->data; - switch (info) - { - case TARGET_URI_LIST: - printf("dropped data on index panel: %s", selection_data->data); - - /* handle background images and keywords soon */ + char *color_spec; + guint16 *data; + + g_return_if_fail (NAUTILUS_IS_INDEX_PANEL (widget)); + + switch (info) + { + case TARGET_URI_LIST: + printf("dropped data on index panel: %s", selection_data->data); + + /* handle background images and keywords soon */ - /* handle images dropped on the logo specially */ + /* handle images dropped on the logo specially */ - /* handle files by setting the location to the file */ + /* handle files by setting the location to the file */ - break; + break; - - /* handle colors - for now, just use a simple color, and don't save it in the meta-data yet */ - + + /* handle colors - for now, just use a simple color, and don't save it in the meta-data yet */ + case TARGET_COLOR: - g_snprintf(temp_str, sizeof(temp_str), "rgb:%2x/%2x/%2x", data[0], data[1], data[2]); - nautilus_index_panel_set_up_background(widget, temp_str); - break; - + data = (guint16 *)selection_data->data; + color_spec = g_strdup_printf ("rgb:%04hX/%04hX/%04hX", data[0], data[1], data[2]); + nautilus_index_panel_set_up_background (NAUTILUS_INDEX_PANEL (widget), color_spec); + g_free (color_spec); + break; + default: - printf("unknown drop type: %d\n", info); + g_warning ("unknown drop type"); break; - } + } } /* add a new meta-view to the index panel */ -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view) +void nautilus_index_panel_add_meta_view (NautilusIndexPanel *index_panel, NautilusView *meta_view) { - GtkWidget *label; - const char *description; - char cbuf[32]; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - description = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); - if (!description) - { - description = cbuf; - g_snprintf(cbuf, sizeof(cbuf), "%p", meta_view); - } - label = gtk_label_new(description); - gtk_widget_show(label); + GtkWidget *label; + const char *description; + char cbuf[32]; + + g_return_if_fail (NAUTILUS_IS_INDEX_PANEL (index_panel)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); + + description = nautilus_meta_view_get_label (NAUTILUS_META_VIEW (meta_view)); + if (description == NULL) { + description = cbuf; + g_snprintf (cbuf, sizeof (cbuf), "%p", meta_view); + } + label = gtk_label_new (description); + gtk_widget_show (label); - /* - gtk_signal_connect(GTK_OBJECT(label), "button_press_event", - GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view); - */ + /* + gtk_signal_connect(GTK_OBJECT(label), "button_press_event", + GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view); + */ - gtk_notebook_prepend_page(GTK_NOTEBOOK(index_panel->meta_tabs), GTK_WIDGET(meta_view), label); - gtk_widget_show(GTK_WIDGET(meta_view)); + gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view), label); + gtk_widget_show (GTK_WIDGET (meta_view)); } /* remove the passed-in meta-view from the index panel */ -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view) +void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *index_panel, NautilusView *meta_view) { - gint pagenum; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(index_panel->meta_tabs), GTK_WIDGET(meta_view)); - g_return_if_fail(pagenum >= 0); - gtk_notebook_remove_page(GTK_NOTEBOOK(index_panel->meta_tabs), pagenum); + gint page_num; + + page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view)); + g_return_if_fail (page_num >= 0); + gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->meta_tabs), page_num); } /* set up the index panel's background. Darin's background stuff will soon replace this, but for now just set up the color */ -void nautilus_index_panel_set_up_background(GtkWidget* widget, const gchar *background_data) +void nautilus_index_panel_set_up_background (NautilusIndexPanel *index_panel, const gchar *background_data) { - GdkColor temp_color; - GtkStyle *temp_style; - - gdk_color_parse(background_data, &temp_color); - gdk_color_alloc(gtk_widget_get_colormap(widget), &temp_color); - temp_style = gtk_style_new(); - temp_style->bg[GTK_STATE_NORMAL] = temp_color; - gtk_widget_set_style(widget, gtk_style_attach(temp_style, widget->window)); + GdkColor temp_color; + GtkStyle *temp_style; + + gdk_color_parse (background_data, &temp_color); + gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (index_panel)), &temp_color); + temp_style = gtk_style_new(); + temp_style->bg[GTK_STATE_NORMAL] = temp_color; + gtk_widget_set_style (GTK_WIDGET (index_panel), + gtk_style_attach (temp_style, GTK_WIDGET (index_panel)->window)); + + nautilus_background_set_color (index_panel->background, background_data); } /* set up the logo image */ -void nautilus_index_panel_set_up_logo(GtkWidget* widget, const gchar *logo_path) +void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gchar *logo_path) { - const gchar *file_name; - GtkWidget *pix_widget; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; + gchar *file_name; + GtkWidget *pix_widget; - file_name = gnome_pixmap_file(logo_path); - pix_widget = (GtkWidget*) gnome_pixmap_new_from_file(file_name); - gtk_widget_show(pix_widget); - gtk_box_pack_start(GTK_BOX(index_panel->per_uri_container), pix_widget, 0, 0, 0); - g_free((gchar*)file_name); + file_name = gnome_pixmap_file (logo_path); + pix_widget = GTK_WIDGET (gnome_pixmap_new_from_file (file_name)); + gtk_widget_show (pix_widget); + gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), pix_widget, 0, 0, 0); + g_free (file_name); } /* utility routine (FIXME: should be located elsewhere) to find the largest font that fits */ GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template) { - GdkFont *candidate_font; - gchar font_name[512]; - gint this_width; - gint font_sizes[8] = { 28, 24, 18, 14, 12, 10, 8 }; - gint font_index = 0; + GdkFont *candidate_font = NULL; + gchar *font_name; + gint this_width; + gint font_sizes[8] = { 28, 24, 18, 14, 12, 10, 8 }; + gint font_index; - while (font_index < 8) - { - g_snprintf(font_name, sizeof(font_name), font_template, font_sizes[font_index]); - candidate_font = gdk_font_load(font_name); - this_width = gdk_string_width(candidate_font, text_to_format); - if (this_width < width) - return candidate_font; - else - gdk_font_unref(candidate_font); - font_index += 1; + for (font_index = 0; font_index < ARRAY_LENGTH (font_sizes); font_index++) { + if (candidate_font != NULL) + gdk_font_unref (candidate_font); + + font_name = g_strdup_printf (font_template, font_sizes[font_index]); + candidate_font = gdk_font_load (font_name); + g_free (font_name); - } - return candidate_font; + this_width = gdk_string_width (candidate_font, text_to_format); + if (this_width < width) + return candidate_font; + } + + return candidate_font; } /* set up the label */ -void nautilus_index_panel_set_up_label(GtkWidget* widget, const gchar *uri) +void nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar *uri) { - GtkWidget *label_widget; - const gchar *file_name; - GnomeVFSURI *vfs_uri; - GdkFont* label_font; - gchar *temp_uri = strdup(uri); - gint slash_pos = strlen(temp_uri) - 1; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* we must remove the trailing slash for vfs_get_basename to work right for us */ - if ((temp_uri[slash_pos] == '/') && (slash_pos > 0)) - temp_uri[slash_pos] = '\0'; - - vfs_uri = gnome_vfs_uri_new(temp_uri); - g_free(temp_uri); - - file_name = gnome_vfs_uri_get_basename(vfs_uri); - gnome_vfs_uri_destroy(vfs_uri); - - if (file_name == NULL) - { - return; - } - - label_widget = gtk_label_new(file_name); - gtk_box_pack_start(GTK_BOX(index_panel->per_uri_container), label_widget, 0, 0, 0); - - label_font = select_font(file_name, widget->allocation.width - 4, "-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*"); - g_free((gchar*) file_name); - - if (label_font != NULL) - { - GtkStyle *temp_style; - gtk_widget_realize(label_widget); - temp_style = gtk_style_new(); - temp_style->font = label_font; - gtk_widget_set_style(label_widget, gtk_style_attach(temp_style, label_widget->window)); - } - - gtk_widget_show(label_widget); + GtkWidget *label_widget; + const gchar *file_name; + GnomeVFSURI *vfs_uri; + GdkFont *label_font; + char *temp_uri; + int slash_pos; + + /* remove the trailing slash so vfs_get_basename will work right for us */ + temp_uri = g_strdup (uri); + slash_pos = strlen (temp_uri) - 1; + if (slash_pos > 0 && temp_uri[slash_pos] == '/') + temp_uri[slash_pos] = '\0'; + + vfs_uri = gnome_vfs_uri_new(temp_uri); + g_free(temp_uri); + + file_name = gnome_vfs_uri_get_basename (vfs_uri); + + if (file_name != NULL) { + label_widget = gtk_label_new (file_name); + gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), label_widget, 0, 0, 0); + + label_font = select_font(file_name, GTK_WIDGET (index_panel)->allocation.width - 4, + "-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*"); + + if (label_font != NULL) { + GtkStyle *temp_style; + gtk_widget_realize (label_widget); + temp_style = gtk_style_new (); + temp_style->font = label_font; + gtk_widget_set_style (label_widget, gtk_style_attach (temp_style, label_widget->window)); + } + + gtk_widget_show(label_widget); + } + + gnome_vfs_uri_unref (vfs_uri); } /* this routine populates the index panel with the per-uri information */ -void nautilus_index_panel_set_up_info(GtkWidget* widget, const gchar* new_uri) -{ - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* set up the background from the metadata. At first, just use hardwired backgrounds */ - nautilus_index_panel_set_up_background(widget, "rgb:DD/DD/FF"); - - /* next, install the logo image. */ - /* For now, just use a fixed folder image */ - nautilus_index_panel_set_up_logo(widget, "nautilus/i-directory.png"); +void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri) +{ + /* set up the background from the metadata. At first, just use hardwired backgrounds */ + nautilus_index_panel_set_up_background (index_panel, "rgb:DDDD/DDDD/FFFF"); - /* add the name, discarding all but the last part of the path */ - /* soon, we'll use the biggest font that fit, for now don't worry about it */ - nautilus_index_panel_set_up_label(widget, new_uri); - - /* format and install the type-dependent descriptive info */ - - /* add the description text, if any. Try to fetch it from the notes file if none is present */ + /* next, install the logo image. */ + /* For now, just use a fixed folder image */ + nautilus_index_panel_set_up_logo (index_panel, "nautilus/i-directory.png"); - /* add keywords if we got any */ + /* add the name, discarding all but the last part of the path */ + /* soon, we'll use the biggest font that fit, for now don't worry about it */ + nautilus_index_panel_set_up_label (index_panel, new_uri); + + /* format and install the type-dependent descriptive info */ + + /* add the description text, if any. Try to fetch it from the notes file if none is present */ + + /* add keywords if we got any */ } /* here is the key routine that populates the index panel with the appropriate information when the uri changes */ -void nautilus_index_panel_set_uri(GtkWidget* widget, const gchar* new_uri) +void nautilus_index_panel_set_uri (NautilusIndexPanel *index_panel, const gchar* new_uri) { - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* there's nothing to do if the uri is the same as the current one */ - - if (index_panel->uri && !strcmp(index_panel->uri, new_uri)) - return; - - if (index_panel->uri) - g_free(index_panel->uri); - - index_panel->uri = g_strdup(new_uri); - - /* get rid of the old widgets in the per_uri container */ - gtk_widget_destroy(index_panel->per_uri_container); - make_per_uri_container(index_panel); - - /* populate the per-uri box with the info */ - nautilus_index_panel_set_up_info(widget, new_uri); - } - + /* there's nothing to do if the uri is the same as the current one */ + + if (nautilus_strcmp (index_panel->uri, new_uri) == 0) + return; + + g_free (index_panel->uri); + index_panel->uri = g_strdup (new_uri); + + /* get rid of the old widgets in the per_uri container */ + gtk_widget_destroy (index_panel->per_uri_container); + make_per_uri_container (index_panel); + + /* populate the per-uri box with the info */ + nautilus_index_panel_set_up_info (index_panel, new_uri); +} diff --git a/src/nautilus-information-panel.h b/src/nautilus-information-panel.h index 06a0b2cec..8e8f1e28d 100644 --- a/src/nautilus-information-panel.h +++ b/src/nautilus-information-panel.h @@ -1,3 +1,5 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + /* Nautilus * Copyright (C) 1999, 2000 Eazel, Inc. * @@ -19,53 +21,52 @@ * * This is the header file for the index panel widget, which displays overview information * in a vertical panel and hosts the meta-views. - * */ -#ifndef __nautilus_index_panel_H__ -#define __nautilus_index_panel_H__ - +#ifndef NTL_INDEX_PANEL_H +#define NTL_INDEX_PANEL_H #include <gdk/gdk.h> #include <gtk/gtkwidget.h> #include "nautilus.h" +#include <libnautilus/nautilus-background.h> -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define nautilus_index_panel(obj) GTK_CHECK_CAST (obj, nautilus_index_panel_get_type (), NautilusIndexPanel) -#define nautilus_index_panel_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, nautilus_index_panel_get_type (), NautilusIndexPanelClass) -#define NAUTILUS_IS_INDEX_PANEL(obj) GTK_CHECK_TYPE (obj, nautilus_index_panel_get_type ()) - - -typedef struct _NautilusIndexPanel NautilusIndexPanel; +typedef struct _NautilusIndexPanel NautilusIndexPanel; typedef struct _NautilusIndexPanelClass NautilusIndexPanelClass; +#define NAUTILUS_TYPE_INDEX_PANEL \ + (nautilus_index_panel_get_type ()) +#define NAUTILUS_INDEX_PANEL(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_INDEX_PANEL, NautilusIndexPanel)) +#define NAUTILUS_INDEX_PANEL_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_INDEX_PANEL, NautilusIndexPanelClass)) +#define NAUTILUS_IS_INDEX_PANEL(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_INDEX_PANEL)) +#define NAUTILUS_IS_INDEX_PANEL_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_INDEX_PANEL)) + struct _NautilusIndexPanel { - GtkEventBox event_box; - GtkWidget* index_container; - GtkWidget* per_uri_container; - GtkWidget* meta_tabs; - gchar* uri; + GtkEventBox event_box; + GtkWidget *index_container; + GtkWidget *per_uri_container; + GtkWidget *meta_tabs; + gchar *uri; + NautilusBackground *background; }; struct _NautilusIndexPanelClass { - GtkEventBoxClass parent_class; + GtkEventBoxClass parent_class; }; -guint nautilus_index_panel_get_type(void); -GtkWidget* nautilus_index_panel_new(void); -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_set_uri(GtkWidget* widget, const gchar* new_uri); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +GtkType nautilus_index_panel_get_type (void); +NautilusIndexPanel *nautilus_index_panel_new (void); +void nautilus_index_panel_add_meta_view (NautilusIndexPanel *panel, + NautilusView *meta_view); +void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *panel, + NautilusView *meta_view); +void nautilus_index_panel_set_uri (NautilusIndexPanel *panel, + const gchar *new_uri); -#endif /* __nautilus_index_panel_H__ */ +#endif /* NTL_INDEX_PANEL_H */ diff --git a/src/nautilus-navigation-window.c b/src/nautilus-navigation-window.c index b804fcfb7..bace01b7e 100644 --- a/src/nautilus-navigation-window.c +++ b/src/nautilus-navigation-window.c @@ -378,7 +378,7 @@ nautilus_window_set_status(NautilusWindow *window, const char *txt) } void -nautilus_window_goto_uri(NautilusWindow *window, const char *uri) +nautilus_window_goto_uri (NautilusWindow *window, const char *uri) { Nautilus_NavigationRequestInfo navinfo; @@ -387,8 +387,8 @@ nautilus_window_goto_uri(NautilusWindow *window, const char *uri) navinfo.new_window_default = navinfo.new_window_suggested = Nautilus_V_FALSE; navinfo.new_window_enforced = Nautilus_V_UNKNOWN; - nautilus_window_request_location_change(window, &navinfo, NULL); - nautilus_index_panel_set_uri(window->index_panel, uri); + nautilus_window_request_location_change (window, &navinfo, NULL); + nautilus_index_panel_set_uri (NAUTILUS_INDEX_PANEL (window->index_panel), uri); } static void @@ -491,8 +491,8 @@ nautilus_window_constructed(NautilusWindow *window) gtk_widget_show(temp_frame); window->index_panel = nautilus_index_panel_new(); - gtk_widget_show(window->index_panel); - gtk_container_add(GTK_CONTAINER(temp_frame), window->index_panel); + gtk_widget_show (GTK_WIDGET (window->index_panel)); + gtk_container_add(GTK_CONTAINER(temp_frame), GTK_WIDGET (window->index_panel)); #ifdef CONTENTS_AS_HBOX gtk_box_pack_start(GTK_BOX(window->content_hbox), temp_frame, FALSE, FALSE, 0); @@ -756,12 +756,11 @@ nautilus_window_set_content_view(NautilusWindow *window, NautilusView *content_v void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) { + g_return_if_fail (!g_slist_find (window->meta_views, meta_view)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); - g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - nautilus_index_panel_add_meta_view(window->index_panel, meta_view); - window->meta_views = g_slist_prepend(window->meta_views, meta_view); + nautilus_index_panel_add_meta_view (window->index_panel, meta_view); + window->meta_views = g_slist_prepend (window->meta_views, meta_view); } void @@ -812,7 +811,7 @@ nautilus_window_fwd (GtkWidget *btn, NautilusWindow *window) const char * nautilus_window_get_requested_uri (NautilusWindow *window) { - return window->ni->requested_uri; + return window->ni == NULL ? NULL : window->ni->requested_uri; } GnomeUIHandler * diff --git a/src/nautilus-navigation-window.h b/src/nautilus-navigation-window.h index 61bd916dd..9e020e41c 100644 --- a/src/nautilus-navigation-window.h +++ b/src/nautilus-navigation-window.h @@ -30,6 +30,7 @@ #include <libgnomeui/gnome-app.h> #include "ntl-types.h" #include "ntl-view.h" +#include "ntl-index-panel.h" #define NAUTILUS_TYPE_WINDOW (nautilus_window_get_type()) #define NAUTILUS_WINDOW(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_WINDOW, NautilusWindow)) @@ -57,7 +58,8 @@ struct _NautilusWindow { GSList *meta_views; /* UI stuff */ - GtkWidget *index_panel, *content_hbox, *btn_back, *btn_fwd; + NautilusIndexPanel *index_panel; + GtkWidget *content_hbox, *btn_back, *btn_fwd; GtkWidget *option_cvtype, *menu_cvtype, *ent_uri; guint statusbar_ctx, statusbar_clear_id; diff --git a/src/nautilus-object-window.c b/src/nautilus-object-window.c index b804fcfb7..bace01b7e 100644 --- a/src/nautilus-object-window.c +++ b/src/nautilus-object-window.c @@ -378,7 +378,7 @@ nautilus_window_set_status(NautilusWindow *window, const char *txt) } void -nautilus_window_goto_uri(NautilusWindow *window, const char *uri) +nautilus_window_goto_uri (NautilusWindow *window, const char *uri) { Nautilus_NavigationRequestInfo navinfo; @@ -387,8 +387,8 @@ nautilus_window_goto_uri(NautilusWindow *window, const char *uri) navinfo.new_window_default = navinfo.new_window_suggested = Nautilus_V_FALSE; navinfo.new_window_enforced = Nautilus_V_UNKNOWN; - nautilus_window_request_location_change(window, &navinfo, NULL); - nautilus_index_panel_set_uri(window->index_panel, uri); + nautilus_window_request_location_change (window, &navinfo, NULL); + nautilus_index_panel_set_uri (NAUTILUS_INDEX_PANEL (window->index_panel), uri); } static void @@ -491,8 +491,8 @@ nautilus_window_constructed(NautilusWindow *window) gtk_widget_show(temp_frame); window->index_panel = nautilus_index_panel_new(); - gtk_widget_show(window->index_panel); - gtk_container_add(GTK_CONTAINER(temp_frame), window->index_panel); + gtk_widget_show (GTK_WIDGET (window->index_panel)); + gtk_container_add(GTK_CONTAINER(temp_frame), GTK_WIDGET (window->index_panel)); #ifdef CONTENTS_AS_HBOX gtk_box_pack_start(GTK_BOX(window->content_hbox), temp_frame, FALSE, FALSE, 0); @@ -756,12 +756,11 @@ nautilus_window_set_content_view(NautilusWindow *window, NautilusView *content_v void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) { + g_return_if_fail (!g_slist_find (window->meta_views, meta_view)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); - g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - nautilus_index_panel_add_meta_view(window->index_panel, meta_view); - window->meta_views = g_slist_prepend(window->meta_views, meta_view); + nautilus_index_panel_add_meta_view (window->index_panel, meta_view); + window->meta_views = g_slist_prepend (window->meta_views, meta_view); } void @@ -812,7 +811,7 @@ nautilus_window_fwd (GtkWidget *btn, NautilusWindow *window) const char * nautilus_window_get_requested_uri (NautilusWindow *window) { - return window->ni->requested_uri; + return window->ni == NULL ? NULL : window->ni->requested_uri; } GnomeUIHandler * diff --git a/src/nautilus-object-window.h b/src/nautilus-object-window.h index 61bd916dd..9e020e41c 100644 --- a/src/nautilus-object-window.h +++ b/src/nautilus-object-window.h @@ -30,6 +30,7 @@ #include <libgnomeui/gnome-app.h> #include "ntl-types.h" #include "ntl-view.h" +#include "ntl-index-panel.h" #define NAUTILUS_TYPE_WINDOW (nautilus_window_get_type()) #define NAUTILUS_WINDOW(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_WINDOW, NautilusWindow)) @@ -57,7 +58,8 @@ struct _NautilusWindow { GSList *meta_views; /* UI stuff */ - GtkWidget *index_panel, *content_hbox, *btn_back, *btn_fwd; + NautilusIndexPanel *index_panel; + GtkWidget *content_hbox, *btn_back, *btn_fwd; GtkWidget *option_cvtype, *menu_cvtype, *ent_uri; guint statusbar_ctx, statusbar_clear_id; diff --git a/src/nautilus-sidebar.c b/src/nautilus-sidebar.c index bd8e61d3f..81209ecc3 100644 --- a/src/nautilus-sidebar.c +++ b/src/nautilus-sidebar.c @@ -1,3 +1,5 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + /* Nautilus * Copyright (C) 1999, 2000 Eazel, Inc. * @@ -31,346 +33,356 @@ #include "nautilus.h" #include "ntl-index-panel.h" #include <libgnomevfs/gnome-vfs-uri.h> +#include <libnautilus/nautilus-gtk-macros.h> +#include <libnautilus/nautilus-string.h> + +#define ARRAY_LENGTH(array) \ + (sizeof (array) / sizeof ((array)[0])) + +static void nautilus_index_panel_initialize_class (gpointer klass); +static void nautilus_index_panel_initialize (gpointer object, gpointer klass); +static void nautilus_index_panel_destroy (GtkObject *object); +static void nautilus_index_panel_finalize (GtkObject *object); -static void nautilus_index_panel_class_init(NautilusIndexPanelClass *klass); -static void nautilus_index_panel_init(NautilusIndexPanel *icon_view); -static void nautilus_index_panel_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time); -void nautilus_index_panel_set_meta_tabs(GtkWidget* widget, GtkWidget* new_tabs); -void nautilus_index_panel_set_uri(GtkWidget *widget, const gchar *new_uri); -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view); +static void nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, + GtkSelectionData *selection_data, + guint info, guint time); -void nautilus_index_panel_set_up_background(GtkWidget* widget, const gchar *background_data); -void nautilus_index_panel_set_up_info(GtkWidget* widget, const gchar* new_uri); -void nautilus_index_panel_set_up_label(GtkWidget* widget, const gchar *uri); -void nautilus_index_panel_set_up_logo(GtkWidget* widget, const gchar *logo_path); +static void nautilus_index_panel_set_up_background (NautilusIndexPanel *index_panel, const gchar *background_data); +static void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri); +static void nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar *uri); +static void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gchar *logo_path); -GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template); +static GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template); + +static GtkObjectClass *parent_class; /* drag and drop definitions */ enum dnd_targets_enum { - TARGET_STRING, - TARGET_COLOR, - TARGET_URI_LIST + TARGET_STRING, + TARGET_COLOR, + TARGET_URI_LIST }; static GtkTargetEntry index_dnd_target_table[] = { - { "application/x-color", 0, TARGET_COLOR }, - { "text/uri-list", 0, TARGET_URI_LIST } + { "application/x-color", 0, TARGET_COLOR }, + { "text/uri-list", 0, TARGET_URI_LIST } }; -/* private globals */ - -/* the get_type routine is boilerplate code that registers the class and returns a unique type integer */ - -guint -nautilus_index_panel_get_type (void) -{ - static guint index_panel_type = 0; - - if (!index_panel_type) - { - static const GtkTypeInfo index_panel_info = - { - "NautilusIndexPanel", - sizeof (NautilusIndexPanel), - sizeof (NautilusIndexPanelClass), - (GtkClassInitFunc) nautilus_index_panel_class_init, - (GtkObjectInitFunc) nautilus_index_panel_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - index_panel_type = gtk_type_unique (gtk_event_box_get_type (), &index_panel_info); - } - - return index_panel_type; -} +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusIndexPanel, nautilus_index_panel, GTK_TYPE_EVENT_BOX); /* initializing the class object by installing the operations we override */ static void -nautilus_index_panel_class_init (NautilusIndexPanelClass *class) +nautilus_index_panel_initialize_class (gpointer klass) { - GtkWidgetClass *widget_class; - widget_class = (GtkWidgetClass*) class; - widget_class->drag_data_received = nautilus_index_panel_drag_data_received; + GtkWidgetClass *widget_class; + + widget_class = GTK_WIDGET_CLASS (klass); + + parent_class = gtk_type_class (GTK_TYPE_EVENT_BOX); + + widget_class->drag_data_received = nautilus_index_panel_drag_data_received; } /* common routine to make the per-uri container */ static void make_per_uri_container(NautilusIndexPanel *index_panel) { - index_panel->per_uri_container = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER (index_panel->per_uri_container), 0); - gtk_widget_show(index_panel->per_uri_container); - gtk_box_pack_start(GTK_BOX(index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0); + index_panel->per_uri_container = gtk_vbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (index_panel->per_uri_container), 0); + gtk_widget_show (index_panel->per_uri_container); + gtk_box_pack_start (GTK_BOX (index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0); } /* initialize the instance's fields, create the necessary subviews, etc. */ static void -nautilus_index_panel_init (NautilusIndexPanel *index_panel) +nautilus_index_panel_initialize (gpointer object, gpointer klass) { - GtkWidget* widget = GTK_WIDGET(index_panel); - - index_panel->index_container = NULL; - index_panel->per_uri_container = NULL; - index_panel->uri = NULL; - - /* set the size of the index panel */ - - gtk_widget_set_usize(widget, 136, 400); + NautilusIndexPanel *index_panel; + GtkWidget* widget; + + index_panel = NAUTILUS_INDEX_PANEL (object); + widget = GTK_WIDGET (object); + + /* set the size of the index panel */ + gtk_widget_set_usize (widget, 136, 400); - /* create the container box */ - - index_panel->index_container = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER (index_panel->index_container), 0); - gtk_widget_show(index_panel->index_container); - gtk_container_add(GTK_CONTAINER(index_panel), index_panel->index_container); + /* create the container box */ + index_panel->index_container = gtk_vbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (index_panel->index_container), 0); + gtk_widget_show (index_panel->index_container); + gtk_container_add (GTK_CONTAINER (index_panel), index_panel->index_container); - /* allocate and install the vbox to hold the per-uri information */ - make_per_uri_container(index_panel); + /* allocate and install the vbox to hold the per-uri information */ + make_per_uri_container (index_panel); - /* allocate and install the meta-tabs (for now it's a notebook) */ + /* allocate and install the meta-tabs (for now it's a notebook) */ - index_panel->meta_tabs = gtk_notebook_new(); - gtk_widget_set_usize(index_panel->meta_tabs, 136, 200); - gtk_widget_show(index_panel->meta_tabs); - gtk_box_pack_end(GTK_BOX(index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0); + index_panel->meta_tabs = gtk_notebook_new (); + gtk_widget_set_usize (index_panel->meta_tabs, 136, 200); + gtk_widget_show (index_panel->meta_tabs); + gtk_box_pack_end (GTK_BOX (index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0); - /* prepare ourselves to receive dropped objects */ - gtk_drag_dest_set (GTK_WIDGET (index_panel), GTK_DEST_DEFAULT_MOTION | - GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, - index_dnd_target_table, 2, GDK_ACTION_COPY); + /* prepare ourselves to receive dropped objects */ + gtk_drag_dest_set (GTK_WIDGET (index_panel), + GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, + index_dnd_target_table, ARRAY_LENGTH (index_dnd_target_table), GDK_ACTION_COPY); + + index_panel->background = nautilus_background_new (); +} + +static void +nautilus_index_panel_destroy (GtkObject *object) +{ + NautilusIndexPanel *index_panel; + + index_panel = NAUTILUS_INDEX_PANEL (object); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_index_panel_finalize (GtkObject *object) +{ + NautilusIndexPanel *index_panel; + + index_panel = NAUTILUS_INDEX_PANEL (object); + + g_free (index_panel->uri); + if (index_panel->background != NULL) + gtk_object_unref (GTK_OBJECT (index_panel->background)); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); } /* create a new instance */ -GtkWidget* +NautilusIndexPanel * nautilus_index_panel_new (void) { - return GTK_WIDGET(gtk_type_new (nautilus_index_panel_get_type ())); + return NAUTILUS_INDEX_PANEL (gtk_type_new (nautilus_index_panel_get_type ())); } /* drag and drop handler for index panel */ static void -nautilus_index_panel_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time) +nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, + GtkSelectionData *selection_data, guint info, guint time) { - gchar temp_str[512]; - guint16 *data = (guint16 *)selection_data->data; - switch (info) - { - case TARGET_URI_LIST: - printf("dropped data on index panel: %s", selection_data->data); - - /* handle background images and keywords soon */ + char *color_spec; + guint16 *data; + + g_return_if_fail (NAUTILUS_IS_INDEX_PANEL (widget)); + + switch (info) + { + case TARGET_URI_LIST: + printf("dropped data on index panel: %s", selection_data->data); + + /* handle background images and keywords soon */ - /* handle images dropped on the logo specially */ + /* handle images dropped on the logo specially */ - /* handle files by setting the location to the file */ + /* handle files by setting the location to the file */ - break; + break; - - /* handle colors - for now, just use a simple color, and don't save it in the meta-data yet */ - + + /* handle colors - for now, just use a simple color, and don't save it in the meta-data yet */ + case TARGET_COLOR: - g_snprintf(temp_str, sizeof(temp_str), "rgb:%2x/%2x/%2x", data[0], data[1], data[2]); - nautilus_index_panel_set_up_background(widget, temp_str); - break; - + data = (guint16 *)selection_data->data; + color_spec = g_strdup_printf ("rgb:%04hX/%04hX/%04hX", data[0], data[1], data[2]); + nautilus_index_panel_set_up_background (NAUTILUS_INDEX_PANEL (widget), color_spec); + g_free (color_spec); + break; + default: - printf("unknown drop type: %d\n", info); + g_warning ("unknown drop type"); break; - } + } } /* add a new meta-view to the index panel */ -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view) +void nautilus_index_panel_add_meta_view (NautilusIndexPanel *index_panel, NautilusView *meta_view) { - GtkWidget *label; - const char *description; - char cbuf[32]; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - description = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); - if (!description) - { - description = cbuf; - g_snprintf(cbuf, sizeof(cbuf), "%p", meta_view); - } - label = gtk_label_new(description); - gtk_widget_show(label); + GtkWidget *label; + const char *description; + char cbuf[32]; + + g_return_if_fail (NAUTILUS_IS_INDEX_PANEL (index_panel)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); + + description = nautilus_meta_view_get_label (NAUTILUS_META_VIEW (meta_view)); + if (description == NULL) { + description = cbuf; + g_snprintf (cbuf, sizeof (cbuf), "%p", meta_view); + } + label = gtk_label_new (description); + gtk_widget_show (label); - /* - gtk_signal_connect(GTK_OBJECT(label), "button_press_event", - GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view); - */ + /* + gtk_signal_connect(GTK_OBJECT(label), "button_press_event", + GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view); + */ - gtk_notebook_prepend_page(GTK_NOTEBOOK(index_panel->meta_tabs), GTK_WIDGET(meta_view), label); - gtk_widget_show(GTK_WIDGET(meta_view)); + gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view), label); + gtk_widget_show (GTK_WIDGET (meta_view)); } /* remove the passed-in meta-view from the index panel */ -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view) +void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *index_panel, NautilusView *meta_view) { - gint pagenum; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(index_panel->meta_tabs), GTK_WIDGET(meta_view)); - g_return_if_fail(pagenum >= 0); - gtk_notebook_remove_page(GTK_NOTEBOOK(index_panel->meta_tabs), pagenum); + gint page_num; + + page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view)); + g_return_if_fail (page_num >= 0); + gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->meta_tabs), page_num); } /* set up the index panel's background. Darin's background stuff will soon replace this, but for now just set up the color */ -void nautilus_index_panel_set_up_background(GtkWidget* widget, const gchar *background_data) +void nautilus_index_panel_set_up_background (NautilusIndexPanel *index_panel, const gchar *background_data) { - GdkColor temp_color; - GtkStyle *temp_style; - - gdk_color_parse(background_data, &temp_color); - gdk_color_alloc(gtk_widget_get_colormap(widget), &temp_color); - temp_style = gtk_style_new(); - temp_style->bg[GTK_STATE_NORMAL] = temp_color; - gtk_widget_set_style(widget, gtk_style_attach(temp_style, widget->window)); + GdkColor temp_color; + GtkStyle *temp_style; + + gdk_color_parse (background_data, &temp_color); + gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (index_panel)), &temp_color); + temp_style = gtk_style_new(); + temp_style->bg[GTK_STATE_NORMAL] = temp_color; + gtk_widget_set_style (GTK_WIDGET (index_panel), + gtk_style_attach (temp_style, GTK_WIDGET (index_panel)->window)); + + nautilus_background_set_color (index_panel->background, background_data); } /* set up the logo image */ -void nautilus_index_panel_set_up_logo(GtkWidget* widget, const gchar *logo_path) +void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gchar *logo_path) { - const gchar *file_name; - GtkWidget *pix_widget; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; + gchar *file_name; + GtkWidget *pix_widget; - file_name = gnome_pixmap_file(logo_path); - pix_widget = (GtkWidget*) gnome_pixmap_new_from_file(file_name); - gtk_widget_show(pix_widget); - gtk_box_pack_start(GTK_BOX(index_panel->per_uri_container), pix_widget, 0, 0, 0); - g_free((gchar*)file_name); + file_name = gnome_pixmap_file (logo_path); + pix_widget = GTK_WIDGET (gnome_pixmap_new_from_file (file_name)); + gtk_widget_show (pix_widget); + gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), pix_widget, 0, 0, 0); + g_free (file_name); } /* utility routine (FIXME: should be located elsewhere) to find the largest font that fits */ GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template) { - GdkFont *candidate_font; - gchar font_name[512]; - gint this_width; - gint font_sizes[8] = { 28, 24, 18, 14, 12, 10, 8 }; - gint font_index = 0; + GdkFont *candidate_font = NULL; + gchar *font_name; + gint this_width; + gint font_sizes[8] = { 28, 24, 18, 14, 12, 10, 8 }; + gint font_index; - while (font_index < 8) - { - g_snprintf(font_name, sizeof(font_name), font_template, font_sizes[font_index]); - candidate_font = gdk_font_load(font_name); - this_width = gdk_string_width(candidate_font, text_to_format); - if (this_width < width) - return candidate_font; - else - gdk_font_unref(candidate_font); - font_index += 1; + for (font_index = 0; font_index < ARRAY_LENGTH (font_sizes); font_index++) { + if (candidate_font != NULL) + gdk_font_unref (candidate_font); + + font_name = g_strdup_printf (font_template, font_sizes[font_index]); + candidate_font = gdk_font_load (font_name); + g_free (font_name); - } - return candidate_font; + this_width = gdk_string_width (candidate_font, text_to_format); + if (this_width < width) + return candidate_font; + } + + return candidate_font; } /* set up the label */ -void nautilus_index_panel_set_up_label(GtkWidget* widget, const gchar *uri) +void nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar *uri) { - GtkWidget *label_widget; - const gchar *file_name; - GnomeVFSURI *vfs_uri; - GdkFont* label_font; - gchar *temp_uri = strdup(uri); - gint slash_pos = strlen(temp_uri) - 1; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* we must remove the trailing slash for vfs_get_basename to work right for us */ - if ((temp_uri[slash_pos] == '/') && (slash_pos > 0)) - temp_uri[slash_pos] = '\0'; - - vfs_uri = gnome_vfs_uri_new(temp_uri); - g_free(temp_uri); - - file_name = gnome_vfs_uri_get_basename(vfs_uri); - gnome_vfs_uri_destroy(vfs_uri); - - if (file_name == NULL) - { - return; - } - - label_widget = gtk_label_new(file_name); - gtk_box_pack_start(GTK_BOX(index_panel->per_uri_container), label_widget, 0, 0, 0); - - label_font = select_font(file_name, widget->allocation.width - 4, "-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*"); - g_free((gchar*) file_name); - - if (label_font != NULL) - { - GtkStyle *temp_style; - gtk_widget_realize(label_widget); - temp_style = gtk_style_new(); - temp_style->font = label_font; - gtk_widget_set_style(label_widget, gtk_style_attach(temp_style, label_widget->window)); - } - - gtk_widget_show(label_widget); + GtkWidget *label_widget; + const gchar *file_name; + GnomeVFSURI *vfs_uri; + GdkFont *label_font; + char *temp_uri; + int slash_pos; + + /* remove the trailing slash so vfs_get_basename will work right for us */ + temp_uri = g_strdup (uri); + slash_pos = strlen (temp_uri) - 1; + if (slash_pos > 0 && temp_uri[slash_pos] == '/') + temp_uri[slash_pos] = '\0'; + + vfs_uri = gnome_vfs_uri_new(temp_uri); + g_free(temp_uri); + + file_name = gnome_vfs_uri_get_basename (vfs_uri); + + if (file_name != NULL) { + label_widget = gtk_label_new (file_name); + gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), label_widget, 0, 0, 0); + + label_font = select_font(file_name, GTK_WIDGET (index_panel)->allocation.width - 4, + "-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*"); + + if (label_font != NULL) { + GtkStyle *temp_style; + gtk_widget_realize (label_widget); + temp_style = gtk_style_new (); + temp_style->font = label_font; + gtk_widget_set_style (label_widget, gtk_style_attach (temp_style, label_widget->window)); + } + + gtk_widget_show(label_widget); + } + + gnome_vfs_uri_unref (vfs_uri); } /* this routine populates the index panel with the per-uri information */ -void nautilus_index_panel_set_up_info(GtkWidget* widget, const gchar* new_uri) -{ - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* set up the background from the metadata. At first, just use hardwired backgrounds */ - nautilus_index_panel_set_up_background(widget, "rgb:DD/DD/FF"); - - /* next, install the logo image. */ - /* For now, just use a fixed folder image */ - nautilus_index_panel_set_up_logo(widget, "nautilus/i-directory.png"); +void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri) +{ + /* set up the background from the metadata. At first, just use hardwired backgrounds */ + nautilus_index_panel_set_up_background (index_panel, "rgb:DDDD/DDDD/FFFF"); - /* add the name, discarding all but the last part of the path */ - /* soon, we'll use the biggest font that fit, for now don't worry about it */ - nautilus_index_panel_set_up_label(widget, new_uri); - - /* format and install the type-dependent descriptive info */ - - /* add the description text, if any. Try to fetch it from the notes file if none is present */ + /* next, install the logo image. */ + /* For now, just use a fixed folder image */ + nautilus_index_panel_set_up_logo (index_panel, "nautilus/i-directory.png"); - /* add keywords if we got any */ + /* add the name, discarding all but the last part of the path */ + /* soon, we'll use the biggest font that fit, for now don't worry about it */ + nautilus_index_panel_set_up_label (index_panel, new_uri); + + /* format and install the type-dependent descriptive info */ + + /* add the description text, if any. Try to fetch it from the notes file if none is present */ + + /* add keywords if we got any */ } /* here is the key routine that populates the index panel with the appropriate information when the uri changes */ -void nautilus_index_panel_set_uri(GtkWidget* widget, const gchar* new_uri) +void nautilus_index_panel_set_uri (NautilusIndexPanel *index_panel, const gchar* new_uri) { - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* there's nothing to do if the uri is the same as the current one */ - - if (index_panel->uri && !strcmp(index_panel->uri, new_uri)) - return; - - if (index_panel->uri) - g_free(index_panel->uri); - - index_panel->uri = g_strdup(new_uri); - - /* get rid of the old widgets in the per_uri container */ - gtk_widget_destroy(index_panel->per_uri_container); - make_per_uri_container(index_panel); - - /* populate the per-uri box with the info */ - nautilus_index_panel_set_up_info(widget, new_uri); - } - + /* there's nothing to do if the uri is the same as the current one */ + + if (nautilus_strcmp (index_panel->uri, new_uri) == 0) + return; + + g_free (index_panel->uri); + index_panel->uri = g_strdup (new_uri); + + /* get rid of the old widgets in the per_uri container */ + gtk_widget_destroy (index_panel->per_uri_container); + make_per_uri_container (index_panel); + + /* populate the per-uri box with the info */ + nautilus_index_panel_set_up_info (index_panel, new_uri); +} diff --git a/src/nautilus-sidebar.h b/src/nautilus-sidebar.h index 06a0b2cec..8e8f1e28d 100644 --- a/src/nautilus-sidebar.h +++ b/src/nautilus-sidebar.h @@ -1,3 +1,5 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + /* Nautilus * Copyright (C) 1999, 2000 Eazel, Inc. * @@ -19,53 +21,52 @@ * * This is the header file for the index panel widget, which displays overview information * in a vertical panel and hosts the meta-views. - * */ -#ifndef __nautilus_index_panel_H__ -#define __nautilus_index_panel_H__ - +#ifndef NTL_INDEX_PANEL_H +#define NTL_INDEX_PANEL_H #include <gdk/gdk.h> #include <gtk/gtkwidget.h> #include "nautilus.h" +#include <libnautilus/nautilus-background.h> -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define nautilus_index_panel(obj) GTK_CHECK_CAST (obj, nautilus_index_panel_get_type (), NautilusIndexPanel) -#define nautilus_index_panel_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, nautilus_index_panel_get_type (), NautilusIndexPanelClass) -#define NAUTILUS_IS_INDEX_PANEL(obj) GTK_CHECK_TYPE (obj, nautilus_index_panel_get_type ()) - - -typedef struct _NautilusIndexPanel NautilusIndexPanel; +typedef struct _NautilusIndexPanel NautilusIndexPanel; typedef struct _NautilusIndexPanelClass NautilusIndexPanelClass; +#define NAUTILUS_TYPE_INDEX_PANEL \ + (nautilus_index_panel_get_type ()) +#define NAUTILUS_INDEX_PANEL(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_INDEX_PANEL, NautilusIndexPanel)) +#define NAUTILUS_INDEX_PANEL_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_INDEX_PANEL, NautilusIndexPanelClass)) +#define NAUTILUS_IS_INDEX_PANEL(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_INDEX_PANEL)) +#define NAUTILUS_IS_INDEX_PANEL_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_INDEX_PANEL)) + struct _NautilusIndexPanel { - GtkEventBox event_box; - GtkWidget* index_container; - GtkWidget* per_uri_container; - GtkWidget* meta_tabs; - gchar* uri; + GtkEventBox event_box; + GtkWidget *index_container; + GtkWidget *per_uri_container; + GtkWidget *meta_tabs; + gchar *uri; + NautilusBackground *background; }; struct _NautilusIndexPanelClass { - GtkEventBoxClass parent_class; + GtkEventBoxClass parent_class; }; -guint nautilus_index_panel_get_type(void); -GtkWidget* nautilus_index_panel_new(void); -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_set_uri(GtkWidget* widget, const gchar* new_uri); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +GtkType nautilus_index_panel_get_type (void); +NautilusIndexPanel *nautilus_index_panel_new (void); +void nautilus_index_panel_add_meta_view (NautilusIndexPanel *panel, + NautilusView *meta_view); +void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *panel, + NautilusView *meta_view); +void nautilus_index_panel_set_uri (NautilusIndexPanel *panel, + const gchar *new_uri); -#endif /* __nautilus_index_panel_H__ */ +#endif /* NTL_INDEX_PANEL_H */ diff --git a/src/nautilus-spatial-window.c b/src/nautilus-spatial-window.c index b804fcfb7..bace01b7e 100644 --- a/src/nautilus-spatial-window.c +++ b/src/nautilus-spatial-window.c @@ -378,7 +378,7 @@ nautilus_window_set_status(NautilusWindow *window, const char *txt) } void -nautilus_window_goto_uri(NautilusWindow *window, const char *uri) +nautilus_window_goto_uri (NautilusWindow *window, const char *uri) { Nautilus_NavigationRequestInfo navinfo; @@ -387,8 +387,8 @@ nautilus_window_goto_uri(NautilusWindow *window, const char *uri) navinfo.new_window_default = navinfo.new_window_suggested = Nautilus_V_FALSE; navinfo.new_window_enforced = Nautilus_V_UNKNOWN; - nautilus_window_request_location_change(window, &navinfo, NULL); - nautilus_index_panel_set_uri(window->index_panel, uri); + nautilus_window_request_location_change (window, &navinfo, NULL); + nautilus_index_panel_set_uri (NAUTILUS_INDEX_PANEL (window->index_panel), uri); } static void @@ -491,8 +491,8 @@ nautilus_window_constructed(NautilusWindow *window) gtk_widget_show(temp_frame); window->index_panel = nautilus_index_panel_new(); - gtk_widget_show(window->index_panel); - gtk_container_add(GTK_CONTAINER(temp_frame), window->index_panel); + gtk_widget_show (GTK_WIDGET (window->index_panel)); + gtk_container_add(GTK_CONTAINER(temp_frame), GTK_WIDGET (window->index_panel)); #ifdef CONTENTS_AS_HBOX gtk_box_pack_start(GTK_BOX(window->content_hbox), temp_frame, FALSE, FALSE, 0); @@ -756,12 +756,11 @@ nautilus_window_set_content_view(NautilusWindow *window, NautilusView *content_v void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) { + g_return_if_fail (!g_slist_find (window->meta_views, meta_view)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); - g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - nautilus_index_panel_add_meta_view(window->index_panel, meta_view); - window->meta_views = g_slist_prepend(window->meta_views, meta_view); + nautilus_index_panel_add_meta_view (window->index_panel, meta_view); + window->meta_views = g_slist_prepend (window->meta_views, meta_view); } void @@ -812,7 +811,7 @@ nautilus_window_fwd (GtkWidget *btn, NautilusWindow *window) const char * nautilus_window_get_requested_uri (NautilusWindow *window) { - return window->ni->requested_uri; + return window->ni == NULL ? NULL : window->ni->requested_uri; } GnomeUIHandler * diff --git a/src/nautilus-spatial-window.h b/src/nautilus-spatial-window.h index 61bd916dd..9e020e41c 100644 --- a/src/nautilus-spatial-window.h +++ b/src/nautilus-spatial-window.h @@ -30,6 +30,7 @@ #include <libgnomeui/gnome-app.h> #include "ntl-types.h" #include "ntl-view.h" +#include "ntl-index-panel.h" #define NAUTILUS_TYPE_WINDOW (nautilus_window_get_type()) #define NAUTILUS_WINDOW(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_WINDOW, NautilusWindow)) @@ -57,7 +58,8 @@ struct _NautilusWindow { GSList *meta_views; /* UI stuff */ - GtkWidget *index_panel, *content_hbox, *btn_back, *btn_fwd; + NautilusIndexPanel *index_panel; + GtkWidget *content_hbox, *btn_back, *btn_fwd; GtkWidget *option_cvtype, *menu_cvtype, *ent_uri; guint statusbar_ctx, statusbar_clear_id; diff --git a/src/nautilus-window.c b/src/nautilus-window.c index b804fcfb7..bace01b7e 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -378,7 +378,7 @@ nautilus_window_set_status(NautilusWindow *window, const char *txt) } void -nautilus_window_goto_uri(NautilusWindow *window, const char *uri) +nautilus_window_goto_uri (NautilusWindow *window, const char *uri) { Nautilus_NavigationRequestInfo navinfo; @@ -387,8 +387,8 @@ nautilus_window_goto_uri(NautilusWindow *window, const char *uri) navinfo.new_window_default = navinfo.new_window_suggested = Nautilus_V_FALSE; navinfo.new_window_enforced = Nautilus_V_UNKNOWN; - nautilus_window_request_location_change(window, &navinfo, NULL); - nautilus_index_panel_set_uri(window->index_panel, uri); + nautilus_window_request_location_change (window, &navinfo, NULL); + nautilus_index_panel_set_uri (NAUTILUS_INDEX_PANEL (window->index_panel), uri); } static void @@ -491,8 +491,8 @@ nautilus_window_constructed(NautilusWindow *window) gtk_widget_show(temp_frame); window->index_panel = nautilus_index_panel_new(); - gtk_widget_show(window->index_panel); - gtk_container_add(GTK_CONTAINER(temp_frame), window->index_panel); + gtk_widget_show (GTK_WIDGET (window->index_panel)); + gtk_container_add(GTK_CONTAINER(temp_frame), GTK_WIDGET (window->index_panel)); #ifdef CONTENTS_AS_HBOX gtk_box_pack_start(GTK_BOX(window->content_hbox), temp_frame, FALSE, FALSE, 0); @@ -756,12 +756,11 @@ nautilus_window_set_content_view(NautilusWindow *window, NautilusView *content_v void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) { + g_return_if_fail (!g_slist_find (window->meta_views, meta_view)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); - g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - nautilus_index_panel_add_meta_view(window->index_panel, meta_view); - window->meta_views = g_slist_prepend(window->meta_views, meta_view); + nautilus_index_panel_add_meta_view (window->index_panel, meta_view); + window->meta_views = g_slist_prepend (window->meta_views, meta_view); } void @@ -812,7 +811,7 @@ nautilus_window_fwd (GtkWidget *btn, NautilusWindow *window) const char * nautilus_window_get_requested_uri (NautilusWindow *window) { - return window->ni->requested_uri; + return window->ni == NULL ? NULL : window->ni->requested_uri; } GnomeUIHandler * diff --git a/src/nautilus-window.h b/src/nautilus-window.h index 61bd916dd..9e020e41c 100644 --- a/src/nautilus-window.h +++ b/src/nautilus-window.h @@ -30,6 +30,7 @@ #include <libgnomeui/gnome-app.h> #include "ntl-types.h" #include "ntl-view.h" +#include "ntl-index-panel.h" #define NAUTILUS_TYPE_WINDOW (nautilus_window_get_type()) #define NAUTILUS_WINDOW(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_WINDOW, NautilusWindow)) @@ -57,7 +58,8 @@ struct _NautilusWindow { GSList *meta_views; /* UI stuff */ - GtkWidget *index_panel, *content_hbox, *btn_back, *btn_fwd; + NautilusIndexPanel *index_panel; + GtkWidget *content_hbox, *btn_back, *btn_fwd; GtkWidget *option_cvtype, *menu_cvtype, *ent_uri; guint statusbar_ctx, statusbar_clear_id; diff --git a/src/ntl-index-panel.c b/src/ntl-index-panel.c index bd8e61d3f..81209ecc3 100644 --- a/src/ntl-index-panel.c +++ b/src/ntl-index-panel.c @@ -1,3 +1,5 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + /* Nautilus * Copyright (C) 1999, 2000 Eazel, Inc. * @@ -31,346 +33,356 @@ #include "nautilus.h" #include "ntl-index-panel.h" #include <libgnomevfs/gnome-vfs-uri.h> +#include <libnautilus/nautilus-gtk-macros.h> +#include <libnautilus/nautilus-string.h> + +#define ARRAY_LENGTH(array) \ + (sizeof (array) / sizeof ((array)[0])) + +static void nautilus_index_panel_initialize_class (gpointer klass); +static void nautilus_index_panel_initialize (gpointer object, gpointer klass); +static void nautilus_index_panel_destroy (GtkObject *object); +static void nautilus_index_panel_finalize (GtkObject *object); -static void nautilus_index_panel_class_init(NautilusIndexPanelClass *klass); -static void nautilus_index_panel_init(NautilusIndexPanel *icon_view); -static void nautilus_index_panel_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time); -void nautilus_index_panel_set_meta_tabs(GtkWidget* widget, GtkWidget* new_tabs); -void nautilus_index_panel_set_uri(GtkWidget *widget, const gchar *new_uri); -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view); +static void nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, + GtkSelectionData *selection_data, + guint info, guint time); -void nautilus_index_panel_set_up_background(GtkWidget* widget, const gchar *background_data); -void nautilus_index_panel_set_up_info(GtkWidget* widget, const gchar* new_uri); -void nautilus_index_panel_set_up_label(GtkWidget* widget, const gchar *uri); -void nautilus_index_panel_set_up_logo(GtkWidget* widget, const gchar *logo_path); +static void nautilus_index_panel_set_up_background (NautilusIndexPanel *index_panel, const gchar *background_data); +static void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri); +static void nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar *uri); +static void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gchar *logo_path); -GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template); +static GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template); + +static GtkObjectClass *parent_class; /* drag and drop definitions */ enum dnd_targets_enum { - TARGET_STRING, - TARGET_COLOR, - TARGET_URI_LIST + TARGET_STRING, + TARGET_COLOR, + TARGET_URI_LIST }; static GtkTargetEntry index_dnd_target_table[] = { - { "application/x-color", 0, TARGET_COLOR }, - { "text/uri-list", 0, TARGET_URI_LIST } + { "application/x-color", 0, TARGET_COLOR }, + { "text/uri-list", 0, TARGET_URI_LIST } }; -/* private globals */ - -/* the get_type routine is boilerplate code that registers the class and returns a unique type integer */ - -guint -nautilus_index_panel_get_type (void) -{ - static guint index_panel_type = 0; - - if (!index_panel_type) - { - static const GtkTypeInfo index_panel_info = - { - "NautilusIndexPanel", - sizeof (NautilusIndexPanel), - sizeof (NautilusIndexPanelClass), - (GtkClassInitFunc) nautilus_index_panel_class_init, - (GtkObjectInitFunc) nautilus_index_panel_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - index_panel_type = gtk_type_unique (gtk_event_box_get_type (), &index_panel_info); - } - - return index_panel_type; -} +NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusIndexPanel, nautilus_index_panel, GTK_TYPE_EVENT_BOX); /* initializing the class object by installing the operations we override */ static void -nautilus_index_panel_class_init (NautilusIndexPanelClass *class) +nautilus_index_panel_initialize_class (gpointer klass) { - GtkWidgetClass *widget_class; - widget_class = (GtkWidgetClass*) class; - widget_class->drag_data_received = nautilus_index_panel_drag_data_received; + GtkWidgetClass *widget_class; + + widget_class = GTK_WIDGET_CLASS (klass); + + parent_class = gtk_type_class (GTK_TYPE_EVENT_BOX); + + widget_class->drag_data_received = nautilus_index_panel_drag_data_received; } /* common routine to make the per-uri container */ static void make_per_uri_container(NautilusIndexPanel *index_panel) { - index_panel->per_uri_container = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER (index_panel->per_uri_container), 0); - gtk_widget_show(index_panel->per_uri_container); - gtk_box_pack_start(GTK_BOX(index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0); + index_panel->per_uri_container = gtk_vbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (index_panel->per_uri_container), 0); + gtk_widget_show (index_panel->per_uri_container); + gtk_box_pack_start (GTK_BOX (index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0); } /* initialize the instance's fields, create the necessary subviews, etc. */ static void -nautilus_index_panel_init (NautilusIndexPanel *index_panel) +nautilus_index_panel_initialize (gpointer object, gpointer klass) { - GtkWidget* widget = GTK_WIDGET(index_panel); - - index_panel->index_container = NULL; - index_panel->per_uri_container = NULL; - index_panel->uri = NULL; - - /* set the size of the index panel */ - - gtk_widget_set_usize(widget, 136, 400); + NautilusIndexPanel *index_panel; + GtkWidget* widget; + + index_panel = NAUTILUS_INDEX_PANEL (object); + widget = GTK_WIDGET (object); + + /* set the size of the index panel */ + gtk_widget_set_usize (widget, 136, 400); - /* create the container box */ - - index_panel->index_container = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER (index_panel->index_container), 0); - gtk_widget_show(index_panel->index_container); - gtk_container_add(GTK_CONTAINER(index_panel), index_panel->index_container); + /* create the container box */ + index_panel->index_container = gtk_vbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (index_panel->index_container), 0); + gtk_widget_show (index_panel->index_container); + gtk_container_add (GTK_CONTAINER (index_panel), index_panel->index_container); - /* allocate and install the vbox to hold the per-uri information */ - make_per_uri_container(index_panel); + /* allocate and install the vbox to hold the per-uri information */ + make_per_uri_container (index_panel); - /* allocate and install the meta-tabs (for now it's a notebook) */ + /* allocate and install the meta-tabs (for now it's a notebook) */ - index_panel->meta_tabs = gtk_notebook_new(); - gtk_widget_set_usize(index_panel->meta_tabs, 136, 200); - gtk_widget_show(index_panel->meta_tabs); - gtk_box_pack_end(GTK_BOX(index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0); + index_panel->meta_tabs = gtk_notebook_new (); + gtk_widget_set_usize (index_panel->meta_tabs, 136, 200); + gtk_widget_show (index_panel->meta_tabs); + gtk_box_pack_end (GTK_BOX (index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0); - /* prepare ourselves to receive dropped objects */ - gtk_drag_dest_set (GTK_WIDGET (index_panel), GTK_DEST_DEFAULT_MOTION | - GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, - index_dnd_target_table, 2, GDK_ACTION_COPY); + /* prepare ourselves to receive dropped objects */ + gtk_drag_dest_set (GTK_WIDGET (index_panel), + GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, + index_dnd_target_table, ARRAY_LENGTH (index_dnd_target_table), GDK_ACTION_COPY); + + index_panel->background = nautilus_background_new (); +} + +static void +nautilus_index_panel_destroy (GtkObject *object) +{ + NautilusIndexPanel *index_panel; + + index_panel = NAUTILUS_INDEX_PANEL (object); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); +} + +static void +nautilus_index_panel_finalize (GtkObject *object) +{ + NautilusIndexPanel *index_panel; + + index_panel = NAUTILUS_INDEX_PANEL (object); + + g_free (index_panel->uri); + if (index_panel->background != NULL) + gtk_object_unref (GTK_OBJECT (index_panel->background)); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object)); } /* create a new instance */ -GtkWidget* +NautilusIndexPanel * nautilus_index_panel_new (void) { - return GTK_WIDGET(gtk_type_new (nautilus_index_panel_get_type ())); + return NAUTILUS_INDEX_PANEL (gtk_type_new (nautilus_index_panel_get_type ())); } /* drag and drop handler for index panel */ static void -nautilus_index_panel_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time) +nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *context, + gint x, gint y, + GtkSelectionData *selection_data, guint info, guint time) { - gchar temp_str[512]; - guint16 *data = (guint16 *)selection_data->data; - switch (info) - { - case TARGET_URI_LIST: - printf("dropped data on index panel: %s", selection_data->data); - - /* handle background images and keywords soon */ + char *color_spec; + guint16 *data; + + g_return_if_fail (NAUTILUS_IS_INDEX_PANEL (widget)); + + switch (info) + { + case TARGET_URI_LIST: + printf("dropped data on index panel: %s", selection_data->data); + + /* handle background images and keywords soon */ - /* handle images dropped on the logo specially */ + /* handle images dropped on the logo specially */ - /* handle files by setting the location to the file */ + /* handle files by setting the location to the file */ - break; + break; - - /* handle colors - for now, just use a simple color, and don't save it in the meta-data yet */ - + + /* handle colors - for now, just use a simple color, and don't save it in the meta-data yet */ + case TARGET_COLOR: - g_snprintf(temp_str, sizeof(temp_str), "rgb:%2x/%2x/%2x", data[0], data[1], data[2]); - nautilus_index_panel_set_up_background(widget, temp_str); - break; - + data = (guint16 *)selection_data->data; + color_spec = g_strdup_printf ("rgb:%04hX/%04hX/%04hX", data[0], data[1], data[2]); + nautilus_index_panel_set_up_background (NAUTILUS_INDEX_PANEL (widget), color_spec); + g_free (color_spec); + break; + default: - printf("unknown drop type: %d\n", info); + g_warning ("unknown drop type"); break; - } + } } /* add a new meta-view to the index panel */ -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view) +void nautilus_index_panel_add_meta_view (NautilusIndexPanel *index_panel, NautilusView *meta_view) { - GtkWidget *label; - const char *description; - char cbuf[32]; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - description = nautilus_meta_view_get_label(NAUTILUS_META_VIEW(meta_view)); - if (!description) - { - description = cbuf; - g_snprintf(cbuf, sizeof(cbuf), "%p", meta_view); - } - label = gtk_label_new(description); - gtk_widget_show(label); + GtkWidget *label; + const char *description; + char cbuf[32]; + + g_return_if_fail (NAUTILUS_IS_INDEX_PANEL (index_panel)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); + + description = nautilus_meta_view_get_label (NAUTILUS_META_VIEW (meta_view)); + if (description == NULL) { + description = cbuf; + g_snprintf (cbuf, sizeof (cbuf), "%p", meta_view); + } + label = gtk_label_new (description); + gtk_widget_show (label); - /* - gtk_signal_connect(GTK_OBJECT(label), "button_press_event", - GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view); - */ + /* + gtk_signal_connect(GTK_OBJECT(label), "button_press_event", + GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view); + */ - gtk_notebook_prepend_page(GTK_NOTEBOOK(index_panel->meta_tabs), GTK_WIDGET(meta_view), label); - gtk_widget_show(GTK_WIDGET(meta_view)); + gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view), label); + gtk_widget_show (GTK_WIDGET (meta_view)); } /* remove the passed-in meta-view from the index panel */ -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view) +void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *index_panel, NautilusView *meta_view) { - gint pagenum; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(index_panel->meta_tabs), GTK_WIDGET(meta_view)); - g_return_if_fail(pagenum >= 0); - gtk_notebook_remove_page(GTK_NOTEBOOK(index_panel->meta_tabs), pagenum); + gint page_num; + + page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view)); + g_return_if_fail (page_num >= 0); + gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->meta_tabs), page_num); } /* set up the index panel's background. Darin's background stuff will soon replace this, but for now just set up the color */ -void nautilus_index_panel_set_up_background(GtkWidget* widget, const gchar *background_data) +void nautilus_index_panel_set_up_background (NautilusIndexPanel *index_panel, const gchar *background_data) { - GdkColor temp_color; - GtkStyle *temp_style; - - gdk_color_parse(background_data, &temp_color); - gdk_color_alloc(gtk_widget_get_colormap(widget), &temp_color); - temp_style = gtk_style_new(); - temp_style->bg[GTK_STATE_NORMAL] = temp_color; - gtk_widget_set_style(widget, gtk_style_attach(temp_style, widget->window)); + GdkColor temp_color; + GtkStyle *temp_style; + + gdk_color_parse (background_data, &temp_color); + gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (index_panel)), &temp_color); + temp_style = gtk_style_new(); + temp_style->bg[GTK_STATE_NORMAL] = temp_color; + gtk_widget_set_style (GTK_WIDGET (index_panel), + gtk_style_attach (temp_style, GTK_WIDGET (index_panel)->window)); + + nautilus_background_set_color (index_panel->background, background_data); } /* set up the logo image */ -void nautilus_index_panel_set_up_logo(GtkWidget* widget, const gchar *logo_path) +void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gchar *logo_path) { - const gchar *file_name; - GtkWidget *pix_widget; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; + gchar *file_name; + GtkWidget *pix_widget; - file_name = gnome_pixmap_file(logo_path); - pix_widget = (GtkWidget*) gnome_pixmap_new_from_file(file_name); - gtk_widget_show(pix_widget); - gtk_box_pack_start(GTK_BOX(index_panel->per_uri_container), pix_widget, 0, 0, 0); - g_free((gchar*)file_name); + file_name = gnome_pixmap_file (logo_path); + pix_widget = GTK_WIDGET (gnome_pixmap_new_from_file (file_name)); + gtk_widget_show (pix_widget); + gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), pix_widget, 0, 0, 0); + g_free (file_name); } /* utility routine (FIXME: should be located elsewhere) to find the largest font that fits */ GdkFont *select_font(const gchar *text_to_format, gint width, const gchar* font_template) { - GdkFont *candidate_font; - gchar font_name[512]; - gint this_width; - gint font_sizes[8] = { 28, 24, 18, 14, 12, 10, 8 }; - gint font_index = 0; + GdkFont *candidate_font = NULL; + gchar *font_name; + gint this_width; + gint font_sizes[8] = { 28, 24, 18, 14, 12, 10, 8 }; + gint font_index; - while (font_index < 8) - { - g_snprintf(font_name, sizeof(font_name), font_template, font_sizes[font_index]); - candidate_font = gdk_font_load(font_name); - this_width = gdk_string_width(candidate_font, text_to_format); - if (this_width < width) - return candidate_font; - else - gdk_font_unref(candidate_font); - font_index += 1; + for (font_index = 0; font_index < ARRAY_LENGTH (font_sizes); font_index++) { + if (candidate_font != NULL) + gdk_font_unref (candidate_font); + + font_name = g_strdup_printf (font_template, font_sizes[font_index]); + candidate_font = gdk_font_load (font_name); + g_free (font_name); - } - return candidate_font; + this_width = gdk_string_width (candidate_font, text_to_format); + if (this_width < width) + return candidate_font; + } + + return candidate_font; } /* set up the label */ -void nautilus_index_panel_set_up_label(GtkWidget* widget, const gchar *uri) +void nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar *uri) { - GtkWidget *label_widget; - const gchar *file_name; - GnomeVFSURI *vfs_uri; - GdkFont* label_font; - gchar *temp_uri = strdup(uri); - gint slash_pos = strlen(temp_uri) - 1; - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* we must remove the trailing slash for vfs_get_basename to work right for us */ - if ((temp_uri[slash_pos] == '/') && (slash_pos > 0)) - temp_uri[slash_pos] = '\0'; - - vfs_uri = gnome_vfs_uri_new(temp_uri); - g_free(temp_uri); - - file_name = gnome_vfs_uri_get_basename(vfs_uri); - gnome_vfs_uri_destroy(vfs_uri); - - if (file_name == NULL) - { - return; - } - - label_widget = gtk_label_new(file_name); - gtk_box_pack_start(GTK_BOX(index_panel->per_uri_container), label_widget, 0, 0, 0); - - label_font = select_font(file_name, widget->allocation.width - 4, "-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*"); - g_free((gchar*) file_name); - - if (label_font != NULL) - { - GtkStyle *temp_style; - gtk_widget_realize(label_widget); - temp_style = gtk_style_new(); - temp_style->font = label_font; - gtk_widget_set_style(label_widget, gtk_style_attach(temp_style, label_widget->window)); - } - - gtk_widget_show(label_widget); + GtkWidget *label_widget; + const gchar *file_name; + GnomeVFSURI *vfs_uri; + GdkFont *label_font; + char *temp_uri; + int slash_pos; + + /* remove the trailing slash so vfs_get_basename will work right for us */ + temp_uri = g_strdup (uri); + slash_pos = strlen (temp_uri) - 1; + if (slash_pos > 0 && temp_uri[slash_pos] == '/') + temp_uri[slash_pos] = '\0'; + + vfs_uri = gnome_vfs_uri_new(temp_uri); + g_free(temp_uri); + + file_name = gnome_vfs_uri_get_basename (vfs_uri); + + if (file_name != NULL) { + label_widget = gtk_label_new (file_name); + gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), label_widget, 0, 0, 0); + + label_font = select_font(file_name, GTK_WIDGET (index_panel)->allocation.width - 4, + "-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*"); + + if (label_font != NULL) { + GtkStyle *temp_style; + gtk_widget_realize (label_widget); + temp_style = gtk_style_new (); + temp_style->font = label_font; + gtk_widget_set_style (label_widget, gtk_style_attach (temp_style, label_widget->window)); + } + + gtk_widget_show(label_widget); + } + + gnome_vfs_uri_unref (vfs_uri); } /* this routine populates the index panel with the per-uri information */ -void nautilus_index_panel_set_up_info(GtkWidget* widget, const gchar* new_uri) -{ - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* set up the background from the metadata. At first, just use hardwired backgrounds */ - nautilus_index_panel_set_up_background(widget, "rgb:DD/DD/FF"); - - /* next, install the logo image. */ - /* For now, just use a fixed folder image */ - nautilus_index_panel_set_up_logo(widget, "nautilus/i-directory.png"); +void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri) +{ + /* set up the background from the metadata. At first, just use hardwired backgrounds */ + nautilus_index_panel_set_up_background (index_panel, "rgb:DDDD/DDDD/FFFF"); - /* add the name, discarding all but the last part of the path */ - /* soon, we'll use the biggest font that fit, for now don't worry about it */ - nautilus_index_panel_set_up_label(widget, new_uri); - - /* format and install the type-dependent descriptive info */ - - /* add the description text, if any. Try to fetch it from the notes file if none is present */ + /* next, install the logo image. */ + /* For now, just use a fixed folder image */ + nautilus_index_panel_set_up_logo (index_panel, "nautilus/i-directory.png"); - /* add keywords if we got any */ + /* add the name, discarding all but the last part of the path */ + /* soon, we'll use the biggest font that fit, for now don't worry about it */ + nautilus_index_panel_set_up_label (index_panel, new_uri); + + /* format and install the type-dependent descriptive info */ + + /* add the description text, if any. Try to fetch it from the notes file if none is present */ + + /* add keywords if we got any */ } /* here is the key routine that populates the index panel with the appropriate information when the uri changes */ -void nautilus_index_panel_set_uri(GtkWidget* widget, const gchar* new_uri) +void nautilus_index_panel_set_uri (NautilusIndexPanel *index_panel, const gchar* new_uri) { - NautilusIndexPanel *index_panel = (NautilusIndexPanel*) widget; - - /* there's nothing to do if the uri is the same as the current one */ - - if (index_panel->uri && !strcmp(index_panel->uri, new_uri)) - return; - - if (index_panel->uri) - g_free(index_panel->uri); - - index_panel->uri = g_strdup(new_uri); - - /* get rid of the old widgets in the per_uri container */ - gtk_widget_destroy(index_panel->per_uri_container); - make_per_uri_container(index_panel); - - /* populate the per-uri box with the info */ - nautilus_index_panel_set_up_info(widget, new_uri); - } - + /* there's nothing to do if the uri is the same as the current one */ + + if (nautilus_strcmp (index_panel->uri, new_uri) == 0) + return; + + g_free (index_panel->uri); + index_panel->uri = g_strdup (new_uri); + + /* get rid of the old widgets in the per_uri container */ + gtk_widget_destroy (index_panel->per_uri_container); + make_per_uri_container (index_panel); + + /* populate the per-uri box with the info */ + nautilus_index_panel_set_up_info (index_panel, new_uri); +} diff --git a/src/ntl-index-panel.h b/src/ntl-index-panel.h index 06a0b2cec..8e8f1e28d 100644 --- a/src/ntl-index-panel.h +++ b/src/ntl-index-panel.h @@ -1,3 +1,5 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + /* Nautilus * Copyright (C) 1999, 2000 Eazel, Inc. * @@ -19,53 +21,52 @@ * * This is the header file for the index panel widget, which displays overview information * in a vertical panel and hosts the meta-views. - * */ -#ifndef __nautilus_index_panel_H__ -#define __nautilus_index_panel_H__ - +#ifndef NTL_INDEX_PANEL_H +#define NTL_INDEX_PANEL_H #include <gdk/gdk.h> #include <gtk/gtkwidget.h> #include "nautilus.h" +#include <libnautilus/nautilus-background.h> -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define nautilus_index_panel(obj) GTK_CHECK_CAST (obj, nautilus_index_panel_get_type (), NautilusIndexPanel) -#define nautilus_index_panel_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, nautilus_index_panel_get_type (), NautilusIndexPanelClass) -#define NAUTILUS_IS_INDEX_PANEL(obj) GTK_CHECK_TYPE (obj, nautilus_index_panel_get_type ()) - - -typedef struct _NautilusIndexPanel NautilusIndexPanel; +typedef struct _NautilusIndexPanel NautilusIndexPanel; typedef struct _NautilusIndexPanelClass NautilusIndexPanelClass; +#define NAUTILUS_TYPE_INDEX_PANEL \ + (nautilus_index_panel_get_type ()) +#define NAUTILUS_INDEX_PANEL(obj) \ + (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_INDEX_PANEL, NautilusIndexPanel)) +#define NAUTILUS_INDEX_PANEL_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_INDEX_PANEL, NautilusIndexPanelClass)) +#define NAUTILUS_IS_INDEX_PANEL(obj) \ + (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_INDEX_PANEL)) +#define NAUTILUS_IS_INDEX_PANEL_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_INDEX_PANEL)) + struct _NautilusIndexPanel { - GtkEventBox event_box; - GtkWidget* index_container; - GtkWidget* per_uri_container; - GtkWidget* meta_tabs; - gchar* uri; + GtkEventBox event_box; + GtkWidget *index_container; + GtkWidget *per_uri_container; + GtkWidget *meta_tabs; + gchar *uri; + NautilusBackground *background; }; struct _NautilusIndexPanelClass { - GtkEventBoxClass parent_class; + GtkEventBoxClass parent_class; }; -guint nautilus_index_panel_get_type(void); -GtkWidget* nautilus_index_panel_new(void); -void nautilus_index_panel_add_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_remove_meta_view(GtkWidget* widget, NautilusView *meta_view); -void nautilus_index_panel_set_uri(GtkWidget* widget, const gchar* new_uri); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +GtkType nautilus_index_panel_get_type (void); +NautilusIndexPanel *nautilus_index_panel_new (void); +void nautilus_index_panel_add_meta_view (NautilusIndexPanel *panel, + NautilusView *meta_view); +void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *panel, + NautilusView *meta_view); +void nautilus_index_panel_set_uri (NautilusIndexPanel *panel, + const gchar *new_uri); -#endif /* __nautilus_index_panel_H__ */ +#endif /* NTL_INDEX_PANEL_H */ diff --git a/src/ntl-window.c b/src/ntl-window.c index b804fcfb7..bace01b7e 100644 --- a/src/ntl-window.c +++ b/src/ntl-window.c @@ -378,7 +378,7 @@ nautilus_window_set_status(NautilusWindow *window, const char *txt) } void -nautilus_window_goto_uri(NautilusWindow *window, const char *uri) +nautilus_window_goto_uri (NautilusWindow *window, const char *uri) { Nautilus_NavigationRequestInfo navinfo; @@ -387,8 +387,8 @@ nautilus_window_goto_uri(NautilusWindow *window, const char *uri) navinfo.new_window_default = navinfo.new_window_suggested = Nautilus_V_FALSE; navinfo.new_window_enforced = Nautilus_V_UNKNOWN; - nautilus_window_request_location_change(window, &navinfo, NULL); - nautilus_index_panel_set_uri(window->index_panel, uri); + nautilus_window_request_location_change (window, &navinfo, NULL); + nautilus_index_panel_set_uri (NAUTILUS_INDEX_PANEL (window->index_panel), uri); } static void @@ -491,8 +491,8 @@ nautilus_window_constructed(NautilusWindow *window) gtk_widget_show(temp_frame); window->index_panel = nautilus_index_panel_new(); - gtk_widget_show(window->index_panel); - gtk_container_add(GTK_CONTAINER(temp_frame), window->index_panel); + gtk_widget_show (GTK_WIDGET (window->index_panel)); + gtk_container_add(GTK_CONTAINER(temp_frame), GTK_WIDGET (window->index_panel)); #ifdef CONTENTS_AS_HBOX gtk_box_pack_start(GTK_BOX(window->content_hbox), temp_frame, FALSE, FALSE, 0); @@ -756,12 +756,11 @@ nautilus_window_set_content_view(NautilusWindow *window, NautilusView *content_v void nautilus_window_add_meta_view(NautilusWindow *window, NautilusView *meta_view) { + g_return_if_fail (!g_slist_find (window->meta_views, meta_view)); + g_return_if_fail (NAUTILUS_IS_META_VIEW (meta_view)); - g_return_if_fail(!g_slist_find(window->meta_views, meta_view)); - g_return_if_fail(NAUTILUS_IS_META_VIEW(meta_view)); - - nautilus_index_panel_add_meta_view(window->index_panel, meta_view); - window->meta_views = g_slist_prepend(window->meta_views, meta_view); + nautilus_index_panel_add_meta_view (window->index_panel, meta_view); + window->meta_views = g_slist_prepend (window->meta_views, meta_view); } void @@ -812,7 +811,7 @@ nautilus_window_fwd (GtkWidget *btn, NautilusWindow *window) const char * nautilus_window_get_requested_uri (NautilusWindow *window) { - return window->ni->requested_uri; + return window->ni == NULL ? NULL : window->ni->requested_uri; } GnomeUIHandler * diff --git a/src/ntl-window.h b/src/ntl-window.h index 61bd916dd..9e020e41c 100644 --- a/src/ntl-window.h +++ b/src/ntl-window.h @@ -30,6 +30,7 @@ #include <libgnomeui/gnome-app.h> #include "ntl-types.h" #include "ntl-view.h" +#include "ntl-index-panel.h" #define NAUTILUS_TYPE_WINDOW (nautilus_window_get_type()) #define NAUTILUS_WINDOW(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_WINDOW, NautilusWindow)) @@ -57,7 +58,8 @@ struct _NautilusWindow { GSList *meta_views; /* UI stuff */ - GtkWidget *index_panel, *content_hbox, *btn_back, *btn_fwd; + NautilusIndexPanel *index_panel; + GtkWidget *content_hbox, *btn_back, *btn_fwd; GtkWidget *option_cvtype, *menu_cvtype, *ent_uri; guint statusbar_ctx, statusbar_clear_id; |