summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamiro Estrugo <ramiro@src.gnome.org>2001-02-10 02:54:25 +0000
committerRamiro Estrugo <ramiro@src.gnome.org>2001-02-10 02:54:25 +0000
commit5585ad975dbd01f9aed1c628ea3e22a39713a3af (patch)
treecacecf62b2899948f2cd8c0c6f296031c224a1e0
parentf792bd3793549b74230e3a89885bdd0f4be02bc4 (diff)
downloadnautilus-5585ad975dbd01f9aed1c628ea3e22a39713a3af.tar.gz
reviewed by: Robey Pointer <robey@eazel.com>
* libnautilus-extensions/Makefile.am: * libnautilus-extensions/nautilus-region.c: * libnautilus-extensions/nautilus-region.h: New class for super easy region management using rectangle. * libnautilus-extensions/nautilus-art-gtk-extensions.h: * libnautilus-extensions/nautilus-art-gtk-extensions.c: (nautilus_gdk_rectangle_assign_irect): New function to convert ArtIRect to GdkRectangles. * libnautilus-extensions/nautilus-customization-data.h: * libnautilus-extensions/nautilus-customization-data.c: (nautilus_customization_data_get_next_element_for_display): Return pixbufs and labels for the object instead of widgets. This is so that the caller can use the widget that best suits its display needs. * libnautilus-extensions/nautilus-image-table.h: * libnautilus-extensions/nautilus-image-table.c: (nautilus_image_table_initialize_class), (nautilus_image_table_initialize), (nautilus_image_table_expose_event), (nautilus_image_table_realize), (nautilus_image_table_unrealize), (nautilus_image_table_set_is_smooth_signal), (image_table_foreach_child_subtract_content), (image_table_clear_dirty_areas), (image_table_peek_clear_gc), (image_table_emit_signal), (image_table_handle_motion), (ancestor_button_press_event), (ancestor_button_release_event), (nautilus_image_table_new), (nautilus_image_table_set_is_smooth), (nautilus_image_table_set_smooth_background_color): Add support for smoothnes. Register widget as a possible smooth widget. When smoothness changes, we modify our background drawing behavior such that in smooth mode we dont flicker at all. Remove grab/ungrab pair that could screw up operations. Turns out these are not needed. Change event signal emissions to include more data from the raw gdk events without exposing these. * libnautilus-extensions/nautilus-image.c: (nautilus_image_initialize_class): Update for new smooth widget class registration scheme. * libnautilus-extensions/nautilus-label.c: (nautilus_label_initialize_class): Update for new smooth widget class registration scheme. * libnautilus-extensions/nautilus-labeled-image.h: * libnautilus-extensions/nautilus-labeled-image.c: (nautilus_labeled_image_size_allocate), (nautilus_labeled_image_get_image_bounds), (nautilus_labeled_image_get_label_bounds): Make these two functions public. * libnautilus-extensions/nautilus-smooth-widget.h: * libnautilus-extensions/nautilus-smooth-widget.c: (smooth_widget_type_list_free), (smooth_widget_list_free), (widget_is_smooth), (nautilus_smooth_widget_register), (nautilus_smooth_widget_register_type): Add mechanism for registering types that are meant to be smooth. That way we dont need to hardcode the list of smooth widget classes. Also made sure to free the static lists at exit time. * libnautilus-extensions/nautilus-viewport.h: * libnautilus-extensions/nautilus-viewport.c: (nautilus_viewport_initialize_class), (nautilus_viewport_initialize), (nautilus_viewport_destroy), (nautilus_viewport_draw), (nautilus_viewport_expose_event), (nautilus_viewport_realize), (nautilus_viewport_paint), (nautilus_viewport_set_is_smooth_signal), (nautilus_viewport_new), (nautilus_viewport_set_is_smooth), (nautilus_viewport_get_scroll_offset): Add support for smoothness. When the is_smooth attribute changes, the viewport will not clear the background on resize - and so its content will not flicker. Add function for querying the scroll offset. * libnautilus-extensions/nautilus-wrap-table.h: * libnautilus-extensions/nautilus-wrap-table.c: (wrap_table_get_content_frame), (wrap_table_get_scroll_offset), (nautilus_wrap_table_get_homogeneous), (nautilus_wrap_table_reorder_child): Fix a mod by zero error. Add support for reordering children. * src/file-manager/fm-properties-window.c: (create_emblems_page): Simplify a bit by using NautilusWrapTable instead of a GtkTable with a hard coded number of columns. The emblems now wrap to fit the available space. Also use NautilusLabeledImages instead of boxes. Update for changes in customization data api. Remove check box painting workaround. Its taken care of in NautilusLabeledImage now. * src/nautilus-property-browser.c: (nautilus_property_browser_initialize_class), (nautilus_property_browser_initialize), (element_clicked_callback), (nautilus_property_browser_preferences_changed), (make_property_tile), (make_properties_from_directories), (add_reset_property), (make_properties_from_xml_node), (property_browser_category_button_new), (make_category_link), (nautilus_property_browser_update_contents), (emit_emblems_changed_signal): Use a NautilusImageTable instead of a GtkTable to make things wrap propertly and thus not have to recreate the whole property box each time its resized. Remove a lot of hard coded dimensions. Simplified a bit by using NautilusLabeledImages. * src/nautilus-search-bar-criterion.c: (make_emblem_value_menu): Update for changes in customization data api. * test/test-nautilus-image-table.c: (labeled_image_new), (foo_timeout), (image_table_size_allocate), (image_table_new_scrolled): Update for new image table features.
-rw-r--r--ChangeLog121
-rw-r--r--libnautilus-extensions/Makefile.am2
-rw-r--r--libnautilus-extensions/nautilus-art-gtk-extensions.c20
-rw-r--r--libnautilus-extensions/nautilus-art-gtk-extensions.h17
-rw-r--r--libnautilus-extensions/nautilus-customization-data.c40
-rw-r--r--libnautilus-extensions/nautilus-customization-data.h8
-rw-r--r--libnautilus-extensions/nautilus-image-table.c336
-rw-r--r--libnautilus-extensions/nautilus-image-table.h10
-rw-r--r--libnautilus-extensions/nautilus-image.c3
-rw-r--r--libnautilus-extensions/nautilus-label.c7
-rw-r--r--libnautilus-extensions/nautilus-labeled-image.c15
-rw-r--r--libnautilus-extensions/nautilus-labeled-image.h2
-rw-r--r--libnautilus-extensions/nautilus-region.c123
-rw-r--r--libnautilus-extensions/nautilus-region.h46
-rw-r--r--libnautilus-extensions/nautilus-smooth-widget.c64
-rw-r--r--libnautilus-extensions/nautilus-smooth-widget.h1
-rw-r--r--libnautilus-extensions/nautilus-viewport.c307
-rw-r--r--libnautilus-extensions/nautilus-viewport.h23
-rw-r--r--libnautilus-extensions/nautilus-wrap-table.c61
-rw-r--r--libnautilus-extensions/nautilus-wrap-table.h3
-rw-r--r--libnautilus-private/Makefile.am2
-rw-r--r--libnautilus-private/nautilus-art-gtk-extensions.c20
-rw-r--r--libnautilus-private/nautilus-art-gtk-extensions.h17
-rw-r--r--libnautilus-private/nautilus-customization-data.c40
-rw-r--r--libnautilus-private/nautilus-customization-data.h8
-rw-r--r--libnautilus-private/nautilus-image-table.c336
-rw-r--r--libnautilus-private/nautilus-image-table.h10
-rw-r--r--libnautilus-private/nautilus-image.c3
-rw-r--r--libnautilus-private/nautilus-label.c7
-rw-r--r--libnautilus-private/nautilus-labeled-image.c15
-rw-r--r--libnautilus-private/nautilus-labeled-image.h2
-rw-r--r--libnautilus-private/nautilus-region.c123
-rw-r--r--libnautilus-private/nautilus-region.h46
-rw-r--r--libnautilus-private/nautilus-smooth-widget.c64
-rw-r--r--libnautilus-private/nautilus-smooth-widget.h1
-rw-r--r--libnautilus-private/nautilus-viewport.c307
-rw-r--r--libnautilus-private/nautilus-viewport.h23
-rw-r--r--libnautilus-private/nautilus-wrap-table.c61
-rw-r--r--libnautilus-private/nautilus-wrap-table.h3
-rw-r--r--src/file-manager/fm-properties-window.c70
-rw-r--r--src/nautilus-property-browser.c448
-rw-r--r--src/nautilus-search-bar-criterion.c35
-rw-r--r--test/test-nautilus-image-table.c55
43 files changed, 2181 insertions, 724 deletions
diff --git a/ChangeLog b/ChangeLog
index b8578257e..38470cc13 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,124 @@
+2001-02-09 Ramiro Estrugo <ramiro@eazel.com>
+
+ reviewed by: Robey Pointer <robey@eazel.com>
+
+ * libnautilus-extensions/Makefile.am:
+ * libnautilus-extensions/nautilus-region.c:
+ * libnautilus-extensions/nautilus-region.h:
+ New class for super easy region management using rectangle.
+
+ * libnautilus-extensions/nautilus-art-gtk-extensions.h:
+ * libnautilus-extensions/nautilus-art-gtk-extensions.c:
+ (nautilus_gdk_rectangle_assign_irect):
+ New function to convert ArtIRect to GdkRectangles.
+
+ * libnautilus-extensions/nautilus-customization-data.h:
+ * libnautilus-extensions/nautilus-customization-data.c:
+ (nautilus_customization_data_get_next_element_for_display):
+ Return pixbufs and labels for the object instead of widgets. This
+ is so that the caller can use the widget that best suits its
+ display needs.
+
+ * libnautilus-extensions/nautilus-image-table.h:
+ * libnautilus-extensions/nautilus-image-table.c:
+ (nautilus_image_table_initialize_class),
+ (nautilus_image_table_initialize),
+ (nautilus_image_table_expose_event),
+ (nautilus_image_table_realize), (nautilus_image_table_unrealize),
+ (nautilus_image_table_set_is_smooth_signal),
+ (image_table_foreach_child_subtract_content),
+ (image_table_clear_dirty_areas), (image_table_peek_clear_gc),
+ (image_table_emit_signal), (image_table_handle_motion),
+ (ancestor_button_press_event), (ancestor_button_release_event),
+ (nautilus_image_table_new), (nautilus_image_table_set_is_smooth),
+ (nautilus_image_table_set_smooth_background_color):
+ Add support for smoothnes. Register widget as a possible smooth
+ widget. When smoothness changes, we modify our background drawing
+ behavior such that in smooth mode we dont flicker at all.
+
+ Remove grab/ungrab pair that could screw up operations. Turns out
+ these are not needed.
+
+ Change event signal emissions to include more data from the raw
+ gdk events without exposing these.
+
+ * libnautilus-extensions/nautilus-image.c:
+ (nautilus_image_initialize_class):
+ Update for new smooth widget class registration scheme.
+
+ * libnautilus-extensions/nautilus-label.c:
+ (nautilus_label_initialize_class):
+ Update for new smooth widget class registration scheme.
+
+ * libnautilus-extensions/nautilus-labeled-image.h:
+ * libnautilus-extensions/nautilus-labeled-image.c:
+ (nautilus_labeled_image_size_allocate),
+ (nautilus_labeled_image_get_image_bounds),
+ (nautilus_labeled_image_get_label_bounds):
+ Make these two functions public.
+
+ * libnautilus-extensions/nautilus-smooth-widget.h:
+ * libnautilus-extensions/nautilus-smooth-widget.c:
+ (smooth_widget_type_list_free), (smooth_widget_list_free),
+ (widget_is_smooth), (nautilus_smooth_widget_register),
+ (nautilus_smooth_widget_register_type):
+ Add mechanism for registering types that are meant to be smooth.
+ That way we dont need to hardcode the list of smooth widget
+ classes. Also made sure to free the static lists at exit time.
+
+ * libnautilus-extensions/nautilus-viewport.h:
+ * libnautilus-extensions/nautilus-viewport.c:
+ (nautilus_viewport_initialize_class),
+ (nautilus_viewport_initialize), (nautilus_viewport_destroy),
+ (nautilus_viewport_draw), (nautilus_viewport_expose_event),
+ (nautilus_viewport_realize), (nautilus_viewport_paint),
+ (nautilus_viewport_set_is_smooth_signal), (nautilus_viewport_new),
+ (nautilus_viewport_set_is_smooth),
+ (nautilus_viewport_get_scroll_offset):
+ Add support for smoothness. When the is_smooth attribute changes,
+ the viewport will not clear the background on resize - and so its
+ content will not flicker.
+
+ Add function for querying the scroll offset.
+
+ * libnautilus-extensions/nautilus-wrap-table.h:
+ * libnautilus-extensions/nautilus-wrap-table.c:
+ (wrap_table_get_content_frame), (wrap_table_get_scroll_offset),
+ (nautilus_wrap_table_get_homogeneous),
+ (nautilus_wrap_table_reorder_child):
+ Fix a mod by zero error.
+ Add support for reordering children.
+
+ * src/file-manager/fm-properties-window.c: (create_emblems_page):
+ Simplify a bit by using NautilusWrapTable instead of a GtkTable
+ with a hard coded number of columns. The emblems now wrap to fit
+ the available space. Also use NautilusLabeledImages instead of
+ boxes. Update for changes in customization data api.
+ Remove check box painting workaround. Its taken care of in
+ NautilusLabeledImage now.
+
+ * src/nautilus-property-browser.c:
+ (nautilus_property_browser_initialize_class),
+ (nautilus_property_browser_initialize), (element_clicked_callback),
+ (nautilus_property_browser_preferences_changed),
+ (make_property_tile), (make_properties_from_directories),
+ (add_reset_property), (make_properties_from_xml_node),
+ (property_browser_category_button_new), (make_category_link),
+ (nautilus_property_browser_update_contents),
+ (emit_emblems_changed_signal):
+ Use a NautilusImageTable instead of a GtkTable to make things wrap
+ propertly and thus not have to recreate the whole property box
+ each time its resized. Remove a lot of hard coded dimensions.
+ Simplified a bit by using NautilusLabeledImages.
+
+ * src/nautilus-search-bar-criterion.c: (make_emblem_value_menu):
+ Update for changes in customization data api.
+
+ * test/test-nautilus-image-table.c: (labeled_image_new),
+ (foo_timeout), (image_table_size_allocate),
+ (image_table_new_scrolled):
+ Update for new image table features.
+
2001-02-09 Andy Hertzfeld <andy@eazel.com>
* src/nautilus-sidebar.c:
diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am
index ade8ebef8..a8817c046 100644
--- a/libnautilus-extensions/Makefile.am
+++ b/libnautilus-extensions/Makefile.am
@@ -84,6 +84,7 @@ libnautilus_extensions_la_SOURCES = \
nautilus-ellipsizing-label.c \
nautilus-entry.c \
nautilus-enumeration.c \
+ nautilus-region.c \
nautilus-file-changes-queue.c \
nautilus-file-operations-progress.c \
nautilus-file-operations.c \
@@ -192,6 +193,7 @@ noinst_HEADERS = \
nautilus-ellipsizing-label.h \
nautilus-entry.h \
nautilus-enumeration.h \
+ nautilus-region.h \
nautilus-file-attributes.h \
nautilus-file-changes-queue.h \
nautilus-file-operations-progress.h \
diff --git a/libnautilus-extensions/nautilus-art-gtk-extensions.c b/libnautilus-extensions/nautilus-art-gtk-extensions.c
index 56ca5bc33..74ccb5878 100644
--- a/libnautilus-extensions/nautilus-art-gtk-extensions.c
+++ b/libnautilus-extensions/nautilus-art-gtk-extensions.c
@@ -262,3 +262,23 @@ nautilus_irect_gdk_window_clip_dirty_area_to_screen (const GdkWindow *gdk_window
return clipped;
}
+
+GdkRectangle
+nautilus_gdk_rectangle_assign_irect (const ArtIRect *irect)
+{
+ GdkRectangle gdk_rect;
+
+ gdk_rect.x = 0;
+ gdk_rect.y = 0;
+ gdk_rect.width = 0;
+ gdk_rect.height = 0;
+
+ g_return_val_if_fail (irect != NULL, gdk_rect);
+
+ gdk_rect.x = irect->x0;
+ gdk_rect.y = irect->y0;
+ gdk_rect.width = nautilus_art_irect_get_width (irect);
+ gdk_rect.height = nautilus_art_irect_get_height (irect);
+
+ return gdk_rect;
+}
diff --git a/libnautilus-extensions/nautilus-art-gtk-extensions.h b/libnautilus-extensions/nautilus-art-gtk-extensions.h
index e50350156..0bc2578a6 100644
--- a/libnautilus-extensions/nautilus-art-gtk-extensions.h
+++ b/libnautilus-extensions/nautilus-art-gtk-extensions.h
@@ -41,14 +41,15 @@
BEGIN_GNOME_DECLS
-ArtIRect nautilus_irect_assign_gdk_rectangle (const GdkRectangle *gdk_rectangle);
-ArtIRect nautilus_irect_screen_get_frame (void);
-ArtIRect nautilus_irect_gdk_window_get_bounds (const GdkWindow *gdk_window);
-ArtIRect nautilus_irect_gdk_window_get_screen_relative_bounds (const GdkWindow *gdk_window);
-ArtIRect nautilus_irect_gtk_widget_get_bounds (const GtkWidget *gtk_widget);
-ArtIRect nautilus_irect_gtk_widget_get_frame (const GtkWidget *gtk_widget);
-ArtIRect nautilus_irect_gdk_window_clip_dirty_area_to_screen (const GdkWindow *gdk_window,
- const ArtIRect *dirty_area);
+GdkRectangle nautilus_gdk_rectangle_assign_irect (const ArtIRect *irect);
+ArtIRect nautilus_irect_assign_gdk_rectangle (const GdkRectangle *gdk_rectangle);
+ArtIRect nautilus_irect_screen_get_frame (void);
+ArtIRect nautilus_irect_gdk_window_get_bounds (const GdkWindow *gdk_window);
+ArtIRect nautilus_irect_gdk_window_get_screen_relative_bounds (const GdkWindow *gdk_window);
+ArtIRect nautilus_irect_gtk_widget_get_bounds (const GtkWidget *gtk_widget);
+ArtIRect nautilus_irect_gtk_widget_get_frame (const GtkWidget *gtk_widget);
+ArtIRect nautilus_irect_gdk_window_clip_dirty_area_to_screen (const GdkWindow *gdk_window,
+ const ArtIRect *dirty_area);
END_GNOME_DECLS
diff --git a/libnautilus-extensions/nautilus-customization-data.c b/libnautilus-extensions/nautilus-customization-data.c
index d9a1c56c4..ce14234c2 100644
--- a/libnautilus-extensions/nautilus-customization-data.c
+++ b/libnautilus-extensions/nautilus-customization-data.c
@@ -46,8 +46,6 @@
#include "nautilus-gdk-extensions.h"
#include "nautilus-gtk-extensions.h"
#include "nautilus-xml-extensions.h"
-#include "nautilus-image.h"
-#include "nautilus-label.h"
#include "nautilus-string.h"
typedef enum {
@@ -155,15 +153,19 @@ nautilus_customization_data_new (const char *customization_name,
GnomeVFSResult
nautilus_customization_data_get_next_element_for_display (NautilusCustomizationData *data,
char **emblem_name,
- GtkWidget **pixmap_widget,
- GtkWidget **label)
+ GdkPixbuf **pixbuf_out,
+ char **label_out)
{
GnomeVFSFileInfo *current_file_info;
- char *image_file_name, *filtered_name, *truncated_name;
+ char *image_file_name, *filtered_name;
GdkPixbuf *pixbuf;
GdkPixbuf *orig_pixbuf;
-
+
+ g_return_val_if_fail (data != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (emblem_name != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (pixbuf_out != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (label_out != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
if (data->current_file_list == NULL) {
if (data->reading_mode == READ_PUBLIC_CUSTOMIZATIONS) {
@@ -174,14 +176,14 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
data->current_file_list = data->private_file_list;
return nautilus_customization_data_get_next_element_for_display (data,
emblem_name,
- pixmap_widget,
- label);
+ pixbuf_out,
+ label_out);
}
else {
- return GNOME_VFS_ERROR_EOF;
+ return GNOME_VFS_ERROR_EOF;
}
}
-
+
current_file_info = data->current_file_list->data;
data->current_file_list = data->current_file_list->next;
@@ -193,14 +195,14 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
return nautilus_customization_data_get_next_element_for_display (data,
emblem_name,
- pixmap_widget,
- label);
+ pixbuf_out,
+ label_out);
}
image_file_name = get_file_path_for_mode (data,
current_file_info->name);
- orig_pixbuf = gdk_pixbuf_new_from_file(image_file_name);
- g_free(image_file_name);
+ orig_pixbuf = gdk_pixbuf_new_from_file (image_file_name);
+ g_free (image_file_name);
*emblem_name = g_strdup (current_file_info->name);
@@ -213,9 +215,7 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
gdk_pixbuf_unref (orig_pixbuf);
}
- *pixmap_widget = nautilus_image_new (NULL);
- nautilus_image_set_pixbuf (NAUTILUS_IMAGE (*pixmap_widget), pixbuf);
- gdk_pixbuf_unref (pixbuf);
+ *pixbuf_out = pixbuf;
filtered_name = format_name_for_display (data, current_file_info->name);
/* If the data is for a menu,
@@ -223,12 +223,10 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
label because anti-aliased text doesn't look right
in menus */
if (data->data_is_for_a_menu) {
- truncated_name = nautilus_truncate_text_for_menu_item (filtered_name);
- *label = gtk_label_new (truncated_name);
- g_free (truncated_name);
+ *label_out = nautilus_truncate_text_for_menu_item (filtered_name);
}
else {
- *label = nautilus_label_new (filtered_name);
+ *label_out = g_strdup (filtered_name);
}
g_free (filtered_name);
diff --git a/libnautilus-extensions/nautilus-customization-data.h b/libnautilus-extensions/nautilus-customization-data.h
index 5f797a347..8cb39bc08 100644
--- a/libnautilus-extensions/nautilus-customization-data.h
+++ b/libnautilus-extensions/nautilus-customization-data.h
@@ -53,12 +53,8 @@ NautilusCustomizationData* nautilus_customization_data_new
*/
GnomeVFSResult nautilus_customization_data_get_next_element_for_display (NautilusCustomizationData *data,
char **emblem_name,
- GtkWidget **pixmap_widget,
-
-
- GtkWidget **label_widget);
-
-
+ GdkPixbuf **pixbuf_out,
+ char **label);
gboolean nautilus_customization_data_private_data_was_displayed (NautilusCustomizationData *data);
void nautilus_customization_data_destroy (NautilusCustomizationData *data);
diff --git a/libnautilus-extensions/nautilus-image-table.c b/libnautilus-extensions/nautilus-image-table.c
index 0c4f0cdd7..f9ec5b990 100644
--- a/libnautilus-extensions/nautilus-image-table.c
+++ b/libnautilus-extensions/nautilus-image-table.c
@@ -30,6 +30,8 @@
#include "nautilus-gtk-extensions.h"
#include "nautilus-art-extensions.h"
#include "nautilus-art-gtk-extensions.h"
+#include "nautilus-region.h"
+#include "nautilus-debug-drawing.h"
#include <gtk/gtkmain.h>
@@ -51,6 +53,9 @@ struct NautilusImageTableDetails
guint button_release_connection_id;
GtkWidget *child_under_pointer;
GtkWidget *child_being_pressed;
+ GdkGC *clear_gc;
+ guint32 smooth_background_color;
+ gboolean is_smooth;
};
/* Signals */
@@ -61,6 +66,7 @@ typedef enum
CHILD_PRESSED,
CHILD_RELEASED,
CHILD_CLICKED,
+ SET_IS_SMOOTH,
LAST_SIGNAL
} ImageTableSignals;
@@ -68,39 +74,54 @@ typedef enum
static guint image_table_signals[LAST_SIGNAL] = { 0 };
/* GtkObjectClass methods */
-static void nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_class);
-static void nautilus_image_table_initialize (NautilusImageTable *image);
-static void nautilus_image_table_destroy (GtkObject *object);
+static void nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_class);
+static void nautilus_image_table_initialize (NautilusImageTable *image);
+static void nautilus_image_table_destroy (GtkObject *object);
/* GtkWidgetClass methods */
-static void nautilus_image_table_realize (GtkWidget *widget);
-static void nautilus_image_table_unrealize (GtkWidget *widget);
+static int nautilus_image_table_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void nautilus_image_table_realize (GtkWidget *widget);
+static void nautilus_image_table_unrealize (GtkWidget *widget);
/* GtkContainerClass methods */
-static void nautilus_image_table_add (GtkContainer *container,
- GtkWidget *widget);
-static void nautilus_image_table_remove (GtkContainer *container,
- GtkWidget *widget);
-static GtkType nautilus_image_table_child_type (GtkContainer *container);
+static void nautilus_image_table_add (GtkContainer *container,
+ GtkWidget *widget);
+static void nautilus_image_table_remove (GtkContainer *container,
+ GtkWidget *widget);
+static GtkType nautilus_image_table_child_type (GtkContainer *container);
/* Private NautilusImageTable methods */
+static void image_table_clear_dirty_areas (NautilusImageTable *image_table);
+static GdkGC * image_table_peek_clear_gc (NautilusImageTable *image_table);
+static void image_table_emit_signal (NautilusImageTable *image_table,
+ GtkWidget *child,
+ guint signal_index,
+ int x,
+ int y,
+ int button,
+ guint state);
/* Ancestor callbacks */
-static int ancestor_enter_notify_event (GtkWidget *widget,
- GdkEventCrossing *event,
- gpointer event_data);
-static int ancestor_leave_notify_event (GtkWidget *widget,
- GdkEventCrossing *event,
- gpointer event_data);
-static int ancestor_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event,
- gpointer event_data);
-static int ancestor_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer event_data);
-static int ancestor_button_release_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer event_data);
+static int ancestor_enter_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer event_data);
+static int ancestor_leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer event_data);
+static int ancestor_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer event_data);
+static int ancestor_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer event_data);
+static int ancestor_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer event_data);
+
+/* NautilusImageTable signals */
+static void nautilus_image_table_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth);
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusImageTable, nautilus_image_table, NAUTILUS_TYPE_WRAP_TABLE)
@@ -116,6 +137,7 @@ nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_clas
object_class->destroy = nautilus_image_table_destroy;
/* GtkWidgetClass */
+ widget_class->expose_event = nautilus_image_table_expose_event;
widget_class->realize = nautilus_image_table_realize;
widget_class->unrealize = nautilus_image_table_unrealize;
@@ -123,7 +145,10 @@ nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_clas
container_class->add = nautilus_image_table_add;
container_class->remove = nautilus_image_table_remove;
container_class->child_type = nautilus_image_table_child_type;
-
+
+ /* NautilusImageTableClass */
+ image_table_class->set_is_smooth = nautilus_image_table_set_is_smooth_signal;
+
/* Signals */
image_table_signals[CHILD_ENTER] = gtk_signal_new ("child_enter",
GTK_RUN_LAST,
@@ -171,7 +196,19 @@ nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_clas
GTK_TYPE_POINTER,
GTK_TYPE_POINTER);
+ image_table_signals[SET_IS_SMOOTH] = gtk_signal_new ("set_is_smooth",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusImageTableClass, set_is_smooth),
+ gtk_marshal_NONE__BOOL,
+ GTK_TYPE_NONE,
+ 1,
+ GTK_TYPE_BOOL);
+
gtk_object_class_add_signals (object_class, image_table_signals, LAST_SIGNAL);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_IMAGE_TABLE);
}
void
@@ -180,6 +217,9 @@ nautilus_image_table_initialize (NautilusImageTable *image_table)
GTK_WIDGET_SET_FLAGS (image_table, GTK_NO_WINDOW);
image_table->details = g_new0 (NautilusImageTableDetails, 1);
+ image_table->details->smooth_background_color = NAUTILUS_RGB_COLOR_WHITE;
+
+ nautilus_smooth_widget_register (GTK_WIDGET (image_table));
}
/* GtkObjectClass methods */
@@ -199,6 +239,28 @@ nautilus_image_table_destroy (GtkObject *object)
}
/* GtkWidgetClass methods */
+static int
+nautilus_image_table_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ NautilusImageTable *image_table;
+
+ g_return_val_if_fail (NAUTILUS_IS_WRAP_TABLE (widget), TRUE);
+ g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), TRUE);
+ g_return_val_if_fail (event != NULL, TRUE);
+
+ image_table = NAUTILUS_IMAGE_TABLE (widget);
+
+ /* In smooth mode we clear dirty areas, since our background wont be
+ * force clear and thus avoid flicker.
+ */
+ if (image_table->details->is_smooth) {
+ image_table_clear_dirty_areas (image_table);
+ }
+
+ return NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, expose_event, (widget, event));
+}
+
static void
nautilus_image_table_realize (GtkWidget *widget)
{
@@ -217,6 +279,7 @@ nautilus_image_table_realize (GtkWidget *widget)
gtk_widget_add_events (image_table->details->windowed_ancestor,
GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
+ | GDK_BUTTON_MOTION_MASK
| GDK_ENTER_NOTIFY_MASK
| GDK_LEAVE_NOTIFY_MASK
| GDK_POINTER_MOTION_MASK);
@@ -283,6 +346,11 @@ nautilus_image_table_unrealize (GtkWidget *widget)
image_table->details->button_press_connection_id = 0;
image_table->details->button_release_connection_id = 0;
+ if (image_table->details->clear_gc != NULL) {
+ gdk_gc_unref (image_table->details->clear_gc);
+ image_table->details->clear_gc = NULL;
+ }
+
/* Chain unrealize */
NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, unrealize, (widget));
}
@@ -331,7 +399,125 @@ nautilus_image_table_child_type (GtkContainer *container)
return NAUTILUS_TYPE_LABELED_IMAGE;
}
+/* NautilusImageTable signals */
+static void
+nautilus_image_table_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (widget));
+
+ nautilus_image_table_set_is_smooth (NAUTILUS_IMAGE_TABLE (widget), is_smooth);
+}
+
/* Private NautilusImageTable methods */
+
+/* For each of the image table children, subtract their content from a region */
+static void
+image_table_foreach_child_subtract_content (GtkWidget *child,
+ gpointer callback_data)
+{
+ NautilusRegion *region;
+ ArtIRect label_bounds;
+ ArtIRect image_bounds;
+
+ g_return_if_fail (NAUTILUS_IS_LABELED_IMAGE (child));
+ g_return_if_fail (callback_data != NULL);
+
+ if (!GTK_WIDGET_VISIBLE (child)) {
+ return;
+ }
+
+ region = callback_data;
+
+ image_bounds = nautilus_labeled_image_get_image_bounds (NAUTILUS_LABELED_IMAGE (child));
+ if (!art_irect_empty (&image_bounds)) {
+ nautilus_region_subtract_rectangle (region, &image_bounds);
+ }
+
+ label_bounds = nautilus_labeled_image_get_label_bounds (NAUTILUS_LABELED_IMAGE (child));
+ if (!art_irect_empty (&label_bounds)) {
+ nautilus_region_subtract_rectangle (region, &label_bounds);
+ }
+}
+
+/* Clear the dirty areas around the children's content */
+static void
+image_table_clear_dirty_areas (NautilusImageTable *image_table)
+{
+ GtkWidget *widget;
+ NautilusRegion *region;
+ ArtIRect bounds;
+ GdkGC *gc;
+
+ g_return_if_fail (NAUTILUS_IS_WRAP_TABLE (image_table));
+ g_return_if_fail (GTK_WIDGET_REALIZED (image_table));
+
+ widget = GTK_WIDGET (image_table);
+
+ bounds = nautilus_irect_gtk_widget_get_frame (widget->parent);
+ region = nautilus_region_new ();
+
+ nautilus_region_add_rectangle (region, &bounds);
+
+ gc = image_table_peek_clear_gc (image_table);
+
+ gtk_container_foreach (GTK_CONTAINER (image_table), image_table_foreach_child_subtract_content, region);
+
+ nautilus_region_set_gc_clip_region (region, gc);
+
+ gdk_draw_rectangle (widget->window,
+ gc,
+ TRUE,
+ bounds.x0,
+ bounds.y0,
+ bounds.x1 - bounds.x0,
+ bounds.y1 - bounds.y0);
+
+ nautilus_region_free (region);
+}
+
+static GdkGC *
+image_table_peek_clear_gc (NautilusImageTable *image_table)
+{
+ g_return_val_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table), NULL);
+
+ if (image_table->details->clear_gc == NULL) {
+ image_table->details->clear_gc = gdk_gc_new (GTK_WIDGET (image_table)->window);
+ gdk_gc_set_function (image_table->details->clear_gc, GDK_COPY);
+ }
+
+ gdk_rgb_gc_set_foreground (image_table->details->clear_gc, image_table->details->smooth_background_color);
+
+ return image_table->details->clear_gc;
+}
+
+static void
+image_table_emit_signal (NautilusImageTable *image_table,
+ GtkWidget *child,
+ guint signal_index,
+ int x,
+ int y,
+ int button,
+ guint state)
+{
+ NautilusImageTableEvent event;
+
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (signal_index >= 0);
+ g_return_if_fail (signal_index < LAST_SIGNAL);
+
+ event.x = x;
+ event.y = y;
+ event.button = button;
+ event.state = state;
+
+ gtk_signal_emit (GTK_OBJECT (image_table),
+ image_table_signals[signal_index],
+ child,
+ &event);
+}
+
static void
image_table_handle_motion (NautilusImageTable *image_table,
int x,
@@ -366,17 +552,23 @@ image_table_handle_motion (NautilusImageTable *image_table,
}
if (leave_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_LEAVE],
- leave_emit_child,
- event);
+ image_table_emit_signal (image_table,
+ leave_emit_child,
+ CHILD_LEAVE,
+ x,
+ y,
+ 0,
+ 0);
}
if (enter_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_ENTER],
- enter_emit_child,
- event);
+ image_table_emit_signal (image_table,
+ enter_emit_child,
+ CHILD_ENTER,
+ x,
+ y,
+ 0,
+ 0);
}
}
@@ -447,17 +639,18 @@ ancestor_button_press_event (GtkWidget *widget,
image_table = NAUTILUS_IMAGE_TABLE (event_data);
- gtk_grab_add (widget);
-
child = nautilus_wrap_table_find_child_at_event_point (NAUTILUS_WRAP_TABLE (image_table), event->x, event->y);
if (child != NULL) {
if (child == image_table->details->child_under_pointer) {
image_table->details->child_being_pressed = child;
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_PRESSED],
- child,
- event);
+ image_table_emit_signal (image_table,
+ child,
+ CHILD_PRESSED,
+ event->x,
+ event->y,
+ event->button,
+ event->state);
}
}
@@ -480,8 +673,6 @@ ancestor_button_release_event (GtkWidget *widget,
image_table = NAUTILUS_IMAGE_TABLE (event_data);
- gtk_grab_remove (widget);
-
child = nautilus_wrap_table_find_child_at_event_point (NAUTILUS_WRAP_TABLE (image_table), event->x, event->y);
if (image_table->details->child_being_pressed != NULL) {
@@ -497,17 +688,24 @@ ancestor_button_release_event (GtkWidget *widget,
image_table->details->child_being_pressed = NULL;
if (released_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_RELEASED],
- released_emit_child,
- event);
+ image_table_emit_signal (image_table,
+ released_emit_child,
+ CHILD_RELEASED,
+ event->x,
+ event->y,
+ event->button,
+ event->state);
}
if (clicked_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_CLICKED],
- clicked_emit_child,
- event);
+
+ image_table_emit_signal (image_table,
+ clicked_emit_child,
+ CHILD_CLICKED,
+ event->x,
+ event->y,
+ event->button,
+ event->state);
}
return FALSE;
@@ -527,3 +725,41 @@ nautilus_image_table_new (gboolean homogeneous)
return GTK_WIDGET (image_table);
}
+
+/**
+ * nautilus_image_table_set_is_smooth:
+ * @image_table: A NautilusImageTable.
+ * @is_smooth: Boolean value indicating whether the image table is smooth.
+ *
+ */
+void
+nautilus_image_table_set_is_smooth (NautilusImageTable *image_table,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+
+ if (image_table->details->is_smooth == is_smooth) {
+ return;
+ }
+
+ image_table->details->is_smooth = is_smooth;
+}
+
+/**
+ * nautilus_image_table_set_smooth_background_color:
+ * @image_table: A NautilusImageTable.
+ * @smooth_background_color: The color to use for background in smooth mode.
+ *
+ */
+void
+nautilus_image_table_set_smooth_background_color (NautilusImageTable *image_table,
+ guint32 smooth_background_color)
+{
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+
+ if (image_table->details->smooth_background_color == smooth_background_color) {
+ return;
+ }
+
+ image_table->details->smooth_background_color = smooth_background_color;
+}
diff --git a/libnautilus-extensions/nautilus-image-table.h b/libnautilus-extensions/nautilus-image-table.h
index 9397f7b89..9ae424702 100644
--- a/libnautilus-extensions/nautilus-image-table.h
+++ b/libnautilus-extensions/nautilus-image-table.h
@@ -27,6 +27,7 @@
#include <libnautilus-extensions/nautilus-wrap-table.h>
#include <libnautilus-extensions/nautilus-labeled-image.h>
+#include <libnautilus-extensions/nautilus-smooth-widget.h>
BEGIN_GNOME_DECLS
@@ -52,6 +53,7 @@ struct NautilusImageTable
struct NautilusImageTableClass
{
NautilusWrapTableClass parent_class;
+ NautilusSmoothWidgetSetIsSmooth set_is_smooth;
};
typedef struct
@@ -63,8 +65,12 @@ typedef struct
} NautilusImageTableEvent;
/* Public GtkImageTable methods */
-GtkType nautilus_image_table_get_type (void);
-GtkWidget *nautilus_image_table_new (gboolean homogeneous);
+GtkType nautilus_image_table_get_type (void);
+GtkWidget *nautilus_image_table_new (gboolean homogeneous);
+void nautilus_image_table_set_smooth_background_color (NautilusImageTable *image_table,
+ guint32 smooth_background_color);
+void nautilus_image_table_set_is_smooth (NautilusImageTable *image_table,
+ gboolean is_smooth);
END_GNOME_DECLS
diff --git a/libnautilus-extensions/nautilus-image.c b/libnautilus-extensions/nautilus-image.c
index 746046a36..173b1d340 100644
--- a/libnautilus-extensions/nautilus-image.c
+++ b/libnautilus-extensions/nautilus-image.c
@@ -198,6 +198,9 @@ nautilus_image_initialize_class (NautilusImageClass *image_class)
/* Make this class inherit the same kind of theme stuff as GtkPixmap */
nautilus_gtk_class_name_make_like_existing_type ("NautilusImage", GTK_TYPE_PIXMAP);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_IMAGE);
}
void
diff --git a/libnautilus-extensions/nautilus-label.c b/libnautilus-extensions/nautilus-label.c
index 93de1d77e..bb19e61fc 100644
--- a/libnautilus-extensions/nautilus-label.c
+++ b/libnautilus-extensions/nautilus-label.c
@@ -145,8 +145,8 @@ static void nautilus_label_get_arg (GtkObject
/* GtkWidgetClass methods */
static void nautilus_label_size_request (GtkWidget *widget,
GtkRequisition *requisition);
-static void nautilus_label_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
+static void nautilus_label_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
static int nautilus_label_expose_event (GtkWidget *widget,
GdkEventExpose *event);
@@ -293,6 +293,9 @@ nautilus_label_initialize_class (NautilusLabelClass *label_class)
/* Make this class inherit the same kind of theme stuff as GtkLabel */
nautilus_gtk_class_name_make_like_existing_type ("NautilusLabel", GTK_TYPE_LABEL);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_LABEL);
}
void
diff --git a/libnautilus-extensions/nautilus-labeled-image.c b/libnautilus-extensions/nautilus-labeled-image.c
index 47f3a768a..c53d59e4d 100644
--- a/libnautilus-extensions/nautilus-labeled-image.c
+++ b/libnautilus-extensions/nautilus-labeled-image.c
@@ -110,8 +110,6 @@ static void nautilus_labeled_image_forall (GtkContainer
/* Private NautilusLabeledImage methods */
static ArtIRect labeled_image_get_image_frame (const NautilusLabeledImage *labeled_image);
static ArtIRect labeled_image_get_label_frame (const NautilusLabeledImage *labeled_image);
-static ArtIRect labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image);
-static ArtIRect labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image);
static void labeled_image_ensure_label (NautilusLabeledImage *labeled_image);
static void labeled_image_ensure_image (NautilusLabeledImage *labeled_image);
static ArtIRect labeled_image_get_content_bounds (const NautilusLabeledImage *labeled_image);
@@ -389,7 +387,7 @@ nautilus_labeled_image_size_allocate (GtkWidget *widget,
widget->allocation = *allocation;
- label_bounds = labeled_image_get_label_bounds (labeled_image);
+ label_bounds = nautilus_labeled_image_get_label_bounds (labeled_image);
if (!art_irect_empty (&label_bounds)) {
GtkAllocation label_allocation;
@@ -401,7 +399,7 @@ nautilus_labeled_image_size_allocate (GtkWidget *widget,
gtk_widget_size_allocate (labeled_image->details->label, &label_allocation);
}
- image_bounds = labeled_image_get_image_bounds (labeled_image);
+ image_bounds = nautilus_labeled_image_get_image_bounds (labeled_image);
if (!art_irect_empty (&image_bounds)) {
GtkAllocation image_allocation;
@@ -584,6 +582,7 @@ nautilus_labeled_image_forall (GtkContainer *container,
}
}
+/* Private NautilusLabeledImage methods */
static ArtIRect
labeled_image_get_image_frame (const NautilusLabeledImage *labeled_image)
{
@@ -684,8 +683,8 @@ labeled_image_get_image_bounds_fill (const NautilusLabeledImage *labeled_image)
return image_bounds;
}
-static ArtIRect
-labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image)
+ArtIRect
+nautilus_labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image)
{
ArtIRect image_frame;
ArtIRect image_bounds;
@@ -808,8 +807,8 @@ labeled_image_get_label_bounds_fill (const NautilusLabeledImage *labeled_image)
return label_bounds;
}
-static ArtIRect
-labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image)
+ArtIRect
+nautilus_labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image)
{
ArtIRect label_bounds;
ArtIRect label_frame;
diff --git a/libnautilus-extensions/nautilus-labeled-image.h b/libnautilus-extensions/nautilus-labeled-image.h
index 9be437b68..13d91f0d2 100644
--- a/libnautilus-extensions/nautilus-labeled-image.h
+++ b/libnautilus-extensions/nautilus-labeled-image.h
@@ -160,6 +160,8 @@ void nautilus_labeled_image_set_text_color (Nautilu
guint32 text_color);
void nautilus_labeled_image_set_label_never_smooth (NautilusLabeledImage *labeled_image,
gboolean never_smooth);
+ArtIRect nautilus_labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image);
+ArtIRect nautilus_labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image);
END_GNOME_DECLS
diff --git a/libnautilus-extensions/nautilus-region.c b/libnautilus-extensions/nautilus-region.c
new file mode 100644
index 000000000..2ab4da988
--- /dev/null
+++ b/libnautilus-extensions/nautilus-region.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-region.c: A simple wrapper on GdkRegion with rectangle operations.
+
+ 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: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#include <config.h>
+
+#include "nautilus-region.h"
+
+#include "nautilus-glib-extensions.h"
+#include "nautilus-art-gtk-extensions.h"
+
+struct NautilusRegion
+{
+ GdkRegion *gdk_region;
+};
+
+NautilusRegion *
+nautilus_region_new (void)
+{
+ NautilusRegion *region;
+
+ region = g_new0 (NautilusRegion, 1);
+
+ region->gdk_region = gdk_region_new ();
+
+ return region;
+}
+
+void
+nautilus_region_free (NautilusRegion *region)
+{
+ if (region == NULL) {
+ return;
+ }
+
+ g_assert (region->gdk_region != NULL);
+ gdk_region_destroy (region->gdk_region);
+
+ g_free (region);
+}
+
+static GdkRegion *
+gdk_region_new_from_irect (const ArtIRect *art_rect)
+{
+ GdkRegion *region;
+ GdkRegion *empty_region;
+ GdkRectangle gdk_rect;
+
+ g_return_val_if_fail (art_rect != NULL, NULL);
+
+ gdk_rect = nautilus_gdk_rectangle_assign_irect (art_rect);
+ empty_region = gdk_region_new ();
+ region = gdk_region_union_with_rect (empty_region, &gdk_rect);
+ gdk_region_destroy (empty_region);
+
+ return region;
+}
+
+void
+nautilus_region_add_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle)
+{
+ GdkRegion *add_region;
+ GdkRegion *new_region;
+
+ g_return_if_fail (region != NULL);
+ g_return_if_fail (rectangle != NULL);
+ g_return_if_fail (!art_irect_empty (rectangle));
+
+ add_region = gdk_region_new_from_irect (rectangle);
+ new_region = gdk_regions_union (region->gdk_region, add_region);
+ gdk_region_destroy (add_region);
+ gdk_region_destroy (region->gdk_region);
+ region->gdk_region = new_region;
+}
+
+void
+nautilus_region_subtract_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle)
+{
+ GdkRegion *subtract_region;
+ GdkRegion *new_region;
+
+ g_return_if_fail (region != NULL);
+ g_return_if_fail (rectangle != NULL);
+ g_return_if_fail (!art_irect_empty (rectangle));
+
+ subtract_region = gdk_region_new_from_irect (rectangle);
+ new_region = gdk_regions_subtract (region->gdk_region, subtract_region);
+ gdk_region_destroy (subtract_region);
+ gdk_region_destroy (region->gdk_region);
+ region->gdk_region = new_region;
+}
+
+void
+nautilus_region_set_gc_clip_region (const NautilusRegion *region,
+ GdkGC *gc)
+{
+ g_return_if_fail (region != NULL);
+ g_return_if_fail (gc != NULL);
+
+ gdk_gc_set_clip_region (gc, region->gdk_region);
+}
diff --git a/libnautilus-extensions/nautilus-region.h b/libnautilus-extensions/nautilus-region.h
new file mode 100644
index 000000000..1727469ad
--- /dev/null
+++ b/libnautilus-extensions/nautilus-region.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-region.h: A simple wrapper on GdkRegion with rectangle operations.
+
+ 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: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#ifndef NAUTILUS_REGION_H
+#define NAUTILUS_REGION_H
+
+#include <libgnome/gnome-defs.h>
+#include <libart_lgpl/art_rect.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+
+/* Opaque NautilusRegion declaration. */
+typedef struct NautilusRegion NautilusRegion;
+
+NautilusRegion *nautilus_region_new (void);
+void nautilus_region_free (NautilusRegion *region);
+void nautilus_region_add_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle);
+void nautilus_region_subtract_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle);
+void nautilus_region_set_gc_clip_region (const NautilusRegion *region,
+ GdkGC *gc);
+
+#endif /* NAUTILUS_REGION_H */
+
diff --git a/libnautilus-extensions/nautilus-smooth-widget.c b/libnautilus-extensions/nautilus-smooth-widget.c
index 3b144263e..28b7ba72a 100644
--- a/libnautilus-extensions/nautilus-smooth-widget.c
+++ b/libnautilus-extensions/nautilus-smooth-widget.c
@@ -88,29 +88,42 @@ static void smooth_widget_paint_tile_and_content_transparent (GtkWi
*/
static GList *smooth_widget_list = NULL;
-
-/* We dont want to have any knowledge of NautilusImage and NautilusLabel
- * in this file. All the smooth widget operations herein should work on
- * either one without special casing. However, since NautilusImage and
- * NautilusLabel are subclassed from different super types, we cant make
- * cast checks for a common superclass. Thus the hack below of.
- *
- * We dont include the headers for NautilusImage and NautilusLabel instead
- * because we dont want special cased turds for each one to appear
- * in this file.
- *
- * Another assumption we make is that smooth widgets are subclasses from
- * GtkMisc.
+/* We maintain a global list of types that can be smooth widgets.
+ * We do this mostly for type safety - to make sure smooth operations only
+ * happen on smooth widgets.
*/
-extern GtkType nautilus_image_get_type (void);
-extern GtkType nautilus_label_get_type (void);
+static GList *smooth_widget_type_list = NULL;
+
+static void
+smooth_widget_type_list_free (void)
+{
+ g_list_free (smooth_widget_type_list);
+ smooth_widget_type_list = NULL;
+}
+
+static void
+smooth_widget_list_free (void)
+{
+ g_list_free (smooth_widget_list);
+ smooth_widget_list = NULL;
+}
static gboolean
widget_is_smooth (const GtkWidget *widget)
{
- return ((GTK_CHECK_TYPE ((widget), nautilus_image_get_type ())
- || GTK_CHECK_TYPE ((widget), nautilus_label_get_type ()))
- && GTK_IS_MISC (widget));
+ GList *node;
+
+ for (node = smooth_widget_type_list; node ; node = node->next) {
+ GtkType type;
+
+ type = GPOINTER_TO_INT (node->data);
+
+ if (GTK_CHECK_TYPE ((widget), type)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
}
static void
@@ -166,6 +179,10 @@ nautilus_smooth_widget_register (GtkWidget *widget)
smooth_widget_set_is_smooth (widget, preferences_get_is_smooth ());
+ if (smooth_widget_list == NULL) {
+ g_atexit (smooth_widget_list_free);
+ }
+
smooth_widget_list = g_list_prepend (smooth_widget_list, widget);
/* Keep track of the widget's destruction so we can purge it */
@@ -976,3 +993,14 @@ nautilus_smooth_widget_get_preferred_frame (const GtkWidget *widget,
return preferred_frame;
}
+
+void
+nautilus_smooth_widget_register_type (GtkType type)
+{
+ if (smooth_widget_type_list == NULL) {
+ g_atexit (smooth_widget_type_list_free);
+ }
+
+ smooth_widget_type_list = g_list_append (smooth_widget_type_list, GINT_TO_POINTER (type));
+}
+
diff --git a/libnautilus-extensions/nautilus-smooth-widget.h b/libnautilus-extensions/nautilus-smooth-widget.h
index a1119b695..007f8769c 100644
--- a/libnautilus-extensions/nautilus-smooth-widget.h
+++ b/libnautilus-extensions/nautilus-smooth-widget.h
@@ -110,6 +110,7 @@ ArtIRect nautilus_smooth_widget_get_preferred_frame (const GtkWidget
const ArtIRect *tile_frame,
int tile_width,
int tile_height);
+void nautilus_smooth_widget_register_type (GtkType type);
END_GNOME_DECLS
diff --git a/libnautilus-extensions/nautilus-viewport.c b/libnautilus-extensions/nautilus-viewport.c
index 898bab8c0..03c52ba5f 100644
--- a/libnautilus-extensions/nautilus-viewport.c
+++ b/libnautilus-extensions/nautilus-viewport.c
@@ -28,105 +28,247 @@
#include "nautilus-gtk-macros.h"
+#include <gtk/gtksignal.h>
+
+/* Detail member struct */
+struct NautilusViewportDetails
+{
+ gboolean is_smooth;
+};
+
/* GtkObjectClass methods */
-static void nautilus_viewport_initialize_class (NautilusViewportClass *viewport_class);
-static void nautilus_viewport_initialize (NautilusViewport *viewport);
-static void nautilus_viewport_draw (GtkWidget *widget,
- GdkRectangle *area);
+static void nautilus_viewport_initialize_class (NautilusViewportClass *viewport_class);
+static void nautilus_viewport_initialize (NautilusViewport *viewport);
+static void nautilus_viewport_destroy (GtkObject *object);
+
+/* GtkWidgetClass methods */
+static void nautilus_viewport_realize (GtkWidget *widget);
+static void nautilus_viewport_draw (GtkWidget *widget,
+ GdkRectangle *area);
+static gint nautilus_viewport_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void nautilus_viewport_paint (GtkWidget *widget,
+ GdkRectangle *area);
+
+/* NautilusViewport signals */
+static void nautilus_viewport_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth);
+
+/* Signals */
+typedef enum
+{
+ SET_IS_SMOOTH,
+ LAST_SIGNAL
+} NautilusViewportSignal;
-static void nautilus_viewport_paint (GtkWidget *widget,
- GdkRectangle *area);
+/* Signals */
+static guint nautilus_viewport_signals[LAST_SIGNAL] = { 0 };
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusViewport, nautilus_viewport, GTK_TYPE_VIEWPORT)
-/* Class init methods */
+/* GtkObjectClass methods */
static void
-nautilus_viewport_initialize_class (NautilusViewportClass *viewport_class)
+nautilus_viewport_initialize_class (NautilusViewportClass *nautilus_viewport_class)
{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (viewport_class);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (nautilus_viewport_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (nautilus_viewport_class);
+
+ /* GtkObjectClass */
+ object_class->destroy = nautilus_viewport_destroy;
/* GtkWidgetClass */
+ widget_class->realize = nautilus_viewport_realize;
+ widget_class->expose_event = nautilus_viewport_expose_event;
widget_class->draw = nautilus_viewport_draw;
+
+ /* NautilusViewportClass */
+ nautilus_viewport_class->set_is_smooth = nautilus_viewport_set_is_smooth_signal;
+
+ nautilus_viewport_signals[SET_IS_SMOOTH] =
+ gtk_signal_new ("set_is_smooth",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusViewportClass, set_is_smooth),
+ gtk_marshal_NONE__BOOL,
+ GTK_TYPE_NONE,
+ 1,
+ GTK_TYPE_BOOL);
+
+ gtk_object_class_add_signals (object_class, nautilus_viewport_signals, LAST_SIGNAL);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_VIEWPORT);
+}
+
+void
+nautilus_viewport_initialize (NautilusViewport *nautilus_viewport)
+{
+ nautilus_viewport->details = g_new0 (NautilusViewportDetails, 1);
+
+ nautilus_smooth_widget_register (GTK_WIDGET (nautilus_viewport));
}
void
-nautilus_viewport_initialize (NautilusViewport *viewport)
+nautilus_viewport_destroy (GtkObject *object)
{
- /* noop */
+ NautilusViewport *viewport;
+
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (object));
+
+ viewport = NAUTILUS_VIEWPORT (object);
+
+ g_free (viewport->details);
+
+ /* Chain destroy */
+ NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
}
+/* GtkWidgetClass methods */
static void
nautilus_viewport_draw (GtkWidget *widget,
GdkRectangle *area)
{
+ NautilusViewport *nautilus_viewport;
GtkViewport *viewport;
GtkBin *bin;
GdkRectangle tmp_area;
GdkRectangle child_area;
gint border_width;
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_VIEWPORT (widget));
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (widget));
g_return_if_fail (area != NULL);
- if (GTK_WIDGET_DRAWABLE (widget)) {
- viewport = GTK_VIEWPORT (widget);
- bin = GTK_BIN (widget);
-
- border_width = GTK_CONTAINER (widget)->border_width;
-
- tmp_area = *area;
- tmp_area.x -= border_width;
- tmp_area.y -= border_width;
-
- nautilus_viewport_paint (widget, &tmp_area);
-
- tmp_area.x += viewport->hadjustment->value - widget->style->klass->xthickness;
- tmp_area.y += viewport->vadjustment->value - widget->style->klass->ythickness;
-
- /* The gtk_viewport_draw() version does not adjust the width
- * and height of the tmp_area for the class x/y thickness. This
- * causes some drawing to be clipped on the bottom. This is a bug
- * in GTK+.
- */
-
- /* FIXME bugzilla.eazel.com xxxx:
- * Remove this widget once the fix makes it to GTK+.
- */
- tmp_area.width += 2 * widget->style->klass->xthickness;
- tmp_area.height += 2 * widget->style->klass->ythickness;
-
- gtk_paint_flat_box(widget->style, viewport->bin_window,
- GTK_STATE_NORMAL, GTK_SHADOW_NONE,
- &tmp_area, widget, "viewportbin",
- 0, 0, -1, -1);
+ if (!GTK_WIDGET_DRAWABLE (widget)) {
+ return;
+ }
+
+ nautilus_viewport = NAUTILUS_VIEWPORT (widget);
+ viewport = GTK_VIEWPORT (widget);
+ bin = GTK_BIN (widget);
+
+ border_width = GTK_CONTAINER (widget)->border_width;
+
+ tmp_area = *area;
+ tmp_area.x -= border_width;
+ tmp_area.y -= border_width;
+
+ nautilus_viewport_paint (widget, &tmp_area);
+
+ tmp_area.x += viewport->hadjustment->value - widget->style->klass->xthickness;
+ tmp_area.y += viewport->vadjustment->value - widget->style->klass->ythickness;
+
+ /* The gtk_viewport_draw() version does not adjust the width
+ * and height of the tmp_area for the class x/y thickness. This
+ * causes some drawing to be clipped on the bottom. This is a bug
+ * in GTK+.
+ */
+
+ /* FIXME bugzilla.eazel.com xxxx:
+ * Remove this widget once the fix makes it to GTK+.
+ */
+ tmp_area.width += 2 * widget->style->klass->xthickness;
+ tmp_area.height += 2 * widget->style->klass->ythickness;
+
+ if (!nautilus_viewport->details->is_smooth) {
+ gtk_paint_flat_box (widget->style, viewport->bin_window,
+ GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+ &tmp_area, widget, "viewportbin",
+ 0, 0, -1, -1);
+ }
+
+ if (bin->child) {
+ if (gtk_widget_intersect (bin->child, &tmp_area, &child_area)) {
+ gtk_widget_draw (bin->child, &child_area);
+ }
+ }
+}
+
+static gint
+nautilus_viewport_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ NautilusViewport *nautilus_viewport;
+ GtkViewport *viewport;
+ GtkBin *bin;
+
+ g_return_val_if_fail (NAUTILUS_IS_VIEWPORT (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ if (!GTK_WIDGET_DRAWABLE (widget)) {
+ return FALSE;
+ }
+
+ nautilus_viewport = NAUTILUS_VIEWPORT (widget);
+ viewport = GTK_VIEWPORT (widget);
+ bin = GTK_BIN (widget);
+
+ if (event->window == widget->window) {
+ nautilus_viewport_paint (widget, &event->area);
+ } else if (event->window == viewport->bin_window) {
+ GdkEventExpose child_event;
+
+ child_event = *event;
- if (bin->child) {
- if (gtk_widget_intersect (bin->child, &tmp_area, &child_area)) {
- gtk_widget_draw (bin->child, &child_area);
- }
+ if (!nautilus_viewport->details->is_smooth) {
+ gtk_paint_flat_box (widget->style, viewport->bin_window,
+ GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+ &event->area, widget, "viewportbin",
+ 0, 0, -1, -1);
}
+
+ if ((bin->child != NULL) &&
+ GTK_WIDGET_NO_WINDOW (bin->child) &&
+ gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+ gtk_widget_event (bin->child, (GdkEvent*) &child_event);
}
+
+ return FALSE;
+}
+
+static void
+nautilus_viewport_realize (GtkWidget *widget)
+{
+ NautilusViewport *nautilus_viewport;
+
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (widget));
+
+ nautilus_viewport = NAUTILUS_VIEWPORT (widget);
+
+ /* GtkViewport does the actual realization */
+ NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, realize, (widget));
+
+ nautilus_viewport_set_is_smooth (nautilus_viewport, nautilus_viewport->details->is_smooth);
}
static void
nautilus_viewport_paint (GtkWidget *widget,
GdkRectangle *area)
{
- GtkViewport *viewport;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_VIEWPORT (widget));
- g_return_if_fail (area != NULL);
+ GtkViewport *viewport;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_VIEWPORT (widget));
+ g_return_if_fail (area != NULL);
+
+ if (!GTK_WIDGET_DRAWABLE (widget)) {
+ return;
+ }
- if (GTK_WIDGET_DRAWABLE (widget))
- {
- viewport = GTK_VIEWPORT (widget);
+ viewport = GTK_VIEWPORT (widget);
+
+ gtk_draw_shadow (widget->style, widget->window,
+ GTK_STATE_NORMAL, viewport->shadow_type,
+ 0, 0, -1, -1);
+}
- gtk_draw_shadow (widget->style, widget->window,
- GTK_STATE_NORMAL, viewport->shadow_type,
- 0, 0, -1, -1);
- }
+/* NautilusViewport signals */
+static void
+nautilus_viewport_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (widget));
+
+ nautilus_viewport_set_is_smooth (NAUTILUS_VIEWPORT (widget), is_smooth);
}
/* Public NautilusViewport methods */
@@ -134,12 +276,47 @@ GtkWidget*
nautilus_viewport_new (GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment)
{
- NautilusViewport *viewport;
+ NautilusViewport *nautilus_viewport;
- viewport = NAUTILUS_VIEWPORT (gtk_widget_new (nautilus_viewport_get_type (), NULL));
+ nautilus_viewport = NAUTILUS_VIEWPORT (gtk_widget_new (nautilus_viewport_get_type (), NULL));
- gtk_viewport_set_hadjustment (GTK_VIEWPORT (viewport), hadjustment);
- gtk_viewport_set_vadjustment (GTK_VIEWPORT (viewport), vadjustment);
+ gtk_viewport_set_hadjustment (GTK_VIEWPORT (nautilus_viewport), hadjustment);
+ gtk_viewport_set_vadjustment (GTK_VIEWPORT (nautilus_viewport), vadjustment);
+
+ return GTK_WIDGET (nautilus_viewport);
+}
+
+void
+nautilus_viewport_set_is_smooth (NautilusViewport *nautilus_viewport,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (nautilus_viewport));
+
+ nautilus_viewport->details->is_smooth = is_smooth;
+
+ if (!GTK_WIDGET_REALIZED (nautilus_viewport)) {
+ return;
+ }
+
+ gdk_window_set_static_gravities (GTK_WIDGET (nautilus_viewport)->window, is_smooth);
+ gdk_window_set_static_gravities (GTK_VIEWPORT (nautilus_viewport)->bin_window, is_smooth);
+ gdk_window_set_static_gravities (GTK_VIEWPORT (nautilus_viewport)->view_window, is_smooth);
+}
+
+NautilusArtIPoint
+nautilus_viewport_get_scroll_offset (const NautilusViewport *nautilus_viewport)
+{
+ NautilusArtIPoint scroll_offset;
+
+ g_return_val_if_fail (NAUTILUS_IS_VIEWPORT (nautilus_viewport), NAUTILUS_ART_IPOINT_ZERO);
+
+ if (!GTK_WIDGET_REALIZED (nautilus_viewport)) {
+ return NAUTILUS_ART_IPOINT_ZERO;
+ }
+
+ gdk_window_get_position (GTK_VIEWPORT (nautilus_viewport)->bin_window,
+ &scroll_offset.x,
+ &scroll_offset.y);
- return GTK_WIDGET (viewport);
+ return scroll_offset;
}
diff --git a/libnautilus-extensions/nautilus-viewport.h b/libnautilus-extensions/nautilus-viewport.h
index 69a3e58b6..5374165c8 100644
--- a/libnautilus-extensions/nautilus-viewport.h
+++ b/libnautilus-extensions/nautilus-viewport.h
@@ -27,6 +27,7 @@
#include <gtk/gtkviewport.h>
#include <libgnome/gnome-defs.h>
+#include <libnautilus-extensions/nautilus-smooth-widget.h>
BEGIN_GNOME_DECLS
@@ -36,23 +37,31 @@ BEGIN_GNOME_DECLS
#define NAUTILUS_IS_VIEWPORT(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_VIEWPORT))
#define NAUTILUS_IS_VIEWPORT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_VIEWPORT))
-typedef struct _NautilusViewport NautilusViewport;
-typedef struct _NautilusViewportClass NautilusViewportClass;
+typedef struct NautilusViewport NautilusViewport;
+typedef struct NautilusViewportClass NautilusViewportClass;
+typedef struct NautilusViewportDetails NautilusViewportDetails;
-struct _NautilusViewport
+struct NautilusViewport
{
/* Superclass */
GtkViewport viewport;
+
+ /* Private things */
+ NautilusViewportDetails *details;
};
-struct _NautilusViewportClass
+struct NautilusViewportClass
{
GtkViewportClass parent_class;
+ NautilusSmoothWidgetSetIsSmooth set_is_smooth;
};
-GtkType nautilus_viewport_get_type (void);
-GtkWidget *nautilus_viewport_new (GtkAdjustment *hadjustment,
- GtkAdjustment *vadjustment);
+GtkType nautilus_viewport_get_type (void);
+GtkWidget * nautilus_viewport_new (GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment);
+void nautilus_viewport_set_is_smooth (NautilusViewport *nautilus_viewport,
+ gboolean is_smooth);
+NautilusArtIPoint nautilus_viewport_get_scroll_offset (const NautilusViewport *nautilus_viewport);
END_GNOME_DECLS
diff --git a/libnautilus-extensions/nautilus-wrap-table.c b/libnautilus-extensions/nautilus-wrap-table.c
index fb51a881f..8a2c62353 100644
--- a/libnautilus-extensions/nautilus-wrap-table.c
+++ b/libnautilus-extensions/nautilus-wrap-table.c
@@ -635,9 +635,10 @@ wrap_table_get_content_frame (const NautilusWrapTable *wrap_table)
wrap_table->details->x_spacing,
max_child_frame.x1);
num_rows = num_children / num_cols;
+ num_rows = MAX (num_rows, 1);
if ((num_children % num_rows) > 0) {
- num_rows++;
+ num_rows++;
}
content_frame.x1 = frame.x1;
@@ -681,11 +682,7 @@ wrap_table_get_scroll_offset (const NautilusWrapTable *wrap_table)
* parent here. Theres probably a better way to do this
*/
if (GTK_IS_VIEWPORT (parent)) {
- GtkViewport *viewport;
-
- viewport = GTK_VIEWPORT (parent);
-
- gdk_window_get_position (viewport->bin_window,
+ gdk_window_get_position (GTK_VIEWPORT (parent)->bin_window,
&scroll_offset.x,
&scroll_offset.y);
}
@@ -933,7 +930,57 @@ nautilus_wrap_table_set_homogeneous (NautilusWrapTable *wrap_table,
gboolean
nautilus_wrap_table_get_homogeneous (const NautilusWrapTable *wrap_table)
{
- g_return_val_if_fail (NAUTILUS_IS_WRAP_TABLE (wrap_table), 0);
+ g_return_val_if_fail (NAUTILUS_IS_WRAP_TABLE (wrap_table), FALSE);
return wrap_table->details->homogeneous;
}
+
+/**
+ * nautilus_wrap_table_reorder_child:
+ * @wrap_table: A NautilusWrapTable.
+ * @child: Child to reorder.
+ * @position: New position to put child at.
+ *
+ * Reorder the given chilren into the given position.
+ *
+ * Position is interpreted as follows:
+ *
+ * 0 - Place child at start of table.
+ * -1 - Place child at end of table.
+ * n - Place child at nth position. Count starts at 0.
+ */
+void
+nautilus_wrap_table_reorder_child (NautilusWrapTable *wrap_table,
+ GtkWidget *child,
+ int position)
+{
+ GList *node;
+ gboolean found_child = FALSE;
+
+ g_return_if_fail (NAUTILUS_IS_WRAP_TABLE (wrap_table));
+ g_return_if_fail (g_list_length (wrap_table->details->items) > 0);
+
+ if (position == -1) {
+ position = g_list_length (wrap_table->details->items) - 1;
+ }
+
+ g_return_if_fail (position >= 0);
+ g_return_if_fail ((guint) position < g_list_length (wrap_table->details->items));
+
+ for (node = wrap_table->details->items; node != NULL; node = node->next) {
+ GtkWidget *next_child;
+ next_child = node->data;
+
+ if (next_child == child) {
+ g_assert (found_child == FALSE);
+ found_child = TRUE;
+ }
+ }
+
+ g_return_if_fail (found_child);
+
+ wrap_table->details->items = g_list_remove (wrap_table->details->items, child);
+ wrap_table->details->items = g_list_insert (wrap_table->details->items, child, position);
+
+ gtk_widget_queue_resize (GTK_WIDGET (wrap_table));
+}
diff --git a/libnautilus-extensions/nautilus-wrap-table.h b/libnautilus-extensions/nautilus-wrap-table.h
index 0a18a6724..497132e22 100644
--- a/libnautilus-extensions/nautilus-wrap-table.h
+++ b/libnautilus-extensions/nautilus-wrap-table.h
@@ -82,6 +82,9 @@ NautilusJustification nautilus_wrap_table_get_y_justification (const Nauti
void nautilus_wrap_table_set_homogeneous (NautilusWrapTable *wrap_table,
gboolean homogeneous);
gboolean nautilus_wrap_table_get_homogeneous (const NautilusWrapTable *wrap_table);
+void nautilus_wrap_table_reorder_child (NautilusWrapTable *wrap_table,
+ GtkWidget *child,
+ int position);
END_GNOME_DECLS
diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am
index ade8ebef8..a8817c046 100644
--- a/libnautilus-private/Makefile.am
+++ b/libnautilus-private/Makefile.am
@@ -84,6 +84,7 @@ libnautilus_extensions_la_SOURCES = \
nautilus-ellipsizing-label.c \
nautilus-entry.c \
nautilus-enumeration.c \
+ nautilus-region.c \
nautilus-file-changes-queue.c \
nautilus-file-operations-progress.c \
nautilus-file-operations.c \
@@ -192,6 +193,7 @@ noinst_HEADERS = \
nautilus-ellipsizing-label.h \
nautilus-entry.h \
nautilus-enumeration.h \
+ nautilus-region.h \
nautilus-file-attributes.h \
nautilus-file-changes-queue.h \
nautilus-file-operations-progress.h \
diff --git a/libnautilus-private/nautilus-art-gtk-extensions.c b/libnautilus-private/nautilus-art-gtk-extensions.c
index 56ca5bc33..74ccb5878 100644
--- a/libnautilus-private/nautilus-art-gtk-extensions.c
+++ b/libnautilus-private/nautilus-art-gtk-extensions.c
@@ -262,3 +262,23 @@ nautilus_irect_gdk_window_clip_dirty_area_to_screen (const GdkWindow *gdk_window
return clipped;
}
+
+GdkRectangle
+nautilus_gdk_rectangle_assign_irect (const ArtIRect *irect)
+{
+ GdkRectangle gdk_rect;
+
+ gdk_rect.x = 0;
+ gdk_rect.y = 0;
+ gdk_rect.width = 0;
+ gdk_rect.height = 0;
+
+ g_return_val_if_fail (irect != NULL, gdk_rect);
+
+ gdk_rect.x = irect->x0;
+ gdk_rect.y = irect->y0;
+ gdk_rect.width = nautilus_art_irect_get_width (irect);
+ gdk_rect.height = nautilus_art_irect_get_height (irect);
+
+ return gdk_rect;
+}
diff --git a/libnautilus-private/nautilus-art-gtk-extensions.h b/libnautilus-private/nautilus-art-gtk-extensions.h
index e50350156..0bc2578a6 100644
--- a/libnautilus-private/nautilus-art-gtk-extensions.h
+++ b/libnautilus-private/nautilus-art-gtk-extensions.h
@@ -41,14 +41,15 @@
BEGIN_GNOME_DECLS
-ArtIRect nautilus_irect_assign_gdk_rectangle (const GdkRectangle *gdk_rectangle);
-ArtIRect nautilus_irect_screen_get_frame (void);
-ArtIRect nautilus_irect_gdk_window_get_bounds (const GdkWindow *gdk_window);
-ArtIRect nautilus_irect_gdk_window_get_screen_relative_bounds (const GdkWindow *gdk_window);
-ArtIRect nautilus_irect_gtk_widget_get_bounds (const GtkWidget *gtk_widget);
-ArtIRect nautilus_irect_gtk_widget_get_frame (const GtkWidget *gtk_widget);
-ArtIRect nautilus_irect_gdk_window_clip_dirty_area_to_screen (const GdkWindow *gdk_window,
- const ArtIRect *dirty_area);
+GdkRectangle nautilus_gdk_rectangle_assign_irect (const ArtIRect *irect);
+ArtIRect nautilus_irect_assign_gdk_rectangle (const GdkRectangle *gdk_rectangle);
+ArtIRect nautilus_irect_screen_get_frame (void);
+ArtIRect nautilus_irect_gdk_window_get_bounds (const GdkWindow *gdk_window);
+ArtIRect nautilus_irect_gdk_window_get_screen_relative_bounds (const GdkWindow *gdk_window);
+ArtIRect nautilus_irect_gtk_widget_get_bounds (const GtkWidget *gtk_widget);
+ArtIRect nautilus_irect_gtk_widget_get_frame (const GtkWidget *gtk_widget);
+ArtIRect nautilus_irect_gdk_window_clip_dirty_area_to_screen (const GdkWindow *gdk_window,
+ const ArtIRect *dirty_area);
END_GNOME_DECLS
diff --git a/libnautilus-private/nautilus-customization-data.c b/libnautilus-private/nautilus-customization-data.c
index d9a1c56c4..ce14234c2 100644
--- a/libnautilus-private/nautilus-customization-data.c
+++ b/libnautilus-private/nautilus-customization-data.c
@@ -46,8 +46,6 @@
#include "nautilus-gdk-extensions.h"
#include "nautilus-gtk-extensions.h"
#include "nautilus-xml-extensions.h"
-#include "nautilus-image.h"
-#include "nautilus-label.h"
#include "nautilus-string.h"
typedef enum {
@@ -155,15 +153,19 @@ nautilus_customization_data_new (const char *customization_name,
GnomeVFSResult
nautilus_customization_data_get_next_element_for_display (NautilusCustomizationData *data,
char **emblem_name,
- GtkWidget **pixmap_widget,
- GtkWidget **label)
+ GdkPixbuf **pixbuf_out,
+ char **label_out)
{
GnomeVFSFileInfo *current_file_info;
- char *image_file_name, *filtered_name, *truncated_name;
+ char *image_file_name, *filtered_name;
GdkPixbuf *pixbuf;
GdkPixbuf *orig_pixbuf;
-
+
+ g_return_val_if_fail (data != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (emblem_name != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (pixbuf_out != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+ g_return_val_if_fail (label_out != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
if (data->current_file_list == NULL) {
if (data->reading_mode == READ_PUBLIC_CUSTOMIZATIONS) {
@@ -174,14 +176,14 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
data->current_file_list = data->private_file_list;
return nautilus_customization_data_get_next_element_for_display (data,
emblem_name,
- pixmap_widget,
- label);
+ pixbuf_out,
+ label_out);
}
else {
- return GNOME_VFS_ERROR_EOF;
+ return GNOME_VFS_ERROR_EOF;
}
}
-
+
current_file_info = data->current_file_list->data;
data->current_file_list = data->current_file_list->next;
@@ -193,14 +195,14 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
return nautilus_customization_data_get_next_element_for_display (data,
emblem_name,
- pixmap_widget,
- label);
+ pixbuf_out,
+ label_out);
}
image_file_name = get_file_path_for_mode (data,
current_file_info->name);
- orig_pixbuf = gdk_pixbuf_new_from_file(image_file_name);
- g_free(image_file_name);
+ orig_pixbuf = gdk_pixbuf_new_from_file (image_file_name);
+ g_free (image_file_name);
*emblem_name = g_strdup (current_file_info->name);
@@ -213,9 +215,7 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
gdk_pixbuf_unref (orig_pixbuf);
}
- *pixmap_widget = nautilus_image_new (NULL);
- nautilus_image_set_pixbuf (NAUTILUS_IMAGE (*pixmap_widget), pixbuf);
- gdk_pixbuf_unref (pixbuf);
+ *pixbuf_out = pixbuf;
filtered_name = format_name_for_display (data, current_file_info->name);
/* If the data is for a menu,
@@ -223,12 +223,10 @@ nautilus_customization_data_get_next_element_for_display (NautilusCustomizationD
label because anti-aliased text doesn't look right
in menus */
if (data->data_is_for_a_menu) {
- truncated_name = nautilus_truncate_text_for_menu_item (filtered_name);
- *label = gtk_label_new (truncated_name);
- g_free (truncated_name);
+ *label_out = nautilus_truncate_text_for_menu_item (filtered_name);
}
else {
- *label = nautilus_label_new (filtered_name);
+ *label_out = g_strdup (filtered_name);
}
g_free (filtered_name);
diff --git a/libnautilus-private/nautilus-customization-data.h b/libnautilus-private/nautilus-customization-data.h
index 5f797a347..8cb39bc08 100644
--- a/libnautilus-private/nautilus-customization-data.h
+++ b/libnautilus-private/nautilus-customization-data.h
@@ -53,12 +53,8 @@ NautilusCustomizationData* nautilus_customization_data_new
*/
GnomeVFSResult nautilus_customization_data_get_next_element_for_display (NautilusCustomizationData *data,
char **emblem_name,
- GtkWidget **pixmap_widget,
-
-
- GtkWidget **label_widget);
-
-
+ GdkPixbuf **pixbuf_out,
+ char **label);
gboolean nautilus_customization_data_private_data_was_displayed (NautilusCustomizationData *data);
void nautilus_customization_data_destroy (NautilusCustomizationData *data);
diff --git a/libnautilus-private/nautilus-image-table.c b/libnautilus-private/nautilus-image-table.c
index 0c4f0cdd7..f9ec5b990 100644
--- a/libnautilus-private/nautilus-image-table.c
+++ b/libnautilus-private/nautilus-image-table.c
@@ -30,6 +30,8 @@
#include "nautilus-gtk-extensions.h"
#include "nautilus-art-extensions.h"
#include "nautilus-art-gtk-extensions.h"
+#include "nautilus-region.h"
+#include "nautilus-debug-drawing.h"
#include <gtk/gtkmain.h>
@@ -51,6 +53,9 @@ struct NautilusImageTableDetails
guint button_release_connection_id;
GtkWidget *child_under_pointer;
GtkWidget *child_being_pressed;
+ GdkGC *clear_gc;
+ guint32 smooth_background_color;
+ gboolean is_smooth;
};
/* Signals */
@@ -61,6 +66,7 @@ typedef enum
CHILD_PRESSED,
CHILD_RELEASED,
CHILD_CLICKED,
+ SET_IS_SMOOTH,
LAST_SIGNAL
} ImageTableSignals;
@@ -68,39 +74,54 @@ typedef enum
static guint image_table_signals[LAST_SIGNAL] = { 0 };
/* GtkObjectClass methods */
-static void nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_class);
-static void nautilus_image_table_initialize (NautilusImageTable *image);
-static void nautilus_image_table_destroy (GtkObject *object);
+static void nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_class);
+static void nautilus_image_table_initialize (NautilusImageTable *image);
+static void nautilus_image_table_destroy (GtkObject *object);
/* GtkWidgetClass methods */
-static void nautilus_image_table_realize (GtkWidget *widget);
-static void nautilus_image_table_unrealize (GtkWidget *widget);
+static int nautilus_image_table_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void nautilus_image_table_realize (GtkWidget *widget);
+static void nautilus_image_table_unrealize (GtkWidget *widget);
/* GtkContainerClass methods */
-static void nautilus_image_table_add (GtkContainer *container,
- GtkWidget *widget);
-static void nautilus_image_table_remove (GtkContainer *container,
- GtkWidget *widget);
-static GtkType nautilus_image_table_child_type (GtkContainer *container);
+static void nautilus_image_table_add (GtkContainer *container,
+ GtkWidget *widget);
+static void nautilus_image_table_remove (GtkContainer *container,
+ GtkWidget *widget);
+static GtkType nautilus_image_table_child_type (GtkContainer *container);
/* Private NautilusImageTable methods */
+static void image_table_clear_dirty_areas (NautilusImageTable *image_table);
+static GdkGC * image_table_peek_clear_gc (NautilusImageTable *image_table);
+static void image_table_emit_signal (NautilusImageTable *image_table,
+ GtkWidget *child,
+ guint signal_index,
+ int x,
+ int y,
+ int button,
+ guint state);
/* Ancestor callbacks */
-static int ancestor_enter_notify_event (GtkWidget *widget,
- GdkEventCrossing *event,
- gpointer event_data);
-static int ancestor_leave_notify_event (GtkWidget *widget,
- GdkEventCrossing *event,
- gpointer event_data);
-static int ancestor_motion_notify_event (GtkWidget *widget,
- GdkEventMotion *event,
- gpointer event_data);
-static int ancestor_button_press_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer event_data);
-static int ancestor_button_release_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer event_data);
+static int ancestor_enter_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer event_data);
+static int ancestor_leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ gpointer event_data);
+static int ancestor_motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer event_data);
+static int ancestor_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer event_data);
+static int ancestor_button_release_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer event_data);
+
+/* NautilusImageTable signals */
+static void nautilus_image_table_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth);
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusImageTable, nautilus_image_table, NAUTILUS_TYPE_WRAP_TABLE)
@@ -116,6 +137,7 @@ nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_clas
object_class->destroy = nautilus_image_table_destroy;
/* GtkWidgetClass */
+ widget_class->expose_event = nautilus_image_table_expose_event;
widget_class->realize = nautilus_image_table_realize;
widget_class->unrealize = nautilus_image_table_unrealize;
@@ -123,7 +145,10 @@ nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_clas
container_class->add = nautilus_image_table_add;
container_class->remove = nautilus_image_table_remove;
container_class->child_type = nautilus_image_table_child_type;
-
+
+ /* NautilusImageTableClass */
+ image_table_class->set_is_smooth = nautilus_image_table_set_is_smooth_signal;
+
/* Signals */
image_table_signals[CHILD_ENTER] = gtk_signal_new ("child_enter",
GTK_RUN_LAST,
@@ -171,7 +196,19 @@ nautilus_image_table_initialize_class (NautilusImageTableClass *image_table_clas
GTK_TYPE_POINTER,
GTK_TYPE_POINTER);
+ image_table_signals[SET_IS_SMOOTH] = gtk_signal_new ("set_is_smooth",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusImageTableClass, set_is_smooth),
+ gtk_marshal_NONE__BOOL,
+ GTK_TYPE_NONE,
+ 1,
+ GTK_TYPE_BOOL);
+
gtk_object_class_add_signals (object_class, image_table_signals, LAST_SIGNAL);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_IMAGE_TABLE);
}
void
@@ -180,6 +217,9 @@ nautilus_image_table_initialize (NautilusImageTable *image_table)
GTK_WIDGET_SET_FLAGS (image_table, GTK_NO_WINDOW);
image_table->details = g_new0 (NautilusImageTableDetails, 1);
+ image_table->details->smooth_background_color = NAUTILUS_RGB_COLOR_WHITE;
+
+ nautilus_smooth_widget_register (GTK_WIDGET (image_table));
}
/* GtkObjectClass methods */
@@ -199,6 +239,28 @@ nautilus_image_table_destroy (GtkObject *object)
}
/* GtkWidgetClass methods */
+static int
+nautilus_image_table_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ NautilusImageTable *image_table;
+
+ g_return_val_if_fail (NAUTILUS_IS_WRAP_TABLE (widget), TRUE);
+ g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), TRUE);
+ g_return_val_if_fail (event != NULL, TRUE);
+
+ image_table = NAUTILUS_IMAGE_TABLE (widget);
+
+ /* In smooth mode we clear dirty areas, since our background wont be
+ * force clear and thus avoid flicker.
+ */
+ if (image_table->details->is_smooth) {
+ image_table_clear_dirty_areas (image_table);
+ }
+
+ return NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, expose_event, (widget, event));
+}
+
static void
nautilus_image_table_realize (GtkWidget *widget)
{
@@ -217,6 +279,7 @@ nautilus_image_table_realize (GtkWidget *widget)
gtk_widget_add_events (image_table->details->windowed_ancestor,
GDK_BUTTON_PRESS_MASK
| GDK_BUTTON_RELEASE_MASK
+ | GDK_BUTTON_MOTION_MASK
| GDK_ENTER_NOTIFY_MASK
| GDK_LEAVE_NOTIFY_MASK
| GDK_POINTER_MOTION_MASK);
@@ -283,6 +346,11 @@ nautilus_image_table_unrealize (GtkWidget *widget)
image_table->details->button_press_connection_id = 0;
image_table->details->button_release_connection_id = 0;
+ if (image_table->details->clear_gc != NULL) {
+ gdk_gc_unref (image_table->details->clear_gc);
+ image_table->details->clear_gc = NULL;
+ }
+
/* Chain unrealize */
NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, unrealize, (widget));
}
@@ -331,7 +399,125 @@ nautilus_image_table_child_type (GtkContainer *container)
return NAUTILUS_TYPE_LABELED_IMAGE;
}
+/* NautilusImageTable signals */
+static void
+nautilus_image_table_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (widget));
+
+ nautilus_image_table_set_is_smooth (NAUTILUS_IMAGE_TABLE (widget), is_smooth);
+}
+
/* Private NautilusImageTable methods */
+
+/* For each of the image table children, subtract their content from a region */
+static void
+image_table_foreach_child_subtract_content (GtkWidget *child,
+ gpointer callback_data)
+{
+ NautilusRegion *region;
+ ArtIRect label_bounds;
+ ArtIRect image_bounds;
+
+ g_return_if_fail (NAUTILUS_IS_LABELED_IMAGE (child));
+ g_return_if_fail (callback_data != NULL);
+
+ if (!GTK_WIDGET_VISIBLE (child)) {
+ return;
+ }
+
+ region = callback_data;
+
+ image_bounds = nautilus_labeled_image_get_image_bounds (NAUTILUS_LABELED_IMAGE (child));
+ if (!art_irect_empty (&image_bounds)) {
+ nautilus_region_subtract_rectangle (region, &image_bounds);
+ }
+
+ label_bounds = nautilus_labeled_image_get_label_bounds (NAUTILUS_LABELED_IMAGE (child));
+ if (!art_irect_empty (&label_bounds)) {
+ nautilus_region_subtract_rectangle (region, &label_bounds);
+ }
+}
+
+/* Clear the dirty areas around the children's content */
+static void
+image_table_clear_dirty_areas (NautilusImageTable *image_table)
+{
+ GtkWidget *widget;
+ NautilusRegion *region;
+ ArtIRect bounds;
+ GdkGC *gc;
+
+ g_return_if_fail (NAUTILUS_IS_WRAP_TABLE (image_table));
+ g_return_if_fail (GTK_WIDGET_REALIZED (image_table));
+
+ widget = GTK_WIDGET (image_table);
+
+ bounds = nautilus_irect_gtk_widget_get_frame (widget->parent);
+ region = nautilus_region_new ();
+
+ nautilus_region_add_rectangle (region, &bounds);
+
+ gc = image_table_peek_clear_gc (image_table);
+
+ gtk_container_foreach (GTK_CONTAINER (image_table), image_table_foreach_child_subtract_content, region);
+
+ nautilus_region_set_gc_clip_region (region, gc);
+
+ gdk_draw_rectangle (widget->window,
+ gc,
+ TRUE,
+ bounds.x0,
+ bounds.y0,
+ bounds.x1 - bounds.x0,
+ bounds.y1 - bounds.y0);
+
+ nautilus_region_free (region);
+}
+
+static GdkGC *
+image_table_peek_clear_gc (NautilusImageTable *image_table)
+{
+ g_return_val_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table), NULL);
+
+ if (image_table->details->clear_gc == NULL) {
+ image_table->details->clear_gc = gdk_gc_new (GTK_WIDGET (image_table)->window);
+ gdk_gc_set_function (image_table->details->clear_gc, GDK_COPY);
+ }
+
+ gdk_rgb_gc_set_foreground (image_table->details->clear_gc, image_table->details->smooth_background_color);
+
+ return image_table->details->clear_gc;
+}
+
+static void
+image_table_emit_signal (NautilusImageTable *image_table,
+ GtkWidget *child,
+ guint signal_index,
+ int x,
+ int y,
+ int button,
+ guint state)
+{
+ NautilusImageTableEvent event;
+
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (signal_index >= 0);
+ g_return_if_fail (signal_index < LAST_SIGNAL);
+
+ event.x = x;
+ event.y = y;
+ event.button = button;
+ event.state = state;
+
+ gtk_signal_emit (GTK_OBJECT (image_table),
+ image_table_signals[signal_index],
+ child,
+ &event);
+}
+
static void
image_table_handle_motion (NautilusImageTable *image_table,
int x,
@@ -366,17 +552,23 @@ image_table_handle_motion (NautilusImageTable *image_table,
}
if (leave_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_LEAVE],
- leave_emit_child,
- event);
+ image_table_emit_signal (image_table,
+ leave_emit_child,
+ CHILD_LEAVE,
+ x,
+ y,
+ 0,
+ 0);
}
if (enter_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_ENTER],
- enter_emit_child,
- event);
+ image_table_emit_signal (image_table,
+ enter_emit_child,
+ CHILD_ENTER,
+ x,
+ y,
+ 0,
+ 0);
}
}
@@ -447,17 +639,18 @@ ancestor_button_press_event (GtkWidget *widget,
image_table = NAUTILUS_IMAGE_TABLE (event_data);
- gtk_grab_add (widget);
-
child = nautilus_wrap_table_find_child_at_event_point (NAUTILUS_WRAP_TABLE (image_table), event->x, event->y);
if (child != NULL) {
if (child == image_table->details->child_under_pointer) {
image_table->details->child_being_pressed = child;
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_PRESSED],
- child,
- event);
+ image_table_emit_signal (image_table,
+ child,
+ CHILD_PRESSED,
+ event->x,
+ event->y,
+ event->button,
+ event->state);
}
}
@@ -480,8 +673,6 @@ ancestor_button_release_event (GtkWidget *widget,
image_table = NAUTILUS_IMAGE_TABLE (event_data);
- gtk_grab_remove (widget);
-
child = nautilus_wrap_table_find_child_at_event_point (NAUTILUS_WRAP_TABLE (image_table), event->x, event->y);
if (image_table->details->child_being_pressed != NULL) {
@@ -497,17 +688,24 @@ ancestor_button_release_event (GtkWidget *widget,
image_table->details->child_being_pressed = NULL;
if (released_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_RELEASED],
- released_emit_child,
- event);
+ image_table_emit_signal (image_table,
+ released_emit_child,
+ CHILD_RELEASED,
+ event->x,
+ event->y,
+ event->button,
+ event->state);
}
if (clicked_emit_child != NULL) {
- gtk_signal_emit (GTK_OBJECT (image_table),
- image_table_signals[CHILD_CLICKED],
- clicked_emit_child,
- event);
+
+ image_table_emit_signal (image_table,
+ clicked_emit_child,
+ CHILD_CLICKED,
+ event->x,
+ event->y,
+ event->button,
+ event->state);
}
return FALSE;
@@ -527,3 +725,41 @@ nautilus_image_table_new (gboolean homogeneous)
return GTK_WIDGET (image_table);
}
+
+/**
+ * nautilus_image_table_set_is_smooth:
+ * @image_table: A NautilusImageTable.
+ * @is_smooth: Boolean value indicating whether the image table is smooth.
+ *
+ */
+void
+nautilus_image_table_set_is_smooth (NautilusImageTable *image_table,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+
+ if (image_table->details->is_smooth == is_smooth) {
+ return;
+ }
+
+ image_table->details->is_smooth = is_smooth;
+}
+
+/**
+ * nautilus_image_table_set_smooth_background_color:
+ * @image_table: A NautilusImageTable.
+ * @smooth_background_color: The color to use for background in smooth mode.
+ *
+ */
+void
+nautilus_image_table_set_smooth_background_color (NautilusImageTable *image_table,
+ guint32 smooth_background_color)
+{
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+
+ if (image_table->details->smooth_background_color == smooth_background_color) {
+ return;
+ }
+
+ image_table->details->smooth_background_color = smooth_background_color;
+}
diff --git a/libnautilus-private/nautilus-image-table.h b/libnautilus-private/nautilus-image-table.h
index 9397f7b89..9ae424702 100644
--- a/libnautilus-private/nautilus-image-table.h
+++ b/libnautilus-private/nautilus-image-table.h
@@ -27,6 +27,7 @@
#include <libnautilus-extensions/nautilus-wrap-table.h>
#include <libnautilus-extensions/nautilus-labeled-image.h>
+#include <libnautilus-extensions/nautilus-smooth-widget.h>
BEGIN_GNOME_DECLS
@@ -52,6 +53,7 @@ struct NautilusImageTable
struct NautilusImageTableClass
{
NautilusWrapTableClass parent_class;
+ NautilusSmoothWidgetSetIsSmooth set_is_smooth;
};
typedef struct
@@ -63,8 +65,12 @@ typedef struct
} NautilusImageTableEvent;
/* Public GtkImageTable methods */
-GtkType nautilus_image_table_get_type (void);
-GtkWidget *nautilus_image_table_new (gboolean homogeneous);
+GtkType nautilus_image_table_get_type (void);
+GtkWidget *nautilus_image_table_new (gboolean homogeneous);
+void nautilus_image_table_set_smooth_background_color (NautilusImageTable *image_table,
+ guint32 smooth_background_color);
+void nautilus_image_table_set_is_smooth (NautilusImageTable *image_table,
+ gboolean is_smooth);
END_GNOME_DECLS
diff --git a/libnautilus-private/nautilus-image.c b/libnautilus-private/nautilus-image.c
index 746046a36..173b1d340 100644
--- a/libnautilus-private/nautilus-image.c
+++ b/libnautilus-private/nautilus-image.c
@@ -198,6 +198,9 @@ nautilus_image_initialize_class (NautilusImageClass *image_class)
/* Make this class inherit the same kind of theme stuff as GtkPixmap */
nautilus_gtk_class_name_make_like_existing_type ("NautilusImage", GTK_TYPE_PIXMAP);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_IMAGE);
}
void
diff --git a/libnautilus-private/nautilus-label.c b/libnautilus-private/nautilus-label.c
index 93de1d77e..bb19e61fc 100644
--- a/libnautilus-private/nautilus-label.c
+++ b/libnautilus-private/nautilus-label.c
@@ -145,8 +145,8 @@ static void nautilus_label_get_arg (GtkObject
/* GtkWidgetClass methods */
static void nautilus_label_size_request (GtkWidget *widget,
GtkRequisition *requisition);
-static void nautilus_label_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
+static void nautilus_label_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
static int nautilus_label_expose_event (GtkWidget *widget,
GdkEventExpose *event);
@@ -293,6 +293,9 @@ nautilus_label_initialize_class (NautilusLabelClass *label_class)
/* Make this class inherit the same kind of theme stuff as GtkLabel */
nautilus_gtk_class_name_make_like_existing_type ("NautilusLabel", GTK_TYPE_LABEL);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_LABEL);
}
void
diff --git a/libnautilus-private/nautilus-labeled-image.c b/libnautilus-private/nautilus-labeled-image.c
index 47f3a768a..c53d59e4d 100644
--- a/libnautilus-private/nautilus-labeled-image.c
+++ b/libnautilus-private/nautilus-labeled-image.c
@@ -110,8 +110,6 @@ static void nautilus_labeled_image_forall (GtkContainer
/* Private NautilusLabeledImage methods */
static ArtIRect labeled_image_get_image_frame (const NautilusLabeledImage *labeled_image);
static ArtIRect labeled_image_get_label_frame (const NautilusLabeledImage *labeled_image);
-static ArtIRect labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image);
-static ArtIRect labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image);
static void labeled_image_ensure_label (NautilusLabeledImage *labeled_image);
static void labeled_image_ensure_image (NautilusLabeledImage *labeled_image);
static ArtIRect labeled_image_get_content_bounds (const NautilusLabeledImage *labeled_image);
@@ -389,7 +387,7 @@ nautilus_labeled_image_size_allocate (GtkWidget *widget,
widget->allocation = *allocation;
- label_bounds = labeled_image_get_label_bounds (labeled_image);
+ label_bounds = nautilus_labeled_image_get_label_bounds (labeled_image);
if (!art_irect_empty (&label_bounds)) {
GtkAllocation label_allocation;
@@ -401,7 +399,7 @@ nautilus_labeled_image_size_allocate (GtkWidget *widget,
gtk_widget_size_allocate (labeled_image->details->label, &label_allocation);
}
- image_bounds = labeled_image_get_image_bounds (labeled_image);
+ image_bounds = nautilus_labeled_image_get_image_bounds (labeled_image);
if (!art_irect_empty (&image_bounds)) {
GtkAllocation image_allocation;
@@ -584,6 +582,7 @@ nautilus_labeled_image_forall (GtkContainer *container,
}
}
+/* Private NautilusLabeledImage methods */
static ArtIRect
labeled_image_get_image_frame (const NautilusLabeledImage *labeled_image)
{
@@ -684,8 +683,8 @@ labeled_image_get_image_bounds_fill (const NautilusLabeledImage *labeled_image)
return image_bounds;
}
-static ArtIRect
-labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image)
+ArtIRect
+nautilus_labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image)
{
ArtIRect image_frame;
ArtIRect image_bounds;
@@ -808,8 +807,8 @@ labeled_image_get_label_bounds_fill (const NautilusLabeledImage *labeled_image)
return label_bounds;
}
-static ArtIRect
-labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image)
+ArtIRect
+nautilus_labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image)
{
ArtIRect label_bounds;
ArtIRect label_frame;
diff --git a/libnautilus-private/nautilus-labeled-image.h b/libnautilus-private/nautilus-labeled-image.h
index 9be437b68..13d91f0d2 100644
--- a/libnautilus-private/nautilus-labeled-image.h
+++ b/libnautilus-private/nautilus-labeled-image.h
@@ -160,6 +160,8 @@ void nautilus_labeled_image_set_text_color (Nautilu
guint32 text_color);
void nautilus_labeled_image_set_label_never_smooth (NautilusLabeledImage *labeled_image,
gboolean never_smooth);
+ArtIRect nautilus_labeled_image_get_image_bounds (const NautilusLabeledImage *labeled_image);
+ArtIRect nautilus_labeled_image_get_label_bounds (const NautilusLabeledImage *labeled_image);
END_GNOME_DECLS
diff --git a/libnautilus-private/nautilus-region.c b/libnautilus-private/nautilus-region.c
new file mode 100644
index 000000000..2ab4da988
--- /dev/null
+++ b/libnautilus-private/nautilus-region.c
@@ -0,0 +1,123 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-region.c: A simple wrapper on GdkRegion with rectangle operations.
+
+ 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: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#include <config.h>
+
+#include "nautilus-region.h"
+
+#include "nautilus-glib-extensions.h"
+#include "nautilus-art-gtk-extensions.h"
+
+struct NautilusRegion
+{
+ GdkRegion *gdk_region;
+};
+
+NautilusRegion *
+nautilus_region_new (void)
+{
+ NautilusRegion *region;
+
+ region = g_new0 (NautilusRegion, 1);
+
+ region->gdk_region = gdk_region_new ();
+
+ return region;
+}
+
+void
+nautilus_region_free (NautilusRegion *region)
+{
+ if (region == NULL) {
+ return;
+ }
+
+ g_assert (region->gdk_region != NULL);
+ gdk_region_destroy (region->gdk_region);
+
+ g_free (region);
+}
+
+static GdkRegion *
+gdk_region_new_from_irect (const ArtIRect *art_rect)
+{
+ GdkRegion *region;
+ GdkRegion *empty_region;
+ GdkRectangle gdk_rect;
+
+ g_return_val_if_fail (art_rect != NULL, NULL);
+
+ gdk_rect = nautilus_gdk_rectangle_assign_irect (art_rect);
+ empty_region = gdk_region_new ();
+ region = gdk_region_union_with_rect (empty_region, &gdk_rect);
+ gdk_region_destroy (empty_region);
+
+ return region;
+}
+
+void
+nautilus_region_add_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle)
+{
+ GdkRegion *add_region;
+ GdkRegion *new_region;
+
+ g_return_if_fail (region != NULL);
+ g_return_if_fail (rectangle != NULL);
+ g_return_if_fail (!art_irect_empty (rectangle));
+
+ add_region = gdk_region_new_from_irect (rectangle);
+ new_region = gdk_regions_union (region->gdk_region, add_region);
+ gdk_region_destroy (add_region);
+ gdk_region_destroy (region->gdk_region);
+ region->gdk_region = new_region;
+}
+
+void
+nautilus_region_subtract_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle)
+{
+ GdkRegion *subtract_region;
+ GdkRegion *new_region;
+
+ g_return_if_fail (region != NULL);
+ g_return_if_fail (rectangle != NULL);
+ g_return_if_fail (!art_irect_empty (rectangle));
+
+ subtract_region = gdk_region_new_from_irect (rectangle);
+ new_region = gdk_regions_subtract (region->gdk_region, subtract_region);
+ gdk_region_destroy (subtract_region);
+ gdk_region_destroy (region->gdk_region);
+ region->gdk_region = new_region;
+}
+
+void
+nautilus_region_set_gc_clip_region (const NautilusRegion *region,
+ GdkGC *gc)
+{
+ g_return_if_fail (region != NULL);
+ g_return_if_fail (gc != NULL);
+
+ gdk_gc_set_clip_region (gc, region->gdk_region);
+}
diff --git a/libnautilus-private/nautilus-region.h b/libnautilus-private/nautilus-region.h
new file mode 100644
index 000000000..1727469ad
--- /dev/null
+++ b/libnautilus-private/nautilus-region.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-region.h: A simple wrapper on GdkRegion with rectangle operations.
+
+ 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: Ramiro Estrugo <ramiro@eazel.com>
+*/
+
+#ifndef NAUTILUS_REGION_H
+#define NAUTILUS_REGION_H
+
+#include <libgnome/gnome-defs.h>
+#include <libart_lgpl/art_rect.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+
+/* Opaque NautilusRegion declaration. */
+typedef struct NautilusRegion NautilusRegion;
+
+NautilusRegion *nautilus_region_new (void);
+void nautilus_region_free (NautilusRegion *region);
+void nautilus_region_add_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle);
+void nautilus_region_subtract_rectangle (NautilusRegion *region,
+ const ArtIRect *rectangle);
+void nautilus_region_set_gc_clip_region (const NautilusRegion *region,
+ GdkGC *gc);
+
+#endif /* NAUTILUS_REGION_H */
+
diff --git a/libnautilus-private/nautilus-smooth-widget.c b/libnautilus-private/nautilus-smooth-widget.c
index 3b144263e..28b7ba72a 100644
--- a/libnautilus-private/nautilus-smooth-widget.c
+++ b/libnautilus-private/nautilus-smooth-widget.c
@@ -88,29 +88,42 @@ static void smooth_widget_paint_tile_and_content_transparent (GtkWi
*/
static GList *smooth_widget_list = NULL;
-
-/* We dont want to have any knowledge of NautilusImage and NautilusLabel
- * in this file. All the smooth widget operations herein should work on
- * either one without special casing. However, since NautilusImage and
- * NautilusLabel are subclassed from different super types, we cant make
- * cast checks for a common superclass. Thus the hack below of.
- *
- * We dont include the headers for NautilusImage and NautilusLabel instead
- * because we dont want special cased turds for each one to appear
- * in this file.
- *
- * Another assumption we make is that smooth widgets are subclasses from
- * GtkMisc.
+/* We maintain a global list of types that can be smooth widgets.
+ * We do this mostly for type safety - to make sure smooth operations only
+ * happen on smooth widgets.
*/
-extern GtkType nautilus_image_get_type (void);
-extern GtkType nautilus_label_get_type (void);
+static GList *smooth_widget_type_list = NULL;
+
+static void
+smooth_widget_type_list_free (void)
+{
+ g_list_free (smooth_widget_type_list);
+ smooth_widget_type_list = NULL;
+}
+
+static void
+smooth_widget_list_free (void)
+{
+ g_list_free (smooth_widget_list);
+ smooth_widget_list = NULL;
+}
static gboolean
widget_is_smooth (const GtkWidget *widget)
{
- return ((GTK_CHECK_TYPE ((widget), nautilus_image_get_type ())
- || GTK_CHECK_TYPE ((widget), nautilus_label_get_type ()))
- && GTK_IS_MISC (widget));
+ GList *node;
+
+ for (node = smooth_widget_type_list; node ; node = node->next) {
+ GtkType type;
+
+ type = GPOINTER_TO_INT (node->data);
+
+ if (GTK_CHECK_TYPE ((widget), type)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
}
static void
@@ -166,6 +179,10 @@ nautilus_smooth_widget_register (GtkWidget *widget)
smooth_widget_set_is_smooth (widget, preferences_get_is_smooth ());
+ if (smooth_widget_list == NULL) {
+ g_atexit (smooth_widget_list_free);
+ }
+
smooth_widget_list = g_list_prepend (smooth_widget_list, widget);
/* Keep track of the widget's destruction so we can purge it */
@@ -976,3 +993,14 @@ nautilus_smooth_widget_get_preferred_frame (const GtkWidget *widget,
return preferred_frame;
}
+
+void
+nautilus_smooth_widget_register_type (GtkType type)
+{
+ if (smooth_widget_type_list == NULL) {
+ g_atexit (smooth_widget_type_list_free);
+ }
+
+ smooth_widget_type_list = g_list_append (smooth_widget_type_list, GINT_TO_POINTER (type));
+}
+
diff --git a/libnautilus-private/nautilus-smooth-widget.h b/libnautilus-private/nautilus-smooth-widget.h
index a1119b695..007f8769c 100644
--- a/libnautilus-private/nautilus-smooth-widget.h
+++ b/libnautilus-private/nautilus-smooth-widget.h
@@ -110,6 +110,7 @@ ArtIRect nautilus_smooth_widget_get_preferred_frame (const GtkWidget
const ArtIRect *tile_frame,
int tile_width,
int tile_height);
+void nautilus_smooth_widget_register_type (GtkType type);
END_GNOME_DECLS
diff --git a/libnautilus-private/nautilus-viewport.c b/libnautilus-private/nautilus-viewport.c
index 898bab8c0..03c52ba5f 100644
--- a/libnautilus-private/nautilus-viewport.c
+++ b/libnautilus-private/nautilus-viewport.c
@@ -28,105 +28,247 @@
#include "nautilus-gtk-macros.h"
+#include <gtk/gtksignal.h>
+
+/* Detail member struct */
+struct NautilusViewportDetails
+{
+ gboolean is_smooth;
+};
+
/* GtkObjectClass methods */
-static void nautilus_viewport_initialize_class (NautilusViewportClass *viewport_class);
-static void nautilus_viewport_initialize (NautilusViewport *viewport);
-static void nautilus_viewport_draw (GtkWidget *widget,
- GdkRectangle *area);
+static void nautilus_viewport_initialize_class (NautilusViewportClass *viewport_class);
+static void nautilus_viewport_initialize (NautilusViewport *viewport);
+static void nautilus_viewport_destroy (GtkObject *object);
+
+/* GtkWidgetClass methods */
+static void nautilus_viewport_realize (GtkWidget *widget);
+static void nautilus_viewport_draw (GtkWidget *widget,
+ GdkRectangle *area);
+static gint nautilus_viewport_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void nautilus_viewport_paint (GtkWidget *widget,
+ GdkRectangle *area);
+
+/* NautilusViewport signals */
+static void nautilus_viewport_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth);
+
+/* Signals */
+typedef enum
+{
+ SET_IS_SMOOTH,
+ LAST_SIGNAL
+} NautilusViewportSignal;
-static void nautilus_viewport_paint (GtkWidget *widget,
- GdkRectangle *area);
+/* Signals */
+static guint nautilus_viewport_signals[LAST_SIGNAL] = { 0 };
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusViewport, nautilus_viewport, GTK_TYPE_VIEWPORT)
-/* Class init methods */
+/* GtkObjectClass methods */
static void
-nautilus_viewport_initialize_class (NautilusViewportClass *viewport_class)
+nautilus_viewport_initialize_class (NautilusViewportClass *nautilus_viewport_class)
{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (viewport_class);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (nautilus_viewport_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (nautilus_viewport_class);
+
+ /* GtkObjectClass */
+ object_class->destroy = nautilus_viewport_destroy;
/* GtkWidgetClass */
+ widget_class->realize = nautilus_viewport_realize;
+ widget_class->expose_event = nautilus_viewport_expose_event;
widget_class->draw = nautilus_viewport_draw;
+
+ /* NautilusViewportClass */
+ nautilus_viewport_class->set_is_smooth = nautilus_viewport_set_is_smooth_signal;
+
+ nautilus_viewport_signals[SET_IS_SMOOTH] =
+ gtk_signal_new ("set_is_smooth",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusViewportClass, set_is_smooth),
+ gtk_marshal_NONE__BOOL,
+ GTK_TYPE_NONE,
+ 1,
+ GTK_TYPE_BOOL);
+
+ gtk_object_class_add_signals (object_class, nautilus_viewport_signals, LAST_SIGNAL);
+
+ /* Let the smooth widget machinery know that our class can be smooth */
+ nautilus_smooth_widget_register_type (NAUTILUS_TYPE_VIEWPORT);
+}
+
+void
+nautilus_viewport_initialize (NautilusViewport *nautilus_viewport)
+{
+ nautilus_viewport->details = g_new0 (NautilusViewportDetails, 1);
+
+ nautilus_smooth_widget_register (GTK_WIDGET (nautilus_viewport));
}
void
-nautilus_viewport_initialize (NautilusViewport *viewport)
+nautilus_viewport_destroy (GtkObject *object)
{
- /* noop */
+ NautilusViewport *viewport;
+
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (object));
+
+ viewport = NAUTILUS_VIEWPORT (object);
+
+ g_free (viewport->details);
+
+ /* Chain destroy */
+ NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
}
+/* GtkWidgetClass methods */
static void
nautilus_viewport_draw (GtkWidget *widget,
GdkRectangle *area)
{
+ NautilusViewport *nautilus_viewport;
GtkViewport *viewport;
GtkBin *bin;
GdkRectangle tmp_area;
GdkRectangle child_area;
gint border_width;
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_VIEWPORT (widget));
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (widget));
g_return_if_fail (area != NULL);
- if (GTK_WIDGET_DRAWABLE (widget)) {
- viewport = GTK_VIEWPORT (widget);
- bin = GTK_BIN (widget);
-
- border_width = GTK_CONTAINER (widget)->border_width;
-
- tmp_area = *area;
- tmp_area.x -= border_width;
- tmp_area.y -= border_width;
-
- nautilus_viewport_paint (widget, &tmp_area);
-
- tmp_area.x += viewport->hadjustment->value - widget->style->klass->xthickness;
- tmp_area.y += viewport->vadjustment->value - widget->style->klass->ythickness;
-
- /* The gtk_viewport_draw() version does not adjust the width
- * and height of the tmp_area for the class x/y thickness. This
- * causes some drawing to be clipped on the bottom. This is a bug
- * in GTK+.
- */
-
- /* FIXME bugzilla.eazel.com xxxx:
- * Remove this widget once the fix makes it to GTK+.
- */
- tmp_area.width += 2 * widget->style->klass->xthickness;
- tmp_area.height += 2 * widget->style->klass->ythickness;
-
- gtk_paint_flat_box(widget->style, viewport->bin_window,
- GTK_STATE_NORMAL, GTK_SHADOW_NONE,
- &tmp_area, widget, "viewportbin",
- 0, 0, -1, -1);
+ if (!GTK_WIDGET_DRAWABLE (widget)) {
+ return;
+ }
+
+ nautilus_viewport = NAUTILUS_VIEWPORT (widget);
+ viewport = GTK_VIEWPORT (widget);
+ bin = GTK_BIN (widget);
+
+ border_width = GTK_CONTAINER (widget)->border_width;
+
+ tmp_area = *area;
+ tmp_area.x -= border_width;
+ tmp_area.y -= border_width;
+
+ nautilus_viewport_paint (widget, &tmp_area);
+
+ tmp_area.x += viewport->hadjustment->value - widget->style->klass->xthickness;
+ tmp_area.y += viewport->vadjustment->value - widget->style->klass->ythickness;
+
+ /* The gtk_viewport_draw() version does not adjust the width
+ * and height of the tmp_area for the class x/y thickness. This
+ * causes some drawing to be clipped on the bottom. This is a bug
+ * in GTK+.
+ */
+
+ /* FIXME bugzilla.eazel.com xxxx:
+ * Remove this widget once the fix makes it to GTK+.
+ */
+ tmp_area.width += 2 * widget->style->klass->xthickness;
+ tmp_area.height += 2 * widget->style->klass->ythickness;
+
+ if (!nautilus_viewport->details->is_smooth) {
+ gtk_paint_flat_box (widget->style, viewport->bin_window,
+ GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+ &tmp_area, widget, "viewportbin",
+ 0, 0, -1, -1);
+ }
+
+ if (bin->child) {
+ if (gtk_widget_intersect (bin->child, &tmp_area, &child_area)) {
+ gtk_widget_draw (bin->child, &child_area);
+ }
+ }
+}
+
+static gint
+nautilus_viewport_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ NautilusViewport *nautilus_viewport;
+ GtkViewport *viewport;
+ GtkBin *bin;
+
+ g_return_val_if_fail (NAUTILUS_IS_VIEWPORT (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ if (!GTK_WIDGET_DRAWABLE (widget)) {
+ return FALSE;
+ }
+
+ nautilus_viewport = NAUTILUS_VIEWPORT (widget);
+ viewport = GTK_VIEWPORT (widget);
+ bin = GTK_BIN (widget);
+
+ if (event->window == widget->window) {
+ nautilus_viewport_paint (widget, &event->area);
+ } else if (event->window == viewport->bin_window) {
+ GdkEventExpose child_event;
+
+ child_event = *event;
- if (bin->child) {
- if (gtk_widget_intersect (bin->child, &tmp_area, &child_area)) {
- gtk_widget_draw (bin->child, &child_area);
- }
+ if (!nautilus_viewport->details->is_smooth) {
+ gtk_paint_flat_box (widget->style, viewport->bin_window,
+ GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+ &event->area, widget, "viewportbin",
+ 0, 0, -1, -1);
}
+
+ if ((bin->child != NULL) &&
+ GTK_WIDGET_NO_WINDOW (bin->child) &&
+ gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+ gtk_widget_event (bin->child, (GdkEvent*) &child_event);
}
+
+ return FALSE;
+}
+
+static void
+nautilus_viewport_realize (GtkWidget *widget)
+{
+ NautilusViewport *nautilus_viewport;
+
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (widget));
+
+ nautilus_viewport = NAUTILUS_VIEWPORT (widget);
+
+ /* GtkViewport does the actual realization */
+ NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, realize, (widget));
+
+ nautilus_viewport_set_is_smooth (nautilus_viewport, nautilus_viewport->details->is_smooth);
}
static void
nautilus_viewport_paint (GtkWidget *widget,
GdkRectangle *area)
{
- GtkViewport *viewport;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_VIEWPORT (widget));
- g_return_if_fail (area != NULL);
+ GtkViewport *viewport;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_VIEWPORT (widget));
+ g_return_if_fail (area != NULL);
+
+ if (!GTK_WIDGET_DRAWABLE (widget)) {
+ return;
+ }
- if (GTK_WIDGET_DRAWABLE (widget))
- {
- viewport = GTK_VIEWPORT (widget);
+ viewport = GTK_VIEWPORT (widget);
+
+ gtk_draw_shadow (widget->style, widget->window,
+ GTK_STATE_NORMAL, viewport->shadow_type,
+ 0, 0, -1, -1);
+}
- gtk_draw_shadow (widget->style, widget->window,
- GTK_STATE_NORMAL, viewport->shadow_type,
- 0, 0, -1, -1);
- }
+/* NautilusViewport signals */
+static void
+nautilus_viewport_set_is_smooth_signal (GtkWidget *widget,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (widget));
+
+ nautilus_viewport_set_is_smooth (NAUTILUS_VIEWPORT (widget), is_smooth);
}
/* Public NautilusViewport methods */
@@ -134,12 +276,47 @@ GtkWidget*
nautilus_viewport_new (GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment)
{
- NautilusViewport *viewport;
+ NautilusViewport *nautilus_viewport;
- viewport = NAUTILUS_VIEWPORT (gtk_widget_new (nautilus_viewport_get_type (), NULL));
+ nautilus_viewport = NAUTILUS_VIEWPORT (gtk_widget_new (nautilus_viewport_get_type (), NULL));
- gtk_viewport_set_hadjustment (GTK_VIEWPORT (viewport), hadjustment);
- gtk_viewport_set_vadjustment (GTK_VIEWPORT (viewport), vadjustment);
+ gtk_viewport_set_hadjustment (GTK_VIEWPORT (nautilus_viewport), hadjustment);
+ gtk_viewport_set_vadjustment (GTK_VIEWPORT (nautilus_viewport), vadjustment);
+
+ return GTK_WIDGET (nautilus_viewport);
+}
+
+void
+nautilus_viewport_set_is_smooth (NautilusViewport *nautilus_viewport,
+ gboolean is_smooth)
+{
+ g_return_if_fail (NAUTILUS_IS_VIEWPORT (nautilus_viewport));
+
+ nautilus_viewport->details->is_smooth = is_smooth;
+
+ if (!GTK_WIDGET_REALIZED (nautilus_viewport)) {
+ return;
+ }
+
+ gdk_window_set_static_gravities (GTK_WIDGET (nautilus_viewport)->window, is_smooth);
+ gdk_window_set_static_gravities (GTK_VIEWPORT (nautilus_viewport)->bin_window, is_smooth);
+ gdk_window_set_static_gravities (GTK_VIEWPORT (nautilus_viewport)->view_window, is_smooth);
+}
+
+NautilusArtIPoint
+nautilus_viewport_get_scroll_offset (const NautilusViewport *nautilus_viewport)
+{
+ NautilusArtIPoint scroll_offset;
+
+ g_return_val_if_fail (NAUTILUS_IS_VIEWPORT (nautilus_viewport), NAUTILUS_ART_IPOINT_ZERO);
+
+ if (!GTK_WIDGET_REALIZED (nautilus_viewport)) {
+ return NAUTILUS_ART_IPOINT_ZERO;
+ }
+
+ gdk_window_get_position (GTK_VIEWPORT (nautilus_viewport)->bin_window,
+ &scroll_offset.x,
+ &scroll_offset.y);
- return GTK_WIDGET (viewport);
+ return scroll_offset;
}
diff --git a/libnautilus-private/nautilus-viewport.h b/libnautilus-private/nautilus-viewport.h
index 69a3e58b6..5374165c8 100644
--- a/libnautilus-private/nautilus-viewport.h
+++ b/libnautilus-private/nautilus-viewport.h
@@ -27,6 +27,7 @@
#include <gtk/gtkviewport.h>
#include <libgnome/gnome-defs.h>
+#include <libnautilus-extensions/nautilus-smooth-widget.h>
BEGIN_GNOME_DECLS
@@ -36,23 +37,31 @@ BEGIN_GNOME_DECLS
#define NAUTILUS_IS_VIEWPORT(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_VIEWPORT))
#define NAUTILUS_IS_VIEWPORT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_VIEWPORT))
-typedef struct _NautilusViewport NautilusViewport;
-typedef struct _NautilusViewportClass NautilusViewportClass;
+typedef struct NautilusViewport NautilusViewport;
+typedef struct NautilusViewportClass NautilusViewportClass;
+typedef struct NautilusViewportDetails NautilusViewportDetails;
-struct _NautilusViewport
+struct NautilusViewport
{
/* Superclass */
GtkViewport viewport;
+
+ /* Private things */
+ NautilusViewportDetails *details;
};
-struct _NautilusViewportClass
+struct NautilusViewportClass
{
GtkViewportClass parent_class;
+ NautilusSmoothWidgetSetIsSmooth set_is_smooth;
};
-GtkType nautilus_viewport_get_type (void);
-GtkWidget *nautilus_viewport_new (GtkAdjustment *hadjustment,
- GtkAdjustment *vadjustment);
+GtkType nautilus_viewport_get_type (void);
+GtkWidget * nautilus_viewport_new (GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment);
+void nautilus_viewport_set_is_smooth (NautilusViewport *nautilus_viewport,
+ gboolean is_smooth);
+NautilusArtIPoint nautilus_viewport_get_scroll_offset (const NautilusViewport *nautilus_viewport);
END_GNOME_DECLS
diff --git a/libnautilus-private/nautilus-wrap-table.c b/libnautilus-private/nautilus-wrap-table.c
index fb51a881f..8a2c62353 100644
--- a/libnautilus-private/nautilus-wrap-table.c
+++ b/libnautilus-private/nautilus-wrap-table.c
@@ -635,9 +635,10 @@ wrap_table_get_content_frame (const NautilusWrapTable *wrap_table)
wrap_table->details->x_spacing,
max_child_frame.x1);
num_rows = num_children / num_cols;
+ num_rows = MAX (num_rows, 1);
if ((num_children % num_rows) > 0) {
- num_rows++;
+ num_rows++;
}
content_frame.x1 = frame.x1;
@@ -681,11 +682,7 @@ wrap_table_get_scroll_offset (const NautilusWrapTable *wrap_table)
* parent here. Theres probably a better way to do this
*/
if (GTK_IS_VIEWPORT (parent)) {
- GtkViewport *viewport;
-
- viewport = GTK_VIEWPORT (parent);
-
- gdk_window_get_position (viewport->bin_window,
+ gdk_window_get_position (GTK_VIEWPORT (parent)->bin_window,
&scroll_offset.x,
&scroll_offset.y);
}
@@ -933,7 +930,57 @@ nautilus_wrap_table_set_homogeneous (NautilusWrapTable *wrap_table,
gboolean
nautilus_wrap_table_get_homogeneous (const NautilusWrapTable *wrap_table)
{
- g_return_val_if_fail (NAUTILUS_IS_WRAP_TABLE (wrap_table), 0);
+ g_return_val_if_fail (NAUTILUS_IS_WRAP_TABLE (wrap_table), FALSE);
return wrap_table->details->homogeneous;
}
+
+/**
+ * nautilus_wrap_table_reorder_child:
+ * @wrap_table: A NautilusWrapTable.
+ * @child: Child to reorder.
+ * @position: New position to put child at.
+ *
+ * Reorder the given chilren into the given position.
+ *
+ * Position is interpreted as follows:
+ *
+ * 0 - Place child at start of table.
+ * -1 - Place child at end of table.
+ * n - Place child at nth position. Count starts at 0.
+ */
+void
+nautilus_wrap_table_reorder_child (NautilusWrapTable *wrap_table,
+ GtkWidget *child,
+ int position)
+{
+ GList *node;
+ gboolean found_child = FALSE;
+
+ g_return_if_fail (NAUTILUS_IS_WRAP_TABLE (wrap_table));
+ g_return_if_fail (g_list_length (wrap_table->details->items) > 0);
+
+ if (position == -1) {
+ position = g_list_length (wrap_table->details->items) - 1;
+ }
+
+ g_return_if_fail (position >= 0);
+ g_return_if_fail ((guint) position < g_list_length (wrap_table->details->items));
+
+ for (node = wrap_table->details->items; node != NULL; node = node->next) {
+ GtkWidget *next_child;
+ next_child = node->data;
+
+ if (next_child == child) {
+ g_assert (found_child == FALSE);
+ found_child = TRUE;
+ }
+ }
+
+ g_return_if_fail (found_child);
+
+ wrap_table->details->items = g_list_remove (wrap_table->details->items, child);
+ wrap_table->details->items = g_list_insert (wrap_table->details->items, child, position);
+
+ gtk_widget_queue_resize (GTK_WIDGET (wrap_table));
+}
diff --git a/libnautilus-private/nautilus-wrap-table.h b/libnautilus-private/nautilus-wrap-table.h
index 0a18a6724..497132e22 100644
--- a/libnautilus-private/nautilus-wrap-table.h
+++ b/libnautilus-private/nautilus-wrap-table.h
@@ -82,6 +82,9 @@ NautilusJustification nautilus_wrap_table_get_y_justification (const Nauti
void nautilus_wrap_table_set_homogeneous (NautilusWrapTable *wrap_table,
gboolean homogeneous);
gboolean nautilus_wrap_table_get_homogeneous (const NautilusWrapTable *wrap_table);
+void nautilus_wrap_table_reorder_child (NautilusWrapTable *wrap_table,
+ GtkWidget *child,
+ int position);
END_GNOME_DECLS
diff --git a/src/file-manager/fm-properties-window.c b/src/file-manager/fm-properties-window.c
index 7781965c6..1222e4efa 100644
--- a/src/file-manager/fm-properties-window.c
+++ b/src/file-manager/fm-properties-window.c
@@ -64,6 +64,9 @@
#include <libnautilus-extensions/nautilus-string.h>
#include <libnautilus-extensions/nautilus-undo-signal-handlers.h>
#include <libnautilus/nautilus-undo.h>
+#include <libnautilus-extensions/nautilus-wrap-table.h>
+#include <libnautilus-extensions/nautilus-labeled-image.h>
+#include <libnautilus-extensions/nautilus-viewport.h>
#include <string.h>
static GHashTable *windows;
@@ -1542,44 +1545,33 @@ remove_default_viewport_shadow (GtkViewport *viewport)
gtk_viewport_set_shadow_type (viewport, GTK_SHADOW_NONE);
}
-/* This is the callback for the focus_out signal, where we queue a redraw to erase
- * the remains of the focus rect which is being left on the screen for reasons that
- * I don't understand.
- */
-static gint
-property_button_focused_out (GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
-{
- gtk_widget_queue_draw (GTK_WIDGET (widget->parent));
- return TRUE;
-}
-
static void
create_emblems_page (FMPropertiesWindow *window)
{
NautilusCustomizationData *customization_data;
GtkWidget *emblems_table, *button, *scroller;
- GtkWidget *image_and_label_table;
char *emblem_name, *dot_pos;
- GtkWidget *emblem_pixmap_widget;
- GtkWidget *emblem_label;
+ GdkPixbuf *pixbuf;
+ char *label;
int row, column;
NautilusFile *file;
file = window->details->file;
- /* we use an estimate for the number of rows - the table will grow as we add more */
- emblems_table = gtk_table_new (4, EMBLEM_COLUMN_COUNT, TRUE);
+ /* The emblems wrapped table */
+ emblems_table = nautilus_wrap_table_new (TRUE);
+
gtk_widget_show (emblems_table);
gtk_container_set_border_width (GTK_CONTAINER (emblems_table), GNOME_PAD);
- gtk_table_set_row_spacings (GTK_TABLE (emblems_table), GNOME_PAD);
- gtk_table_set_col_spacings (GTK_TABLE (emblems_table), 2*GNOME_PAD_BIG);
-
+
scroller = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroller),
- emblems_table);
+
+ /* Viewport */
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroller),
+ emblems_table);
gtk_widget_show (scroller);
/* Get rid of default lowered shadow appearance.
@@ -1604,8 +1596,8 @@ create_emblems_page (FMPropertiesWindow *window)
while (nautilus_customization_data_get_next_element_for_display (customization_data,
&emblem_name,
- &emblem_pixmap_widget,
- &emblem_label) == GNOME_VFS_OK) {
+ &pixbuf,
+ &label) == GNOME_VFS_OK) {
/* strip the suffix, if any */
dot_pos = strrchr(emblem_name, '.');
@@ -1614,25 +1606,15 @@ create_emblems_page (FMPropertiesWindow *window)
}
if (strcmp (emblem_name, "erase") == 0) {
- gtk_widget_destroy (emblem_pixmap_widget);
- gtk_widget_destroy (emblem_label);
+ gdk_pixbuf_unref (pixbuf);
+ g_free (label);
g_free (emblem_name);
continue;
}
- button = gtk_check_button_new ();
-
- image_and_label_table = gtk_table_new (2, 1, FALSE);
-
- gtk_table_attach_defaults (GTK_TABLE (image_and_label_table), emblem_pixmap_widget,
- 0, 1,
- 0, 1);
-
- gtk_table_attach_defaults (GTK_TABLE (image_and_label_table), emblem_label,
- 0, 1,
- 1, 2);
-
- gtk_container_add (GTK_CONTAINER (button), image_and_label_table);
+ button = nautilus_labeled_image_check_button_new (label, pixbuf);
+ g_free (label);
+ gdk_pixbuf_unref (pixbuf);
/* Attach parameters and signal handler. */
gtk_object_set_data_full (GTK_OBJECT (button),
@@ -1651,12 +1633,6 @@ create_emblems_page (FMPropertiesWindow *window)
property_button_toggled,
NULL);
- /* attach to focus out signal to fix focus rect drawing anomaly */
- gtk_signal_connect (GTK_OBJECT (button),
- "focus_out_event",
- GTK_SIGNAL_FUNC (property_button_focused_out),
- NULL);
-
/* Set initial state of button. */
property_button_update (GTK_TOGGLE_BUTTON (button));
@@ -1666,10 +1642,8 @@ create_emblems_page (FMPropertiesWindow *window)
property_button_update,
GTK_OBJECT (button));
- gtk_table_attach_defaults (GTK_TABLE (emblems_table), button,
- column, column + 1,
- row, row+1);
-
+ gtk_container_add (GTK_CONTAINER (emblems_table), button);
+
if (++column == EMBLEM_COLUMN_COUNT) {
column = 0;
++row;
diff --git a/src/nautilus-property-browser.c b/src/nautilus-property-browser.c
index 3c896dcb7..717981bea 100644
--- a/src/nautilus-property-browser.c
+++ b/src/nautilus-property-browser.c
@@ -78,6 +78,9 @@
#include <libnautilus-extensions/nautilus-string.h>
#include <libnautilus-extensions/nautilus-theme.h>
#include <libnautilus-extensions/nautilus-xml-extensions.h>
+#include <libnautilus-extensions/nautilus-labeled-image.h>
+#include <libnautilus-extensions/nautilus-image-table.h>
+#include <libnautilus-extensions/nautilus-viewport.h>
#include <math.h>
/* property types */
@@ -131,7 +134,6 @@ struct NautilusPropertyBrowserDetails {
NautilusPropertyType category_type;
int category_position;
- int content_table_width;
GdkPixbuf *property_chit;
@@ -171,15 +173,18 @@ static void nautilus_property_browser_drag_data_get (GtkWidget
GtkSelectionData *selection_data,
guint info,
guint32 time);
-static void nautilus_property_browser_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-
static void nautilus_property_browser_theme_changed (gpointer user_data);
static void emit_emblems_changed_signal (void);
/* misc utilities */
static char * strip_extension (const char *string_to_strip);
+static void element_clicked_callback (GtkWidget *image_table,
+ GtkWidget *child,
+ const NautilusImageTableEvent *event,
+ gpointer callback_data);
+
+
#define BROWSER_BACKGROUND_COLOR "rgb:FFFF/FFFF/FFFF"
#define THEME_SELECT_COLOR "rgb:FFFF/9999/9999"
@@ -223,7 +228,6 @@ nautilus_property_browser_initialize_class (GtkObjectClass *object_klass)
object_klass->destroy = nautilus_property_browser_destroy;
widget_class->drag_data_get = nautilus_property_browser_drag_data_get;
widget_class->drag_end = nautilus_property_browser_drag_end;
- widget_class->size_allocate = nautilus_property_browser_size_allocate;
}
/* initialize the instance's fields, create the necessary subviews, etc. */
@@ -261,17 +265,17 @@ nautilus_property_browser_initialize (GtkObject *object)
/* create the container box */
property_browser->details->container = GTK_HBOX (gtk_hbox_new (FALSE, 0));
- gtk_container_set_border_width (GTK_CONTAINER (property_browser->details->container), 0);
+ gtk_container_set_border_width (GTK_CONTAINER (property_browser->details->container), 0);
gtk_widget_show (GTK_WIDGET (property_browser->details->container));
gtk_container_add (GTK_CONTAINER (property_browser),
GTK_WIDGET (property_browser->details->container));
/* make the category container */
property_browser->details->category_container = gtk_scrolled_window_new (NULL, NULL);
- gtk_container_set_border_width (GTK_CONTAINER (property_browser->details->category_container), 0 );
+ gtk_container_set_border_width (GTK_CONTAINER (property_browser->details->category_container), 0);
property_browser->details->category_position = -1;
- viewport = gtk_viewport_new(NULL, NULL);
+ viewport = nautilus_viewport_new(NULL, NULL);
gtk_widget_show (viewport);
gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
@@ -1443,16 +1447,30 @@ remove_button_callback(GtkWidget *widget, NautilusPropertyBrowser *property_brow
/* this callback handles clicks on the image or color based content content elements */
static void
-element_clicked_callback (GtkWidget *widget, GdkEventButton *event, char *element_name)
+element_clicked_callback (GtkWidget *image_table,
+ GtkWidget *child,
+ const NautilusImageTableEvent *event,
+ gpointer callback_data)
{
+ NautilusPropertyBrowser *property_browser;
GtkTargetList *target_list;
GdkDragContext *context;
GdkPixbuf *pixbuf;
GdkPixmap *pixmap_for_dragged_file;
GdkBitmap *mask_for_dragged_file;
int x_delta, y_delta;
- NautilusPropertyBrowser *property_browser = NAUTILUS_PROPERTY_BROWSER(gtk_object_get_user_data(GTK_OBJECT(widget)));
-
+ const char *element_name;
+ NautilusArtIPoint scroll_offset;
+
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+ g_return_if_fail (NAUTILUS_IS_LABELED_IMAGE (child));
+ g_return_if_fail (event != NULL);
+ g_return_if_fail (NAUTILUS_IS_PROPERTY_BROWSER (callback_data));
+ g_return_if_fail (gtk_object_get_data (GTK_OBJECT (child), "property-name") != NULL);
+
+ element_name = gtk_object_get_data (GTK_OBJECT (child), "property-name");
+ property_browser = NAUTILUS_PROPERTY_BROWSER (callback_data);
+
/* handle remove mode by removing the element */
if (property_browser->details->remove_mode) {
nautilus_property_browser_remove_element(property_browser, element_name);
@@ -1478,13 +1496,11 @@ element_clicked_callback (GtkWidget *widget, GdkEventButton *event, char *elemen
target_list,
GDK_ACTION_MOVE | GDK_ACTION_COPY,
event->button,
- (GdkEvent *) event);
+ NULL);
/* compute the offsets for dragging */
-
- x_delta = floor(event->x + .5);
- y_delta = floor(event->y + .5) ;
-
+ scroll_offset = nautilus_viewport_get_scroll_offset (NAUTILUS_VIEWPORT (image_table->parent));
+
if (strcmp(drag_types[0].target, "application/x-color")) {
/*it's not a color, so, for now, it must be an image */
/* fiddle with the category to handle the "reset" case properly */
@@ -1494,12 +1510,12 @@ element_clicked_callback (GtkWidget *widget, GdkEventButton *event, char *elemen
}
pixbuf = make_drag_image (property_browser, element_name);
property_browser->details->category = save_category;
-
- x_delta -= (widget->allocation.width - gdk_pixbuf_get_width (pixbuf)) >> 1;
- y_delta -= (widget->allocation.height - gdk_pixbuf_get_height (pixbuf)) >> 1;
-
+ x_delta = gdk_pixbuf_get_width (pixbuf) / 2;
+ y_delta = gdk_pixbuf_get_height (pixbuf) / 2;
} else {
pixbuf = make_color_drag_image (property_browser, element_name, TRUE);
+ x_delta = event->x - child->allocation.x - scroll_offset.x;
+ y_delta = event->y - child->allocation.y - scroll_offset.y;
}
/* set the pixmap and mask for dragging */
@@ -1546,90 +1562,50 @@ strip_extension (const char* string_to_strip)
static void
nautilus_property_browser_preferences_changed (NautilusPropertyBrowser *property_browser)
{
- nautilus_property_browser_update_contents(property_browser);
-}
-
-/* utility routine to add the passed-in widget to the content table */
-
-static void
-add_to_content_table (NautilusPropertyBrowser *property_browser, GtkWidget* widget, int position, int padding)
-{
- int column_pos = position % property_browser->details->content_table_width;
- int row_pos = position / property_browser->details->content_table_width;
-
- gtk_table_attach (GTK_TABLE (property_browser->details->content_table),
- widget, column_pos, column_pos + 1, row_pos ,row_pos + 1,
- GTK_FILL, GTK_FILL, padding, padding);
+ nautilus_property_browser_update_contents (property_browser);
}
-
-/* make_properties_from_directories generates widgets corresponding all of the objects
- in the public and private directories */
-
+/* Make a color tile for a property */
static GtkWidget *
make_property_tile (NautilusPropertyBrowser *property_browser,
- GtkWidget *pixmap_widget,
- GtkWidget *label,
- const char* property_name)
+ GdkPixbuf *pixbuf,
+ const char *label,
+ const char *property_name)
{
- NautilusBackground *background;
- GtkWidget *temp_vbox, *event_box;
-
- temp_vbox = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (temp_vbox);
+ GtkWidget *image;
- event_box = gtk_event_box_new ();
- gtk_widget_show (event_box);
+ g_return_val_if_fail (NAUTILUS_IS_PROPERTY_BROWSER (property_browser), NULL);
+ g_return_val_if_fail (pixbuf != NULL, NULL);
+ g_return_val_if_fail (label != NULL, NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+ g_return_val_if_fail (property_name[0] != '\0', NULL);
+
+ image = nautilus_labeled_image_new (label, pixbuf);
- background = nautilus_get_widget_background (GTK_WIDGET (event_box));
- nautilus_background_set_color (background, BROWSER_BACKGROUND_COLOR);
+ nautilus_labeled_image_set_background_mode (NAUTILUS_LABELED_IMAGE (image),
+ NAUTILUS_SMOOTH_BACKGROUND_SOLID_COLOR);
+ nautilus_labeled_image_set_solid_background_color (NAUTILUS_LABELED_IMAGE (image),
+ NAUTILUS_RGB_COLOR_WHITE);
- if (label != NULL) {
- nautilus_label_set_background_mode
- (NAUTILUS_LABEL (label), NAUTILUS_SMOOTH_BACKGROUND_SOLID_COLOR);
- nautilus_label_set_solid_background_color
- (NAUTILUS_LABEL (label), NAUTILUS_RGB_COLOR_WHITE);
- nautilus_label_make_smaller (NAUTILUS_LABEL (label), 3);
- gtk_box_pack_end (GTK_BOX (temp_vbox), label, FALSE, FALSE, 2);
- gtk_widget_show (label);
- }
+ nautilus_labeled_image_make_smaller (NAUTILUS_LABELED_IMAGE (image), 2);
+ gtk_widget_show (image);
- gtk_widget_show (pixmap_widget);
- gtk_container_add (GTK_CONTAINER(event_box), pixmap_widget);
- gtk_box_pack_end (GTK_BOX (temp_vbox), event_box, FALSE, FALSE, 0);
-
- gtk_object_set_user_data (GTK_OBJECT(event_box), property_browser);
- gtk_signal_connect_full
- (GTK_OBJECT (event_box),
- "button_press_event",
- GTK_SIGNAL_FUNC (element_clicked_callback),
- NULL,
- g_strdup (property_name),
- g_free,
- FALSE,
- FALSE);
-
- return temp_vbox;
+ gtk_object_set_data_full (GTK_OBJECT (image),
+ "property-name",
+ g_strdup (property_name),
+ (GtkDestroyNotify) g_free);
+
+ return image;
}
-static int
+static void
make_properties_from_directories (NautilusPropertyBrowser *property_browser)
{
NautilusCustomizationData *customization_data;
char *object_name;
- GtkWidget *pixmap_widget;
- GtkWidget *label;
- GtkWidget *erase_object;
- int index, object_position = 0;
-
- /* make room for the reset property if necessary */
- if (property_browser->details->category_type == NAUTILUS_PROPERTY_PATTERN &&
- !property_browser->details->remove_mode) {
- index = 1;
- } else {
- index = 0;
- }
-
+ char *object_label;
+ GdkPixbuf *object_pixbuf;
+
if (property_browser->details->category_type == NAUTILUS_PROPERTY_EMBLEM) {
nautilus_g_list_free_deep (property_browser->details->keywords);
property_browser->details->keywords = NULL;
@@ -1641,87 +1617,87 @@ make_properties_from_directories (NautilusPropertyBrowser *property_browser)
MAX_ICON_WIDTH,
MAX_ICON_HEIGHT);
if (customization_data == NULL) {
- return index;
+ return;
}
- erase_object = NULL;
-
/* interate through the set of objects and display each */
while (nautilus_customization_data_get_next_element_for_display (customization_data,
&object_name,
- &pixmap_widget,
- &label) == GNOME_VFS_OK) {
- GtkWidget *temp_vbox;
+ &object_pixbuf,
+ &object_label) == GNOME_VFS_OK) {
+ GtkWidget *property_image;
- /* set the mode of the returned nautilus_image since the background is fixed */
- nautilus_image_set_background_mode (NAUTILUS_IMAGE (pixmap_widget), NAUTILUS_SMOOTH_BACKGROUND_SOLID_COLOR);
- nautilus_image_set_solid_background_color (NAUTILUS_IMAGE (pixmap_widget), NAUTILUS_RGB_COLOR_WHITE);
+ property_image = make_property_tile (property_browser, object_pixbuf, object_label, object_name);
+
+ g_free (object_label);
+ gdk_pixbuf_unref (object_pixbuf);
- /* allocate a pixmap and insert it into the table */
- temp_vbox = make_property_tile (property_browser, pixmap_widget, label, object_name);
-
- /* put the reset item in the pole position or the erase image at the end */
- object_position = index++;
- if (property_browser->details->category_type == NAUTILUS_PROPERTY_PATTERN) {
- if (nautilus_strcmp (object_name, RESET_IMAGE_NAME) == 0) {
- object_position = 0;
- index -= 1;
- }
- } else if (property_browser->details->category_type == NAUTILUS_PROPERTY_EMBLEM) {
- char *keyword, *extension;
+ if (property_browser->details->category_type == NAUTILUS_PROPERTY_EMBLEM) {
+ char *keyword;
+ char *extension;
keyword = g_strdup (object_name);
extension = strchr (keyword, '.');
+
if (extension) {
*extension = '\0';
}
- property_browser->details->keywords = g_list_prepend (property_browser->details->keywords, keyword);
- if (nautilus_strcmp (object_name, ERASE_OBJECT_NAME) == 0) {
- object_position = -1;
- erase_object = temp_vbox;
- index -= 1;
- }
+
+ property_browser->details->keywords = g_list_prepend (property_browser->details->keywords,
+ keyword);
}
- if (object_position >= 0) {
- add_to_content_table(property_browser, temp_vbox, object_position, 2);
+
+ gtk_container_add (GTK_CONTAINER (property_browser->details->content_table), property_image);
+
+ /*
+ * If the object is either a "pattern reset" or "emblem erase" always
+ * place them at the start of the table
+ */
+ if ((property_browser->details->category_type == NAUTILUS_PROPERTY_PATTERN
+ && nautilus_str_is_equal (object_name, RESET_IMAGE_NAME))
+ || ((property_browser->details->category_type == NAUTILUS_PROPERTY_EMBLEM)
+ && nautilus_str_is_equal (object_name, ERASE_OBJECT_NAME))) {
+ nautilus_wrap_table_reorder_child (NAUTILUS_WRAP_TABLE (property_browser->details->content_table),
+ property_image,
+ 0);
}
- g_free (object_name);
- }
-
- /* add the eraser if necessary */
- if (erase_object != NULL) {
- add_to_content_table(property_browser, erase_object, object_position + 2, 2);
+
+ gtk_widget_show (property_image);
}
-
+
property_browser->details->has_local = nautilus_customization_data_private_data_was_displayed (customization_data);
nautilus_customization_data_destroy (customization_data);
-
- return index;
}
/* utility routine to add a reset property in the first position */
static void
add_reset_property (NautilusPropertyBrowser *property_browser)
{
- char *reset_path;
- GtkWidget *new_property;
- GdkPixbuf *pixbuf, *reset_pixbuf;
- GtkWidget *image_widget, *label;
-
- reset_path = g_strdup_printf ("%s/%s/%s", NAUTILUS_DATADIR, "patterns", RESET_IMAGE_NAME);
- pixbuf = gdk_pixbuf_new_from_file (reset_path);
- reset_pixbuf = nautilus_customization_make_pattern_chit (pixbuf, property_browser->details->property_chit, FALSE);
- g_free (reset_path);
-
- image_widget = nautilus_image_new (NULL);
- nautilus_image_set_pixbuf (NAUTILUS_IMAGE (image_widget), reset_pixbuf);
- gdk_pixbuf_unref (reset_pixbuf);
+ char *reset_image_file_name;
+ GtkWidget *reset_image;
+
+ reset_image_file_name = g_strdup_printf ("%s/%s/%s", NAUTILUS_DATADIR, "patterns", RESET_IMAGE_NAME);
+
+ reset_image = nautilus_labeled_image_new_from_file_name ("", reset_image_file_name);
+ nautilus_labeled_image_set_background_mode (NAUTILUS_LABELED_IMAGE (reset_image),
+ NAUTILUS_SMOOTH_BACKGROUND_SOLID_COLOR);
+ nautilus_labeled_image_set_solid_background_color (NAUTILUS_LABELED_IMAGE (reset_image),
+ NAUTILUS_RGB_COLOR_WHITE);
+
+ g_free (reset_image_file_name);
- /* make the label from the name */
- label = nautilus_label_new ("");
+ gtk_widget_show (reset_image);
- new_property = make_property_tile (property_browser, image_widget, label, RESET_IMAGE_NAME);
- add_to_content_table (property_browser, new_property, 0, 2);
+ gtk_container_add (GTK_CONTAINER (property_browser->details->content_table), reset_image);
+
+ nautilus_wrap_table_reorder_child (NAUTILUS_WRAP_TABLE (property_browser->details->content_table),
+ reset_image,
+ 0);
+
+ gtk_object_set_data_full (GTK_OBJECT (reset_image),
+ "property-name",
+ g_strdup (RESET_IMAGE_NAME),
+ (GtkDestroyNotify) g_free);
}
/* generate properties from the children of the passed in node */
@@ -1733,8 +1709,7 @@ make_properties_from_xml_node (NautilusPropertyBrowser *property_browser,
{
xmlNodePtr child_node;
GdkPixbuf *pixbuf;
- GtkWidget *image_widget, *label, *new_property;
- int index;
+ GtkWidget *new_property;
char *deleted, *local, *color, *name;
gboolean local_only = property_browser->details->remove_mode;
@@ -1742,9 +1717,7 @@ make_properties_from_xml_node (NautilusPropertyBrowser *property_browser,
/* add a reset property in the first slot */
if (!property_browser->details->remove_mode) {
add_reset_property (property_browser);
- index = 1;
- } else
- index = 0;
+ }
property_browser->details->has_local = FALSE;
@@ -1764,17 +1737,12 @@ make_properties_from_xml_node (NautilusPropertyBrowser *property_browser,
/* make the image from the color spec */
pixbuf = make_color_drag_image (property_browser, color, FALSE);
- image_widget = nautilus_image_new (NULL);
- nautilus_image_set_pixbuf (NAUTILUS_IMAGE (image_widget), pixbuf);
- gdk_pixbuf_unref (pixbuf);
-
- /* make the label from the name */
- label = nautilus_label_new (name);
-
+
/* make the tile from the pixmap and name */
- new_property = make_property_tile (property_browser, image_widget, label, color);
- add_to_content_table (property_browser, new_property, index++, 2);
-
+ new_property = make_property_tile (property_browser, pixbuf, name, color);
+ gtk_container_add (GTK_CONTAINER (property_browser->details->content_table), new_property);
+
+ gdk_pixbuf_unref (pixbuf);
xmlFree (color);
xmlFree (name);
}
@@ -1811,50 +1779,60 @@ make_category(NautilusPropertyBrowser *property_browser, const char* path, const
}
+/* Create a category button */
+static GtkWidget *
+property_browser_category_button_new (const char *display_name,
+ const char *image)
+{
+ GtkWidget *button;
+ char *file_name;
+
+ g_return_val_if_fail (display_name != NULL, NULL);
+ g_return_val_if_fail (image != NULL, NULL);
+
+ file_name = nautilus_pixmap_file (image);
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ button = nautilus_labeled_image_toggle_button_new_from_file_name (display_name,
+ file_name);
+
+ /* We want the label to never be smooth */
+ nautilus_labeled_image_set_label_never_smooth (NAUTILUS_LABELED_IMAGE (GTK_BIN (button)->child), TRUE);
+
+ g_free (file_name);
+
+ return button;
+}
+
/* this is a utility routine to generate a category link widget and install it in the browser */
static void
-make_category_link (NautilusPropertyBrowser *property_browser, char* name, char *display_name, char* image)
+make_category_link (NautilusPropertyBrowser *property_browser,
+ const char *name,
+ const char *display_name,
+ const char *image)
{
- GtkWidget *label, *pix_widget, *button, *temp_vbox;
- char *file_name = nautilus_pixmap_file (image);
- GtkWidget* temp_box = gtk_vbox_new (FALSE, 0);
-
- pix_widget = GTK_WIDGET (nautilus_image_new (file_name));
- gtk_widget_show (pix_widget);
- gtk_box_pack_start (GTK_BOX (temp_box), pix_widget, FALSE, FALSE, 0);
-
- /* FIXME bugzilla.eazel.com 5587:
- * We cant hard code the geometry of buttons because we dont know
- * what the geometry of the label text is going to be.
- */
- button = gtk_toggle_button_new();
- gtk_widget_show(button);
+ GtkWidget *button;
+
+ g_return_if_fail (NAUTILUS_IS_PROPERTY_BROWSER (property_browser));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (display_name != NULL);
+ g_return_if_fail (image != NULL);
+
+ button = property_browser_category_button_new (display_name, image);
+ gtk_widget_show (button);
/* if the button represents the current category, highlight it */
if (property_browser->details->category && !strcmp(property_browser->details->category, name)) {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
property_browser->details->selected_button = button;
}
-
- /* put the button in a vbox so it won't grow vertically */
- temp_vbox = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (temp_vbox);
- gtk_box_pack_start (GTK_BOX (temp_vbox), button, FALSE, FALSE, 1);
- /* use the name as a label */
- label = gtk_label_new (display_name);
-
- gtk_box_pack_start (GTK_BOX (temp_box), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
+ /* Place it in the category box */
gtk_box_pack_start (GTK_BOX (property_browser->details->category_box),
- temp_vbox, FALSE, FALSE, 8);
+ button, FALSE, FALSE, 8);
property_browser->details->category_position += 1;
- gtk_container_add (GTK_CONTAINER (button), temp_box);
- gtk_widget_show (temp_box);
-
/* add a signal to handle clicks */
gtk_object_set_user_data (GTK_OBJECT(button), property_browser);
gtk_signal_connect_full
@@ -1866,69 +1844,6 @@ make_category_link (NautilusPropertyBrowser *property_browser, char* name, char
g_free,
FALSE,
FALSE);
-
- g_free (file_name);
-}
-
-/* return the width of the current category for layout */
-
-/* FIXME: this is bogus - we really have to measure the text labels to figure
- * out the category width
- */
-
-static int
-nautilus_property_browser_get_category_width (NautilusPropertyBrowser *property_browser)
-{
- int category_width;
- switch (property_browser->details->category_type) {
- case NAUTILUS_PROPERTY_PATTERN:
- category_width = 80;
- break;
- case NAUTILUS_PROPERTY_COLOR:
- category_width = 80;
- break;
- case NAUTILUS_PROPERTY_EMBLEM:
- category_width = 64;
- break;
- default:
- category_width = 80;
- break;
- }
- return category_width;
-}
-
-/* extract the number of columns for the current category from the xml file */
-static void
-set_up_category_width (NautilusPropertyBrowser *property_browser)
-{
- int container_width, category_width;
-
- /* set up the default */
- property_browser->details->content_table_width = 5;
-
- container_width = property_browser->details->content_container->allocation.width;
- category_width = nautilus_property_browser_get_category_width (property_browser);
-
- if (container_width > 64) {
- property_browser->details->content_table_width = container_width / category_width;
- if (property_browser->details->content_table_width < 1) {
- property_browser->details->content_table_width = 1;
- }
- return;
- }
-
-}
-
-static void
-update_category_width (NautilusPropertyBrowser *property_browser)
-{
- int current_width;
-
- current_width = property_browser->details->content_table_width;
- set_up_category_width (property_browser);
- if (current_width != property_browser->details->content_table_width) {
- nautilus_property_browser_update_contents (property_browser);
- }
}
/* update_contents populates the property browser with information specified by the path and other state variables */
@@ -1954,15 +1869,10 @@ nautilus_property_browser_update_contents (NautilusPropertyBrowser *property_bro
gtk_widget_destroy(property_browser->details->content_frame);
}
- /* set up the content_table_width field so we know how many columns to put in the table */
- set_up_category_width (property_browser);
-
/* allocate a new container, with a scrollwindow and viewport */
-
property_browser->details->content_frame = gtk_scrolled_window_new (NULL, NULL);
gtk_container_set_border_width (GTK_CONTAINER (property_browser->details->content_frame), 0);
-
- viewport = gtk_viewport_new(NULL, NULL);
+ viewport = nautilus_viewport_new (NULL, NULL);
gtk_widget_show(viewport);
gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_IN);
background = nautilus_get_widget_background (viewport);
@@ -1972,7 +1882,13 @@ nautilus_property_browser_update_contents (NautilusPropertyBrowser *property_bro
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (property_browser->details->content_frame), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
/* allocate a table to hold the content widgets */
- property_browser->details->content_table = gtk_table_new(property_browser->details->content_table_width, CONTENT_TABLE_HEIGHT, FALSE);
+ property_browser->details->content_table = nautilus_image_table_new (TRUE);
+
+ gtk_signal_connect (GTK_OBJECT (property_browser->details->content_table),
+ "child_pressed",
+ GTK_SIGNAL_FUNC (element_clicked_callback),
+ property_browser);
+
gtk_container_add(GTK_CONTAINER(viewport), property_browser->details->content_table);
gtk_container_add (GTK_CONTAINER (property_browser->details->content_frame), viewport);
gtk_widget_show (GTK_WIDGET (property_browser->details->content_table));
@@ -2188,20 +2104,8 @@ nautilus_property_browser_set_path (NautilusPropertyBrowser *property_browser,
nautilus_property_browser_update_contents (property_browser);
}
-/* handle resizing ourselves by relaying out if necessary */
-static void
-nautilus_property_browser_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
- NautilusPropertyBrowser *property_browser = NAUTILUS_PROPERTY_BROWSER (widget);
-
- NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, size_allocate, (widget, allocation));
-
- update_category_width (property_browser);
-}
-
static void
emit_emblems_changed_signal (void)
{
- gtk_signal_emit_by_name (nautilus_signaller_get_current (),
- "emblems_changed");
+ gtk_signal_emit_by_name (nautilus_signaller_get_current (), "emblems_changed");
}
diff --git a/src/nautilus-search-bar-criterion.c b/src/nautilus-search-bar-criterion.c
index 56498f779..f1ebc0eab 100644
--- a/src/nautilus-search-bar-criterion.c
+++ b/src/nautilus-search-bar-criterion.c
@@ -50,6 +50,7 @@
#include <libnautilus-extensions/nautilus-search-uri.h>
#include <libnautilus-extensions/nautilus-string.h>
#include <libnautilus-extensions/nautilus-undo-signal-handlers.h>
+#include <libnautilus-extensions/nautilus-labeled-image.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@@ -984,12 +985,11 @@ static void
make_emblem_value_menu (NautilusSearchBarCriterion *criterion)
{
NautilusCustomizationData *customization_data;
- GtkWidget *temp_hbox;
GtkWidget *menu_item;
char *emblem_name, *dot_pos;
- GtkWidget *emblem_pixmap_widget;
- GtkWidget *emblem_label;
GtkWidget *value_menu;
+ GdkPixbuf *pixbuf;
+ char *label;
/* Add the items to the emblems menu here */
value_menu = gtk_menu_new ();
@@ -1000,9 +1000,10 @@ make_emblem_value_menu (NautilusSearchBarCriterion *criterion)
NAUTILUS_ICON_SIZE_FOR_MENUS);
while (nautilus_customization_data_get_next_element_for_display (customization_data,
&emblem_name,
- &emblem_pixmap_widget,
- &emblem_label) == GNOME_VFS_OK) {
-
+ &pixbuf,
+ &label) == GNOME_VFS_OK) {
+ GtkWidget *image;
+
/* remove the suffix, if any, to make the emblem name */
dot_pos = strrchr (emblem_name, '.');
if (dot_pos) {
@@ -1010,21 +1011,29 @@ make_emblem_value_menu (NautilusSearchBarCriterion *criterion)
}
if (strcmp (emblem_name, "erase") == 0) {
- gtk_widget_destroy (emblem_pixmap_widget);
- gtk_widget_destroy (emblem_label);
+ gdk_pixbuf_unref (pixbuf);
+ g_free (label);
g_free (emblem_name);
continue;
}
menu_item = gtk_menu_item_new ();
gtk_object_set_data_full (GTK_OBJECT (menu_item), "emblem name",
- emblem_name, (GtkDestroyNotify) g_free);
- temp_hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
- gtk_box_pack_start (GTK_BOX (temp_hbox), emblem_pixmap_widget, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (temp_hbox), emblem_label, FALSE, FALSE, 0);
- gtk_container_add (GTK_CONTAINER (menu_item), temp_hbox);
+ g_strdup (emblem_name), (GtkDestroyNotify) g_free);
+
+
+ image = nautilus_labeled_image_new (label, pixbuf);
+ nautilus_labeled_image_set_label_position (NAUTILUS_LABELED_IMAGE (image), GTK_POS_RIGHT);
+ nautilus_labeled_image_set_x_alignment (NAUTILUS_LABELED_IMAGE (image), 0.0);
+ nautilus_labeled_image_set_spacing (NAUTILUS_LABELED_IMAGE (image), 4);
+
+ gtk_container_add (GTK_CONTAINER (menu_item), image);
gtk_widget_show_all (menu_item);
gtk_menu_append (GTK_MENU (value_menu), menu_item);
+
+ gdk_pixbuf_unref (pixbuf);
+ g_free (label);
+ g_free (emblem_name);
}
gtk_widget_show_all (GTK_WIDGET (criterion->details->value_menu));
diff --git a/test/test-nautilus-image-table.c b/test/test-nautilus-image-table.c
index 53fb7c1b3..9230f737d 100644
--- a/test/test-nautilus-image-table.c
+++ b/test/test-nautilus-image-table.c
@@ -5,6 +5,9 @@
static const char pixbuf_name[] = "/usr/share/pixmaps/gnome-globe.png";
+#define BG_COLOR 0xFFFFFF
+#define BG_COLOR_SPEC "white"
+
static const char *names[] =
{
"Tomaso Albinoni",
@@ -71,7 +74,7 @@ labeled_image_new (const char *text,
nautilus_labeled_image_set_background_mode (NAUTILUS_LABELED_IMAGE (image),
NAUTILUS_SMOOTH_BACKGROUND_SOLID_COLOR);
nautilus_labeled_image_set_solid_background_color (NAUTILUS_LABELED_IMAGE (image),
- 0xFFFFFF);
+ BG_COLOR);
nautilus_gdk_pixbuf_unref_if_not_null (pixbuf);
@@ -154,6 +157,47 @@ image_table_child_clicked_callback (GtkWidget *image_table,
g_print ("%s(%s)\n", __FUNCTION__, text);
}
+static int
+foo_timeout (gpointer callback_data)
+{
+ static int recursion_count = 0;
+ g_return_val_if_fail (GTK_IS_WINDOW (callback_data), FALSE);
+
+ recursion_count++;
+
+ g_print ("%s(%d)\n", __FUNCTION__, recursion_count);
+ gtk_widget_queue_resize (GTK_WIDGET (callback_data));
+
+ recursion_count--;
+
+ return FALSE;
+}
+
+static void
+image_table_size_allocate (GtkWidget *image_table,
+ GtkAllocation *allocation,
+ gpointer callback_data)
+{
+ static int recursion_count = 0;
+
+ g_return_if_fail (NAUTILUS_IS_IMAGE_TABLE (image_table));
+ g_return_if_fail (allocation != NULL);
+ g_return_if_fail (GTK_IS_WINDOW (callback_data));
+
+ recursion_count++;
+
+ if (0) gtk_timeout_add (0, foo_timeout, callback_data);
+
+ //gtk_widget_queue_resize (GTK_WIDGET (callback_data));
+
+ if (0) gtk_widget_size_allocate (GTK_WIDGET (image_table),
+ &GTK_WIDGET (image_table)->allocation);
+
+ g_print ("%s(%d)\n", __FUNCTION__, recursion_count);
+
+ recursion_count--;
+}
+
static GtkWidget *
image_table_new_scrolled (void)
{
@@ -180,6 +224,12 @@ image_table_new_scrolled (void)
gtk_container_add (GTK_CONTAINER (scrolled), viewport);
image_table = nautilus_image_table_new (FALSE);
+
+ if (0) gtk_signal_connect (GTK_OBJECT (image_table),
+ "size_allocate",
+ GTK_SIGNAL_FUNC (image_table_size_allocate),
+ window);
+
nautilus_wrap_table_set_x_justification (NAUTILUS_WRAP_TABLE (image_table),
NAUTILUS_JUSTIFICATION_MIDDLE);
nautilus_wrap_table_set_y_justification (NAUTILUS_WRAP_TABLE (image_table),
@@ -212,8 +262,7 @@ image_table_new_scrolled (void)
GTK_SIGNAL_FUNC (image_table_child_clicked_callback),
NULL);
- //test_gtk_widget_set_background_color (viewport, "white");
- nautilus_gtk_widget_set_background_color (viewport, "white:red");
+ nautilus_gtk_widget_set_background_color (viewport, BG_COLOR_SPEC);
for (i = 0; i < 100; i++) {
char *text;