summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Hertzfeld <andy@src.gnome.org>2001-04-01 23:44:46 +0000
committerAndy Hertzfeld <andy@src.gnome.org>2001-04-01 23:44:46 +0000
commit0f7c34dfb0a7a30cfce0820be2a6c80a9d0210f8 (patch)
tree309a25010f50ecd850590f20ad62e487b418d17c
parent9a61eb330ae70c247171629a7b402ce3ab4d3c00 (diff)
downloadnautilus-0f7c34dfb0a7a30cfce0820be2a6c80a9d0210f8.tar.gz
added a way for sidebar views to specify small images that are displayed
added a way for sidebar views to specify small images that are displayed in their tab for notification purposes. Used that to make the notes component indicate if a note is present or not. * components/notes/nautilus-notes.c: (get_bonobo_properties), (set_bonobo_properties), (load_note_text_from_metadata), (done_with_file), (notes_load_metainfo), (notify_listeners_if_changed), (notes_save_metainfo), (do_destroy), (notes_get_indicator_image), (make_notes_view): added a property bag to the notes component to provide a tab_image property, and made it notify the listeners when the note text changes. * icons/Makefile.am: * icons/note-indicator.png: new notes indicator image from Arlo. * src/nautilus-sidebar-tabs.c: (tab_item_destroy), (pixbuf_composite), (draw_one_tab_plain), (draw_one_tab_themed), (get_tab_width), (draw_or_layout_all_tabs), (nautilus_sidebar_tabs_expose), (nautilus_sidebar_tabs_update_tab_item), (get_tab_item_from_view), (nautilus_sidebar_tabs_update_all_indicators), (nautilus_sidebar_tabs_update_indicator), (tab_indicator_changed_callback), (nautilus_sidebar_tabs_connect_view): * src/nautilus-sidebar-tabs.h: made the sidebar tabs hook up to the nautilus_view's tab_image property and use it to display a notification image in the tab if necessary. * src/nautilus-sidebar.c: (view_loaded_callback), (nautilus_sidebar_add_panel): connect the sidebar tabs to a newly added view, once the view is loaded. * src/nautilus-view-frame.c: (nautilus_view_frame_get_control): * src/nautilus-view-frame.h: added nautilus_view_frame_get_control so view properties can be accessed by the sidebar.
-rw-r--r--ChangeLog46
-rw-r--r--components/notes/nautilus-notes.c123
-rw-r--r--icons/Makefile.am1
-rw-r--r--icons/note-indicator.pngbin0 -> 602 bytes
-rw-r--r--src/nautilus-information-panel.c11
-rw-r--r--src/nautilus-sidebar-tabs.c261
-rw-r--r--src/nautilus-sidebar-tabs.h3
-rw-r--r--src/nautilus-sidebar.c11
-rw-r--r--src/nautilus-view-frame.c11
-rw-r--r--src/nautilus-view-frame.h1
10 files changed, 431 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index ebc578ed1..3e33ef026 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2001-04-01 Andy Hertzfeld <andy@eazel.com>
+
+ reviewed by: Michael Engber <engber@eazel.com>
+
+ added a way for sidebar views to specify small images that
+ are displayed in their tab for notification purposes. Used
+ that to make the notes component indicate if a note is present or
+ not.
+
+ * components/notes/nautilus-notes.c: (get_bonobo_properties),
+ (set_bonobo_properties), (load_note_text_from_metadata),
+ (done_with_file), (notes_load_metainfo),
+ (notify_listeners_if_changed), (notes_save_metainfo), (do_destroy),
+ (notes_get_indicator_image), (make_notes_view):
+ added a property bag to the notes component to provide a tab_image
+ property, and made it notify the listeners when the note text
+ changes.
+
+ * icons/Makefile.am:
+ * icons/note-indicator.png:
+ new notes indicator image from Arlo.
+
+ * src/nautilus-sidebar-tabs.c: (tab_item_destroy),
+ (pixbuf_composite), (draw_one_tab_plain), (draw_one_tab_themed),
+ (get_tab_width), (draw_or_layout_all_tabs),
+ (nautilus_sidebar_tabs_expose),
+ (nautilus_sidebar_tabs_update_tab_item), (get_tab_item_from_view),
+ (nautilus_sidebar_tabs_update_all_indicators),
+ (nautilus_sidebar_tabs_update_indicator),
+ (tab_indicator_changed_callback),
+ (nautilus_sidebar_tabs_connect_view):
+ * src/nautilus-sidebar-tabs.h:
+ made the sidebar tabs hook up to the nautilus_view's tab_image
+ property and use it to display a notification image in the tab
+ if necessary.
+
+ * src/nautilus-sidebar.c: (view_loaded_callback),
+ (nautilus_sidebar_add_panel):
+ connect the sidebar tabs to a newly added view, once the view
+ is loaded.
+
+ * src/nautilus-view-frame.c: (nautilus_view_frame_get_control):
+ * src/nautilus-view-frame.h:
+ added nautilus_view_frame_get_control so view properties can be
+ accessed by the sidebar.
+
2001-03-31 Ramiro Estrugo <ramiro@eazel.com>
* src/nautilus-sidebar.c: (toggle_sidebar_panel):
diff --git a/components/notes/nautilus-notes.c b/components/notes/nautilus-notes.c
index b531e7ae0..da92d7852 100644
--- a/components/notes/nautilus-notes.c
+++ b/components/notes/nautilus-notes.c
@@ -54,22 +54,68 @@
#define NOTES_DEFAULT_BACKGROUND_COLOR "rgb:FFFF/FFFF/BBBB"
-
typedef struct {
- NautilusView *view;
- GtkWidget *note_text_field;
- char *uri;
- NautilusFile *file;
- guint save_timeout_id;
- char* previous_saved_text;
+ NautilusView *view;
+ BonoboPropertyBag *property_bag;
+ GtkWidget *note_text_field;
+ char *uri;
+ NautilusFile *file;
+ guint save_timeout_id;
+ char* previous_saved_text;
} Notes;
-static void notes_save_metainfo (Notes *notes);
+static void notes_save_metainfo (Notes *notes);
+static char* notes_get_indicator_image (const char *notes_text);
+static void notify_listeners_if_changed (Notes *notes, char *new_notes);
static int notes_object_count = 0;
#define SAVE_TIMEOUT (3 * 1000)
+/* property bag getting and setting routines */
+enum {
+ TAB_IMAGE,
+} MyArgs;
+
+static void
+get_bonobo_properties (BonoboPropertyBag *bag,
+ BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ char *indicator_image;
+ Notes *notes;
+ notes = (Notes*) user_data;
+
+ switch (arg_id) {
+
+ case TAB_IMAGE:
+ {
+ /* if there is a note, return the name of the indicator image,
+ otherwise, return NULL */
+ indicator_image = notes_get_indicator_image (notes->previous_saved_text);
+ BONOBO_ARG_SET_STRING (arg, indicator_image);
+ g_free (indicator_image);
+ break;
+ }
+
+ default:
+ g_warning ("Unhandled arg %d", arg_id);
+ break;
+ }
+}
+
+static void
+set_bonobo_properties (BonoboPropertyBag *bag,
+ const BonoboArg *arg,
+ guint arg_id,
+ CORBA_Environment *ev,
+ gpointer user_data)
+{
+ g_warning ("Cant set note property %d", arg_id);
+}
+
static gboolean
schedule_save_callback (gpointer data)
{
@@ -119,6 +165,9 @@ load_note_text_from_metadata (NautilusFile *file,
* metadata has actually changed.
*/
if (nautilus_strcmp (saved_text, notes->previous_saved_text) != 0) {
+
+ notify_listeners_if_changed (notes, saved_text);
+
g_free (notes->previous_saved_text);
notes->previous_saved_text = saved_text;
cancel_pending_save (notes);
@@ -146,8 +195,6 @@ static void
done_with_file (Notes *notes)
{
cancel_pending_save (notes);
- g_free (notes->previous_saved_text);
- notes->previous_saved_text = NULL;
if (notes->file != NULL) {
nautilus_file_monitor_remove (notes->file, notes);
@@ -163,13 +210,13 @@ notes_load_metainfo (Notes *notes)
{
GList *attributes;
- gtk_editable_delete_text (GTK_EDITABLE (notes->note_text_field), 0, -1);
-
done_with_file (notes);
notes->file = nautilus_file_get (notes->uri);
+ gtk_editable_delete_text (GTK_EDITABLE (notes->note_text_field), 0, -1);
+
if (notes->file == NULL) {
- return;
+ return;
}
attributes = g_list_append (NULL, NAUTILUS_FILE_ATTRIBUTE_METADATA);
@@ -187,8 +234,28 @@ notes_load_metainfo (Notes *notes)
notes);
}
-/* save the metainfo corresponding to the current uri, if any, into the text field */
+/* utility to notify event listeners if the notes data actually changed */
+static void
+notify_listeners_if_changed (Notes *notes, char *new_notes)
+{
+ char *tab_image;
+ BonoboArg *tab_image_arg;
+
+ if (nautilus_strcmp (notes->previous_saved_text, new_notes) != 0) {
+ /* notify listeners that the notes text has changed */
+ tab_image = notes_get_indicator_image (new_notes);
+
+ tab_image_arg = bonobo_arg_new (BONOBO_ARG_STRING);
+ BONOBO_ARG_SET_STRING (tab_image_arg, tab_image);
+
+ bonobo_property_bag_notify_listeners (notes->property_bag, "tab_image", tab_image_arg, NULL);
+
+ bonobo_arg_release (tab_image_arg);
+ g_free (tab_image);
+ }
+}
+/* save the metainfo corresponding to the current uri, if any, into the text field */
static void
notes_save_metainfo (Notes *notes)
{
@@ -208,12 +275,15 @@ notes_save_metainfo (Notes *notes)
notes_text = gtk_editable_get_chars (GTK_EDITABLE (notes->note_text_field), 0 , -1);
nautilus_file_set_metadata (notes->file, NAUTILUS_METADATA_KEY_ANNOTATION, NULL, notes_text);
- g_free (notes->previous_saved_text);
- notes->previous_saved_text = notes_text;
-
+
gtk_signal_handler_unblock_by_func (GTK_OBJECT (notes->file),
load_note_text_from_metadata,
- notes);
+ notes);
+
+ notify_listeners_if_changed (notes, notes_text);
+
+ g_free (notes->previous_saved_text);
+ notes->previous_saved_text = notes_text;
}
static void
@@ -268,6 +338,7 @@ do_destroy (GtkObject *obj, Notes *notes)
done_with_file (notes);
g_free (notes->uri);
+ g_free (notes->previous_saved_text);
g_free (notes);
notes_object_count--;
@@ -276,6 +347,16 @@ do_destroy (GtkObject *obj, Notes *notes)
}
}
+static char*
+notes_get_indicator_image (const char *notes_text)
+{
+ if (notes_text != NULL && strlen (notes_text) > 0) {
+ return g_strdup ("note-indicator.png");
+ }
+
+ return NULL;
+}
+
static BonoboObject *
make_notes_view (BonoboGenericFactory *Factory, const char *goad_id, gpointer closure)
{
@@ -316,6 +397,12 @@ make_notes_view (BonoboGenericFactory *Factory, const char *goad_id, gpointer cl
notes->view = nautilus_view_new (vbox);
gtk_signal_connect (GTK_OBJECT (notes->view), "destroy", do_destroy, notes);
+ /* allocate a property bag to reflect the TAB_IMAGE property */
+ notes->property_bag = bonobo_property_bag_new (get_bonobo_properties, set_bonobo_properties, notes);
+ bonobo_control_set_properties (nautilus_view_get_bonobo_control (notes->view), notes->property_bag);
+
+ bonobo_property_bag_add (notes->property_bag, "tab_image", TAB_IMAGE, BONOBO_ARG_STRING, NULL,
+ "image indicating that a note is present", 0);
notes_object_count++;
/* handle events */
diff --git a/icons/Makefile.am b/icons/Makefile.am
index 34002d4fa..bb9ad804d 100644
--- a/icons/Makefile.am
+++ b/icons/Makefile.am
@@ -227,6 +227,7 @@ icon_DATA =\
nautilus-mini-logo.png \
netscape.png \
not.png \
+ note-indicator.png \
novice-selected.png \
novice.png \
number_strip.png \
diff --git a/icons/note-indicator.png b/icons/note-indicator.png
new file mode 100644
index 000000000..f8b97567f
--- /dev/null
+++ b/icons/note-indicator.png
Binary files differ
diff --git a/src/nautilus-information-panel.c b/src/nautilus-information-panel.c
index 159301b46..3a302bedd 100644
--- a/src/nautilus-information-panel.c
+++ b/src/nautilus-information-panel.c
@@ -850,6 +850,15 @@ nautilus_sidebar_drag_data_received (GtkWidget *widget, GdkDragContext *context,
}
}
+static void
+view_loaded_callback (NautilusViewFrame *view_frame, gpointer user_data)
+{
+ NautilusSidebar *sidebar;
+
+ sidebar = NAUTILUS_SIDEBAR (user_data);
+ nautilus_sidebar_tabs_connect_view (sidebar->details->sidebar_tabs, GTK_WIDGET (view_frame));
+}
+
/* add a new panel to the sidebar */
void
nautilus_sidebar_add_panel (NautilusSidebar *sidebar, NautilusViewFrame *panel)
@@ -867,6 +876,8 @@ nautilus_sidebar_add_panel (NautilusSidebar *sidebar, NautilusViewFrame *panel)
gtk_widget_show (label);
+ gtk_signal_connect (GTK_OBJECT (panel), "view_loaded", view_loaded_callback, sidebar);
+
gtk_notebook_append_page (GTK_NOTEBOOK (sidebar->details->notebook),
GTK_WIDGET (panel), label);
page_num = gtk_notebook_page_num (GTK_NOTEBOOK (sidebar->details->notebook),
diff --git a/src/nautilus-sidebar-tabs.c b/src/nautilus-sidebar-tabs.c
index 0d8ea539c..3ade8eb41 100644
--- a/src/nautilus-sidebar-tabs.c
+++ b/src/nautilus-sidebar-tabs.c
@@ -24,6 +24,13 @@
#include <config.h>
#include "nautilus-sidebar-tabs.h"
+#include "nautilus-view-frame.h"
+
+#include <bonobo/bonobo-event-source.h>
+#include <bonobo/bonobo-listener.h>
+#include <bonobo/bonobo-property-bag-client.h>
+#include <bonobo/bonobo-ui-util.h>
+#include <bonobo/bonobo-exception.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libgnome/gnome-defs.h>
@@ -75,7 +82,10 @@ typedef struct {
gboolean visible;
gboolean prelit;
char *tab_text;
+ char *indicator_pixbuf_name;
+ GdkPixbuf *indicator_pixbuf;
int notebook_page;
+ Bonobo_EventSource_ListenerId listener_id;
GtkWidget *tab_view;
GdkRectangle tab_rect;
} TabItem;
@@ -314,7 +324,31 @@ nautilus_sidebar_tabs_new (void)
static void
tab_item_destroy (TabItem *item)
{
+ CORBA_Environment ev;
+ Bonobo_PropertyBag property_bag;
+ Bonobo_Control control;
+
g_free (item->tab_text);
+ g_free (item->indicator_pixbuf_name);
+
+ if (item->indicator_pixbuf != NULL) {
+ gdk_pixbuf_unref (item->indicator_pixbuf);
+ }
+
+ if (item->listener_id != 0) {
+ CORBA_exception_init (&ev);
+ control = nautilus_view_frame_get_control (NAUTILUS_VIEW_FRAME (item->tab_view));
+ if (control != NULL) {
+ property_bag = Bonobo_Control_getProperties (control, &ev);
+ if (!BONOBO_EX (&ev) && property_bag != CORBA_OBJECT_NIL) {
+ bonobo_event_source_client_remove_listener
+ (property_bag,
+ item->listener_id,
+ &ev);
+ bonobo_object_release_unref (property_bag, &ev);
+ }
+ }
+ }
g_free (item);
}
@@ -509,13 +543,41 @@ nautilus_sidebar_tabs_size_allocate(GtkWidget *widget, GtkAllocation *allocation
}
}
+/* convenience routine to composite an image with the proper clipping */
+static void
+pixbuf_composite (GdkPixbuf *source, GdkPixbuf *destination, int x_offset, int y_offset, int alpha)
+{
+ int source_width, source_height, dest_width, dest_height;
+ double float_x_offset, float_y_offset;
+
+ source_width = gdk_pixbuf_get_width (source);
+ source_height = gdk_pixbuf_get_height (source);
+ dest_width = gdk_pixbuf_get_width (destination);
+ dest_height = gdk_pixbuf_get_height (destination);
+
+ float_x_offset = x_offset;
+ float_y_offset = y_offset;
+
+ /* clip to the destination size */
+ if ((x_offset + source_width) > dest_width) {
+ source_width = dest_width - x_offset;
+ }
+ if ((y_offset + source_height) > dest_height) {
+ source_height = dest_height - y_offset;
+ }
+
+ gdk_pixbuf_composite (source, destination, x_offset, y_offset, source_width, source_height,
+ float_x_offset, float_y_offset, 1.0, 1.0, GDK_PIXBUF_ALPHA_BILEVEL, alpha);
+}
+
/* draw a single tab using the default, non-themed approach */
static int
-draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
- char *tab_name, int x, int y, gboolean prelight_flag, GdkRectangle *tab_rect)
+draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc, char *tab_name,
+ GdkPixbuf *indicator_pixbuf, int x, int y, gboolean prelight_flag, GdkRectangle *tab_rect)
{
int tab_bottom;
int tab_right;
+ int indicator_width;
NautilusDimensions name_dimensions;
int total_width;
GtkWidget *widget;
@@ -524,13 +586,19 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
g_assert (NAUTILUS_IS_SIDEBAR_TABS (sidebar_tabs));
+ if (indicator_pixbuf != NULL) {
+ indicator_width = gdk_pixbuf_get_width (indicator_pixbuf);
+ } else {
+ indicator_width = 0;
+ }
+
/* measure the name and compute the bounding box */
name_dimensions = nautilus_scalable_font_measure_text (sidebar_tabs->details->tab_font,
sidebar_tabs->details->font_size,
tab_name,
strlen (tab_name));
- total_width = name_dimensions.width + 2 * TAB_MARGIN;
+ total_width = name_dimensions.width + indicator_width + 2 * TAB_MARGIN;
widget = GTK_WIDGET (sidebar_tabs);
@@ -565,12 +633,17 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
gdk_draw_line(widget->window, gc, x + 2, y + 2, x + 2, y + sidebar_tabs->details->tab_height - 1);
/* allocate the pixbuf and fill it with the background color */
- temp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, name_dimensions.width + 1, name_dimensions.height + 1);
+ temp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, name_dimensions.width + indicator_width + 1, name_dimensions.height + 1);
nautilus_gdk_pixbuf_fill_rectangle_with_color (temp_pixbuf, NULL, nautilus_gdk_color_to_rgb (foreground_color));
+
+ /* draw the indicator if necessary */
+ if (indicator_pixbuf) {
+ pixbuf_composite (indicator_pixbuf, temp_pixbuf, 0, 0, 255);
+ }
/* draw the name into the pixbuf using anti-aliased text */
nautilus_scalable_font_draw_text (sidebar_tabs->details->tab_font, temp_pixbuf,
- 1, 1,
+ 1 + indicator_width, 1,
NULL,
sidebar_tabs->details->font_size,
tab_name, strlen (tab_name),
@@ -578,7 +651,7 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
NAUTILUS_OPACITY_FULLY_OPAQUE);
nautilus_scalable_font_draw_text (sidebar_tabs->details->tab_font, temp_pixbuf,
- 0, 0,
+ indicator_width, 0,
NULL,
sidebar_tabs->details->font_size,
tab_name, strlen (tab_name),
@@ -591,7 +664,7 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
widget->window,
0, 0,
x + TAB_MARGIN, y + 5,
- name_dimensions.width + 1, name_dimensions.height + 1,
+ name_dimensions.width + indicator_width + 1, name_dimensions.height + 1,
GDK_PIXBUF_ALPHA_BILEVEL, 128,
GDK_RGB_DITHER_MAX,
0, 0);
@@ -601,12 +674,12 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
/* draw the bottom lines */
tab_bottom = y + sidebar_tabs->details->tab_height - 1;
gdk_gc_set_foreground (gc, &sidebar_tabs->details->line_color);
- tab_right = x + 2*TAB_MARGIN + name_dimensions.width;
+ tab_right = x + 2*TAB_MARGIN + name_dimensions.width + indicator_width;
gdk_gc_set_foreground (gc, &sidebar_tabs->details->line_color);
gdk_draw_line(widget->window, gc, tab_right, tab_bottom, widget->parent->allocation.width, tab_bottom);
gdk_draw_line(widget->window, gc, 0, tab_bottom, x, tab_bottom);
- return name_dimensions.width + 2 * TAB_MARGIN;
+ return name_dimensions.width + indicator_width + 2 * TAB_MARGIN;
}
/* utility to draw a single tab piece into a pixbuf */
@@ -668,7 +741,7 @@ draw_tab_piece_aa (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *dest_pixbuf, in
draw the right edge of the tab, as we don't have enough info about the next tab
to do it properly at this time. We draw into an offscreen pixbuf so we can get nice anti-aliased text */
static int
-draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *tab_pixbuf,
+draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *tab_pixbuf, GdkPixbuf *indicator_pixbuf,
char *tab_name, int x, int y, gboolean prelight_flag,
gboolean first_flag, gboolean prev_invisible, int text_h_offset,
GdkRectangle *tab_rect)
@@ -681,6 +754,13 @@ draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *tab_pixbuf,
int highlight_offset;
int text_x;
int text_y;
+ int indicator_width;
+
+ if (indicator_pixbuf != NULL) {
+ indicator_width = gdk_pixbuf_get_width (indicator_pixbuf);
+ } else {
+ indicator_width = 0;
+ }
left_width = 0;
@@ -708,7 +788,7 @@ draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *tab_pixbuf,
/* draw the middle portion in a loop */
text_x_pos = current_pos;
- right_edge_pos = current_pos + name_dimensions.width;
+ right_edge_pos = current_pos + name_dimensions.width + indicator_width;
while (current_pos < right_edge_pos) {
piece_width = draw_tab_piece_aa (sidebar_tabs, tab_pixbuf, current_pos, y - widget->allocation.y,
right_edge_pos, TAB_NORMAL_FILL + highlight_offset);
@@ -724,6 +804,12 @@ draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *tab_pixbuf,
/* make sure we can at least draw some of it */
if (text_x < gdk_pixbuf_get_width (tab_pixbuf)) {
+ if (indicator_pixbuf) {
+
+ pixbuf_composite (indicator_pixbuf, tab_pixbuf, text_x, text_y, 255);
+ text_x += indicator_width;
+ }
+
nautilus_scalable_font_draw_text (sidebar_tabs->details->tab_font, tab_pixbuf,
text_x, text_y,
NULL,
@@ -747,12 +833,12 @@ draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *tab_pixbuf,
if (tab_rect) {
tab_rect->x = x;
tab_rect->y = y;
- tab_rect->width = current_pos - x;
+ tab_rect->width = current_pos - x + indicator_width;
tab_rect->height = sidebar_tabs->details->tab_height;
}
/* return the total tab width */
- tab_width = left_width + name_dimensions.width;
+ tab_width = left_width + name_dimensions.width + indicator_width;
return tab_width;
}
@@ -777,12 +863,18 @@ get_text_offset (void)
static int
get_tab_width (NautilusSidebarTabs *sidebar_tabs, TabItem *this_tab, gboolean is_themed, gboolean first_flag)
{
- int edge_width;
+ int edge_width, indicator_width;
NautilusDimensions name_dimensions;
if (this_tab == NULL)
return 0;
+ if (this_tab->indicator_pixbuf != NULL) {
+ indicator_width = gdk_pixbuf_get_width (this_tab->indicator_pixbuf);
+ } else {
+ indicator_width = 0;
+ }
+
if (is_themed) {
if (first_flag) {
edge_width = gdk_pixbuf_get_width (sidebar_tabs->details->tab_piece_images[TAB_NORMAL_LEFT]);
@@ -799,7 +891,7 @@ get_tab_width (NautilusSidebarTabs *sidebar_tabs, TabItem *this_tab, gboolean is
edge_width = 2 * TAB_MARGIN;
name_dimensions.width = gdk_string_width (GTK_WIDGET (sidebar_tabs)->style->font, this_tab->tab_text);
}
- return name_dimensions.width + edge_width;
+ return name_dimensions.width + edge_width + indicator_width;
}
/* fill the canvas buffer with a tiled pixmap */
@@ -955,12 +1047,12 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
prev_invisible = prev_item && !prev_item->visible;
if (is_themed) {
g_assert (tab_pixbuf != NULL);
- draw_one_tab_themed (sidebar_tabs, tab_pixbuf, this_item->tab_text, x_pos, y_pos,
+ draw_one_tab_themed (sidebar_tabs, tab_pixbuf, this_item->indicator_pixbuf, this_item->tab_text, x_pos, y_pos,
this_item->prelit, first_flag, prev_invisible,
text_h_offset, &this_item->tab_rect);
} else {
g_assert (temp_gc != NULL);
- draw_one_tab_plain (sidebar_tabs, temp_gc, this_item->tab_text,
+ draw_one_tab_plain (sidebar_tabs, temp_gc, this_item->tab_text, this_item->indicator_pixbuf,
x_pos, y_pos, this_item->prelit, &this_item->tab_rect);
}
}
@@ -1176,7 +1268,7 @@ nautilus_sidebar_tabs_expose (GtkWidget *widget, GdkEventExpose *event)
tab_height = gdk_pixbuf_get_height (sidebar_tabs->details->tab_piece_images[0]);
pixbuf = allocate_cleared_pixbuf (widget->allocation.width, tab_height);
- tab_width = draw_one_tab_themed (sidebar_tabs, pixbuf, sidebar_tabs->details->title, 0, 0,
+ tab_width = draw_one_tab_themed (sidebar_tabs, pixbuf, NULL, sidebar_tabs->details->title, 0, 0,
sidebar_tabs->details->title_prelit, TRUE, FALSE, text_offset, &sidebar_tabs->details->title_rect);
/* draw the right edge */
draw_tab_piece_aa (sidebar_tabs, pixbuf, tab_width, 0, -1,
@@ -1194,7 +1286,7 @@ nautilus_sidebar_tabs_expose (GtkWidget *widget, GdkEventExpose *event)
gdk_pixbuf_unref (pixbuf);
} else {
- draw_one_tab_plain (sidebar_tabs, temp_gc, sidebar_tabs->details->title,
+ draw_one_tab_plain (sidebar_tabs, temp_gc, sidebar_tabs->details->title, NULL,
x_pos + TITLE_TAB_OFFSET, y_pos, sidebar_tabs->details->title_prelit, &sidebar_tabs->details->title_rect);
}
gdk_gc_unref (temp_gc);
@@ -1208,6 +1300,137 @@ nautilus_sidebar_tabs_expose (GtkWidget *widget, GdkEventExpose *event)
return FALSE;
}
+/* update the indicator image for the passed in tab */
+static void
+nautilus_sidebar_tabs_update_tab_item (NautilusSidebarTabs *sidebar_tabs, TabItem *tab_item)
+{
+ CORBA_Environment ev;
+ Bonobo_Control control;
+ Bonobo_PropertyBag property_bag;
+ char *tab_image_name, *image_path;
+
+ /* fetch indicator icon through the bonobo propertybag mechanism */
+ CORBA_exception_init (&ev);
+ control = nautilus_view_frame_get_control (NAUTILUS_VIEW_FRAME (tab_item->tab_view));
+ if (control != NULL) {
+ property_bag = Bonobo_Control_getProperties (control, &ev);
+ if (property_bag != NULL) {
+ tab_image_name = bonobo_property_bag_client_get_value_string (property_bag, "tab_image", &ev);
+ bonobo_object_release_unref (property_bag, &ev);
+
+ /* see if the indicator icon changed; if so, fetch the new one */
+ if (nautilus_strcmp (tab_image_name, tab_item->indicator_pixbuf_name) != 0) {
+ g_free (tab_item->indicator_pixbuf_name);
+
+ if (tab_item->indicator_pixbuf != NULL) {
+ gdk_pixbuf_unref (tab_item->indicator_pixbuf);
+ tab_item->indicator_pixbuf = NULL;
+ }
+
+ if (tab_image_name != NULL) {
+ tab_item->indicator_pixbuf_name = g_strdup (tab_image_name);
+ image_path = nautilus_theme_get_image_path (tab_image_name);
+ if (image_path != NULL) {
+ tab_item->indicator_pixbuf = gdk_pixbuf_new_from_file (image_path);
+ g_free (image_path);
+ }
+ } else {
+ tab_item->indicator_pixbuf_name = NULL;
+ if (tab_item->indicator_pixbuf != NULL) {
+ gdk_pixbuf_unref (tab_item->indicator_pixbuf);
+ tab_item->indicator_pixbuf = NULL;
+ }
+ }
+
+ recalculate_size (sidebar_tabs);
+ gtk_widget_queue_draw (GTK_WIDGET (sidebar_tabs));
+ }
+ g_free (tab_image_name);
+ }
+ }
+ CORBA_exception_free (&ev);
+
+}
+
+static TabItem *
+get_tab_item_from_view (NautilusSidebarTabs *sidebar_tabs, GtkWidget *view)
+{
+ GList *iterator;
+
+ for (iterator = sidebar_tabs->details->tab_items; iterator != NULL; iterator = iterator->next) {
+ TabItem *tab_item = iterator->data;
+ if (tab_item->tab_view == view) {
+ return tab_item;
+ }
+ }
+ return NULL;
+}
+
+/* check all of the tabs to see if their indicator pixmaps are ready for updating */
+static void
+nautilus_sidebar_tabs_update_all_indicators (NautilusSidebarTabs *sidebar_tabs)
+{
+ GList *iterator;
+
+ for (iterator = sidebar_tabs->details->tab_items; iterator != NULL; iterator = iterator->next) {
+ TabItem *tab_item = iterator->data;
+ nautilus_sidebar_tabs_update_tab_item (sidebar_tabs, tab_item);
+ }
+}
+
+/* check all of the tabs to see if their indicator pixmaps are ready for updating */
+static void
+nautilus_sidebar_tabs_update_indicator (NautilusSidebarTabs *sidebar_tabs, GtkWidget *view)
+{
+ GList *iterator;
+
+ for (iterator = sidebar_tabs->details->tab_items; iterator != NULL; iterator = iterator->next) {
+ TabItem *tab_item = iterator->data;
+ if (tab_item->tab_view == view) {
+ nautilus_sidebar_tabs_update_tab_item (sidebar_tabs, tab_item);
+ break;
+ }
+ }
+}
+
+static void
+tab_indicator_changed_callback (BonoboListener *listener,
+ char *event_name,
+ CORBA_any *arg,
+ CORBA_Environment *ev,
+ gpointer callback_data)
+{
+ NautilusSidebarTabs *sidebar_tabs;
+ sidebar_tabs = NAUTILUS_SIDEBAR_TABS (callback_data);
+ nautilus_sidebar_tabs_update_all_indicators (sidebar_tabs);
+}
+
+/* listen for changes on the tab_image property */
+void
+nautilus_sidebar_tabs_connect_view (NautilusSidebarTabs *sidebar_tabs, GtkWidget *view)
+{
+ CORBA_Environment ev;
+ Bonobo_PropertyBag property_bag;
+ TabItem *tab_item;
+
+ tab_item = get_tab_item_from_view (sidebar_tabs, view);
+ if (tab_item == NULL) {
+ return;
+ }
+
+ CORBA_exception_init (&ev);
+ property_bag = Bonobo_Control_getProperties (nautilus_view_frame_get_control (NAUTILUS_VIEW_FRAME (view)), &ev);
+ if (!BONOBO_EX (&ev) && property_bag != CORBA_OBJECT_NIL) {
+ tab_item->listener_id = bonobo_event_source_client_add_listener
+ (property_bag, tab_indicator_changed_callback,
+ "Bonobo/Property:change:tab_image", NULL, sidebar_tabs);
+ bonobo_object_release_unref (property_bag, &ev);
+ }
+ CORBA_exception_free (&ev);
+
+ nautilus_sidebar_tabs_update_indicator (sidebar_tabs, view);
+}
+
/* add a new tab entry, return TRUE if we succeed */
gboolean
diff --git a/src/nautilus-sidebar-tabs.h b/src/nautilus-sidebar-tabs.h
index 89731434b..a15b8f14c 100644
--- a/src/nautilus-sidebar-tabs.h
+++ b/src/nautilus-sidebar-tabs.h
@@ -57,6 +57,9 @@ gboolean nautilus_sidebar_tabs_add_view (NautilusSidebarTabs *sid
const char *name,
GtkWidget *new_view,
int page_number);
+void nautilus_sidebar_tabs_connect_view (NautilusSidebarTabs *sidebar_tabs,
+ GtkWidget *view);
+
char * nautilus_sidebar_tabs_get_title_from_index (NautilusSidebarTabs *sidebar_tabs,
int which_tab);
int nautilus_sidebar_tabs_hit_test (NautilusSidebarTabs *sidebar_tabs,
diff --git a/src/nautilus-sidebar.c b/src/nautilus-sidebar.c
index 159301b46..3a302bedd 100644
--- a/src/nautilus-sidebar.c
+++ b/src/nautilus-sidebar.c
@@ -850,6 +850,15 @@ nautilus_sidebar_drag_data_received (GtkWidget *widget, GdkDragContext *context,
}
}
+static void
+view_loaded_callback (NautilusViewFrame *view_frame, gpointer user_data)
+{
+ NautilusSidebar *sidebar;
+
+ sidebar = NAUTILUS_SIDEBAR (user_data);
+ nautilus_sidebar_tabs_connect_view (sidebar->details->sidebar_tabs, GTK_WIDGET (view_frame));
+}
+
/* add a new panel to the sidebar */
void
nautilus_sidebar_add_panel (NautilusSidebar *sidebar, NautilusViewFrame *panel)
@@ -867,6 +876,8 @@ nautilus_sidebar_add_panel (NautilusSidebar *sidebar, NautilusViewFrame *panel)
gtk_widget_show (label);
+ gtk_signal_connect (GTK_OBJECT (panel), "view_loaded", view_loaded_callback, sidebar);
+
gtk_notebook_append_page (GTK_NOTEBOOK (sidebar->details->notebook),
GTK_WIDGET (panel), label);
page_num = gtk_notebook_page_num (GTK_NOTEBOOK (sidebar->details->notebook),
diff --git a/src/nautilus-view-frame.c b/src/nautilus-view-frame.c
index 209ca3a66..4b67123c0 100644
--- a/src/nautilus-view-frame.c
+++ b/src/nautilus-view-frame.c
@@ -1271,6 +1271,17 @@ nautilus_view_frame_report_load_failed (NautilusViewFrame *view)
view_frame_failed (view);
}
+/* return the Bonobo_Control CORBA object associated with the view frame */
+Bonobo_Control
+nautilus_view_frame_get_control (NautilusViewFrame *view)
+{
+ if (view->details->control_frame == NULL) {
+ return NULL;
+ }
+
+ return bonobo_control_frame_get_control (view->details->control_frame);
+}
+
void
nautilus_view_frame_go_back (NautilusViewFrame *view)
{
diff --git a/src/nautilus-view-frame.h b/src/nautilus-view-frame.h
index 45ef8328f..14e49047a 100644
--- a/src/nautilus-view-frame.h
+++ b/src/nautilus-view-frame.h
@@ -99,6 +99,7 @@ typedef struct {
GtkType nautilus_view_frame_get_type (void);
NautilusViewFrame *nautilus_view_frame_new (BonoboUIContainer *ui_container,
NautilusUndoManager *undo_manager);
+Bonobo_Control nautilus_view_frame_get_control (NautilusViewFrame *view);
/* connecting to a Nautilus:View */
void nautilus_view_frame_load_view (NautilusViewFrame *view,