summaryrefslogtreecommitdiff
path: root/libnautilus-private
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2006-04-18 16:54:31 +0000
committerAlexander Larsson <alexl@src.gnome.org>2006-04-18 16:54:31 +0000
commitd870f63ebfb717a7b9db22957568965932f02d89 (patch)
tree7292405ed96da153d74d6f2cda0544f0fd151e2d /libnautilus-private
parentdc98244d6ad94e6a3388f5ae9a35f8c62b965d22 (diff)
downloadnautilus-d870f63ebfb717a7b9db22957568965932f02d89.tar.gz
Add LARGE_TOP_LEFT_TEXT attribute and change the text size for the normal
2006-04-18 Alexander Larsson <alexl@redhat.com> * libnautilus-private/nautilus-file-attributes.h: * libnautilus-private/nautilus-directory-async.c: * libnautilus-private/nautilus-directory-private.h: * libnautilus-private/nautilus-file-private.h: * libnautilus-private/nautilus-file.c: * libnautilus-private/nautilus-file.h: Add LARGE_TOP_LEFT_TEXT attribute and change the text size for the normal top-left text to 10x5. Add need_large argument to nautilus_file_peek_top_left_text and nautilus_extract_top_left_text. * libnautilus-private/nautilus-icon-canvas-item.[ch] Make details an instance-private instead of allocating separately. Add _set_is_visible() and only keep PangoLayouts cached for visible icons. * libnautilus-private/nautilus-icon-container.[ch]: * src/file-manager/fm-icon-container.c: Monitor large embedded text for larger icons. Call nautilus_icon_canvas_item_set_is_visible as needed. * libnautilus-private/nautilus-icon-factory.[ch]: Limit never-free recently used cache to 20 items. Free other unused cache items after a 100 sec.
Diffstat (limited to 'libnautilus-private')
-rw-r--r--libnautilus-private/nautilus-directory-async.c73
-rw-r--r--libnautilus-private/nautilus-directory-private.h1
-rw-r--r--libnautilus-private/nautilus-file-attributes.h9
-rw-r--r--libnautilus-private/nautilus-file-private.h12
-rw-r--r--libnautilus-private/nautilus-file.c29
-rw-r--r--libnautilus-private/nautilus-file.h1
-rw-r--r--libnautilus-private/nautilus-icon-canvas-item.c171
-rw-r--r--libnautilus-private/nautilus-icon-canvas-item.h2
-rw-r--r--libnautilus-private/nautilus-icon-container.c54
-rw-r--r--libnautilus-private/nautilus-icon-container.h4
-rw-r--r--libnautilus-private/nautilus-icon-factory.c19
-rw-r--r--libnautilus-private/nautilus-icon-private.h3
12 files changed, 282 insertions, 96 deletions
diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c
index e633fbf1a..d85be1eca 100644
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -67,6 +67,7 @@
#define MAX_ASYNC_JOBS 10
struct TopLeftTextReadState {
+ gboolean large;
NautilusFile *file;
EelReadFileHandle *handle;
};
@@ -534,6 +535,11 @@ nautilus_directory_set_up_request (Request *request,
request->file_info = TRUE;
}
+ if (file_attributes & NAUTILUS_FILE_ATTRIBUTE_LARGE_TOP_LEFT_TEXT) {
+ request->large_top_left_text = TRUE;
+ request->file_info = TRUE;
+ }
+
if (file_attributes & NAUTILUS_FILE_ATTRIBUTE_ACTIVATION_URI) {
request->file_info = TRUE;
request->link_info = TRUE;
@@ -1616,6 +1622,21 @@ wants_top_left (const Request *request)
}
static gboolean
+lacks_large_top_left (NautilusFile *file)
+{
+ return file->details->file_info_is_up_to_date &&
+ (!file->details->top_left_text_is_up_to_date ||
+ file->details->got_large_top_left_text != file->details->got_top_left_text)
+ && nautilus_file_should_get_top_left_text (file);
+}
+
+static gboolean
+wants_large_top_left (const Request *request)
+{
+ return request->large_top_left_text;
+}
+
+static gboolean
lacks_info (NautilusFile *file)
{
return !file->details->file_info_is_up_to_date
@@ -1768,6 +1789,12 @@ request_is_satisfied (NautilusDirectory *directory,
return FALSE;
}
}
+
+ if (request->large_top_left_text) {
+ if (has_problem (directory, file, lacks_large_top_left)) {
+ return FALSE;
+ }
+ }
if (request->deep_count) {
if (has_problem (directory, file, lacks_deep_count)) {
@@ -2598,11 +2625,13 @@ top_left_read_callback (GnomeVFSResult result,
file_details->top_left_text_is_up_to_date = TRUE;
g_free (file_details->top_left_text);
if (result == GNOME_VFS_OK) {
- file_details->top_left_text = nautilus_extract_top_left_text (file_contents, bytes_read);
+ file_details->top_left_text = nautilus_extract_top_left_text (file_contents, directory->details->top_left_read_state->large, bytes_read);
file_details->got_top_left_text = TRUE;
+ file_details->got_large_top_left_text = directory->details->top_left_read_state->large;
} else {
file_details->top_left_text = NULL;
file_details->got_top_left_text = FALSE;
+ file_details->got_large_top_left_text = FALSE;
}
g_free (file_contents);
@@ -2617,11 +2646,20 @@ top_left_read_more_callback (GnomeVFSFileSize bytes_read,
const char *file_contents,
gpointer callback_data)
{
- g_assert (NAUTILUS_IS_DIRECTORY (callback_data));
+ NautilusDirectory *directory;
+
+ directory = NAUTILUS_DIRECTORY (callback_data);
+
/* Stop reading when we have enough. */
- return bytes_read < NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_BYTES
- && count_lines (file_contents, bytes_read) <= NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_LINES;
+ if (directory->details->top_left_read_state->large) {
+ return bytes_read < NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_BYTES
+ && count_lines (file_contents, bytes_read) <= NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_LINES;
+ } else {
+ return bytes_read < NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_BYTES
+ && count_lines (file_contents, bytes_read) <= NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_LINES;
+ }
+
}
static void
@@ -2636,7 +2674,10 @@ top_left_stop (NautilusDirectory *directory)
g_assert (file->details->directory == directory);
if (is_needy (file,
lacks_top_left,
- wants_top_left)) {
+ wants_top_left) ||
+ is_needy (file,
+ lacks_large_top_left,
+ wants_large_top_left)) {
return;
}
}
@@ -2651,15 +2692,25 @@ top_left_start (NautilusDirectory *directory,
NautilusFile *file)
{
char *uri;
+ gboolean needs_large;
if (directory->details->top_left_read_state != NULL) {
return;
}
+
+ needs_large = FALSE;
+
+ if (is_needy (file,
+ lacks_large_top_left,
+ wants_large_top_left)) {
+ needs_large = TRUE;
+ }
/* Figure out which file to read the top left for. */
- if (!is_needy (file,
- lacks_top_left,
- wants_top_left)) {
+ if (!(needs_large ||
+ is_needy (file,
+ lacks_top_left,
+ wants_top_left))) {
return;
}
@@ -2667,6 +2718,7 @@ top_left_start (NautilusDirectory *directory,
g_free (file->details->top_left_text);
file->details->top_left_text = NULL;
file->details->got_top_left_text = FALSE;
+ file->details->got_large_top_left_text = FALSE;
file->details->top_left_text_is_up_to_date = TRUE;
nautilus_directory_async_state_changed (directory);
@@ -2679,6 +2731,7 @@ top_left_start (NautilusDirectory *directory,
/* Start reading. */
directory->details->top_left_read_state = g_new0 (TopLeftTextReadState, 1);
+ directory->details->top_left_read_state->large = needs_large;
directory->details->top_left_read_state->file = file;
uri = nautilus_file_get_uri (file);
directory->details->top_left_read_state->handle = eel_read_file_async
@@ -3479,6 +3532,10 @@ file_needs_low_priority_work_done (NautilusDirectory *directory,
return TRUE;
}
+ if (is_needy (file, lacks_large_top_left, wants_large_top_left)) {
+ return TRUE;
+ }
+
return FALSE;
}
diff --git a/libnautilus-private/nautilus-directory-private.h b/libnautilus-private/nautilus-directory-private.h
index 930084f93..e669e4793 100644
--- a/libnautilus-private/nautilus-directory-private.h
+++ b/libnautilus-private/nautilus-directory-private.h
@@ -130,6 +130,7 @@ typedef struct {
gboolean metafile;
gboolean mime_list;
gboolean top_left_text;
+ gboolean large_top_left_text;
gboolean extension_info;
gboolean slow_mime_type;
} Request;
diff --git a/libnautilus-private/nautilus-file-attributes.h b/libnautilus-private/nautilus-file-attributes.h
index fb5a14622..cdee9d1f7 100644
--- a/libnautilus-private/nautilus-file-attributes.h
+++ b/libnautilus-private/nautilus-file-attributes.h
@@ -41,10 +41,11 @@ typedef enum {
NAUTILUS_FILE_ATTRIBUTE_METADATA = 1 << 8,
NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE = 1 << 9,
NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT = 1 << 10,
- NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME = 1 << 11,
- NAUTILUS_FILE_ATTRIBUTE_VOLUMES = 1 << 12,
- NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO = 1 << 13,
- NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE = 1 << 14
+ NAUTILUS_FILE_ATTRIBUTE_LARGE_TOP_LEFT_TEXT = 1 << 11,
+ NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME = 1 << 12,
+ NAUTILUS_FILE_ATTRIBUTE_VOLUMES = 1 << 13,
+ NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO = 1 << 14,
+ NAUTILUS_FILE_ATTRIBUTE_SLOW_MIME_TYPE = 1 << 15
} NautilusFileAttributes;
#endif /* NAUTILUS_FILE_ATTRIBUTES_H */
diff --git a/libnautilus-private/nautilus-file-private.h b/libnautilus-private/nautilus-file-private.h
index 7faae5a85..1d1c46254 100644
--- a/libnautilus-private/nautilus-file-private.h
+++ b/libnautilus-private/nautilus-file-private.h
@@ -30,9 +30,13 @@
#include <libnautilus-private/nautilus-monitor.h>
#include <eel/eel-glib-extensions.h>
-#define NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_CHARACTERS_PER_LINE 80
-#define NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_LINES 24
-#define NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_BYTES 10000
+#define NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_CHARACTERS_PER_LINE 80
+#define NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_LINES 24
+#define NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_BYTES 10000
+
+#define NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_CHARACTERS_PER_LINE 10
+#define NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_LINES 5
+#define NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_BYTES 1024
/* These are in the typical sort order. Known things come first, then
* things where we can't know, finally things where we don't yet know.
@@ -135,6 +139,7 @@ struct NautilusFileDetails
eel_boolean_bit mime_list_is_up_to_date : 1;
eel_boolean_bit got_top_left_text : 1;
+ eel_boolean_bit got_large_top_left_text : 1;
eel_boolean_bit top_left_text_is_up_to_date : 1;
eel_boolean_bit got_link_info : 1;
@@ -156,6 +161,7 @@ void nautilus_file_mark_gone (NautilusFile
gboolean nautilus_file_info_missing (NautilusFile *file,
GnomeVFSFileInfoFields needed_mask);
char * nautilus_extract_top_left_text (const char *text,
+ gboolean large,
int length);
void nautilus_file_set_directory (NautilusFile *file,
NautilusDirectory *directory);
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index d296241ad..a370a1df6 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -5241,7 +5241,9 @@ nautilus_file_is_executable (NautilusFile *file)
*
**/
char *
-nautilus_file_peek_top_left_text (NautilusFile *file, gboolean *needs_loading)
+nautilus_file_peek_top_left_text (NautilusFile *file,
+ gboolean need_large_text,
+ gboolean *needs_loading)
{
g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
@@ -5254,6 +5256,9 @@ nautilus_file_peek_top_left_text (NautilusFile *file, gboolean *needs_loading)
if (needs_loading) {
*needs_loading = !file->details->top_left_text_is_up_to_date;
+ if (need_large_text) {
+ *needs_loading |= file->details->got_top_left_text != file->details->got_large_top_left_text;
+ }
}
/* Show " ..." in the file until we read the contents in. */
@@ -5281,7 +5286,7 @@ nautilus_file_peek_top_left_text (NautilusFile *file, gboolean *needs_loading)
char *
nautilus_file_get_top_left_text (NautilusFile *file)
{
- return g_strdup (nautilus_file_peek_top_left_text (file, NULL));
+ return g_strdup (nautilus_file_peek_top_left_text (file, FALSE, NULL));
}
@@ -5992,6 +5997,7 @@ try_to_make_utf8 (const char *text, int *length)
/* Extract the top left part of the read-in text. */
char *
nautilus_extract_top_left_text (const char *text,
+ gboolean large,
int length)
{
GString* buffer;
@@ -6002,13 +6008,26 @@ nautilus_extract_top_left_text (const char *text,
char *text_copy;
const char *utf8_end;
gboolean validated;
+ int max_bytes, max_lines, max_cols;
+
+ if (large) {
+ max_bytes = NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_BYTES;
+ max_lines = NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_LINES;
+ max_cols = NAUTILUS_FILE_LARGE_TOP_LEFT_TEXT_MAXIMUM_CHARACTERS_PER_LINE;
+ } else {
+ max_bytes = NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_BYTES;
+ max_lines = NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_LINES;
+ max_cols = NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_CHARACTERS_PER_LINE;
+ }
+
+
text_copy = NULL;
if (text != NULL) {
/* Might be a partial utf8 character at the end if we didn't read whole file */
validated = g_utf8_validate (text, length, &utf8_end);
if (!validated &&
- !(length >= NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_BYTES &&
+ !(length >= max_bytes &&
text + length - utf8_end < 6)) {
text_copy = try_to_make_utf8 (text, &length);
text = text_copy;
@@ -6024,9 +6043,9 @@ nautilus_extract_top_left_text (const char *text,
buffer = g_string_new ("");
end = text + length; in = text;
- for (line = 0; line < NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_LINES; line++) {
+ for (line = 0; line < max_lines; line++) {
/* Extract one line. */
- for (i = 0; i < NAUTILUS_FILE_TOP_LEFT_TEXT_MAXIMUM_CHARACTERS_PER_LINE; ) {
+ for (i = 0; i < max_cols; ) {
if (*in == '\n') {
break;
}
diff --git a/libnautilus-private/nautilus-file.h b/libnautilus-private/nautilus-file.h
index af71a796e..e80d94e6b 100644
--- a/libnautilus-private/nautilus-file.h
+++ b/libnautilus-private/nautilus-file.h
@@ -180,6 +180,7 @@ void nautilus_file_set_keywords (Nautilu
GList * nautilus_file_get_emblem_names (NautilusFile *file);
char * nautilus_file_get_top_left_text (NautilusFile *file);
char * nautilus_file_peek_top_left_text (NautilusFile *file,
+ gboolean need_large_text,
gboolean *got_top_left_text);
gboolean nautilus_file_get_directory_item_mime_types (NautilusFile *file,
GList **mime_list);
diff --git a/libnautilus-private/nautilus-icon-canvas-item.c b/libnautilus-private/nautilus-icon-canvas-item.c
index bb6493d88..13f4bf460 100644
--- a/libnautilus-private/nautilus-icon-canvas-item.c
+++ b/libnautilus-private/nautilus-icon-canvas-item.c
@@ -103,10 +103,14 @@ struct NautilusIconCanvasItemDetails {
guint bounds_cached : 1;
+ guint is_visible : 1;
+
+ GdkRectangle embedded_text_rect;
+ char *embedded_text;
+
+ /* Cached PangoLayouts. Only used if the icon is visible */
PangoLayout *editable_text_layout;
PangoLayout *additional_text_layout;
-
- GdkRectangle embedded_text_rect;
PangoLayout *embedded_text_layout;
/* Cached rectangle in canvas coordinates */
@@ -244,7 +248,6 @@ static void
nautilus_icon_canvas_item_init (NautilusIconCanvasItem *icon_item)
{
static gboolean setup_auto_enums = FALSE;
- NautilusIconCanvasItemDetails *details;
if (!setup_auto_enums) {
eel_preferences_add_auto_enum
@@ -253,9 +256,7 @@ nautilus_icon_canvas_item_init (NautilusIconCanvasItem *icon_item)
setup_auto_enums = TRUE;
}
- details = g_new0 (NautilusIconCanvasItemDetails, 1);
-
- icon_item->details = details;
+ icon_item->details = G_TYPE_INSTANCE_GET_PRIVATE ((icon_item), NAUTILUS_TYPE_ICON_CANVAS_ITEM, NautilusIconCanvasItemDetails);
nautilus_icon_canvas_item_invalidate_label_size (icon_item);
}
@@ -297,9 +298,8 @@ nautilus_icon_canvas_item_finalize (GObject *object)
g_object_unref (details->embedded_text_layout);
}
+ g_free (details->embedded_text);
- g_free (details);
-
EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}
@@ -659,27 +659,18 @@ void
nautilus_icon_canvas_item_set_embedded_text (NautilusIconCanvasItem *item,
const char *text)
{
- PangoContext *context;
- PangoFontDescription *desc;
-
- if (item->details->embedded_text_layout == NULL && text != NULL) {
- context = gtk_widget_get_pango_context (GTK_WIDGET (EEL_CANVAS_ITEM(item)->canvas));
- item->details->embedded_text_layout = pango_layout_new (context);
-
- desc = pango_font_description_from_string ("monospace 6");
- pango_layout_set_font_description (item->details->embedded_text_layout, desc);
- pango_font_description_free (desc);
- }
-
+ g_free (item->details->embedded_text);
+ item->details->embedded_text = g_strdup (text);
+
if (item->details->embedded_text_layout != NULL) {
if (text != NULL) {
pango_layout_set_text (item->details->embedded_text_layout, text, -1);
} else {
pango_layout_set_text (item->details->embedded_text_layout, "", -1);
}
-
- eel_canvas_item_request_update (EEL_CANVAS_ITEM (item));
}
+
+ eel_canvas_item_request_update (EEL_CANVAS_ITEM (item));
}
@@ -1167,6 +1158,32 @@ draw_label_text (NautilusIconCanvasItem *item, GdkDrawable *drawable,
draw_or_measure_label_text (item, drawable, create_mask, icon_rect);
}
+void
+nautilus_icon_canvas_item_set_is_visible (NautilusIconCanvasItem *item,
+ gboolean visible)
+{
+ if (item->details->is_visible == visible)
+ return;
+
+ item->details->is_visible = visible;
+
+ if (!visible) {
+ if (item->details->editable_text_layout) {
+ g_object_unref (item->details->editable_text_layout);
+ item->details->editable_text_layout = NULL;
+ }
+ if (item->details->additional_text_layout) {
+ g_object_unref (item->details->additional_text_layout);
+ item->details->additional_text_layout = NULL;
+ }
+ if (item->details->embedded_text_layout) {
+ g_object_unref (item->details->embedded_text_layout);
+ item->details->embedded_text_layout = NULL;
+ }
+ }
+}
+
+
static GdkPixbuf *
get_knob_pixbuf (void)
{
@@ -1511,34 +1528,54 @@ map_pixbuf (NautilusIconCanvasItem *icon_item)
}
static void
-draw_embedded_text (NautilusIconCanvasItem *icon_item,
+draw_embedded_text (NautilusIconCanvasItem *item,
GdkDrawable *drawable,
int x, int y)
{
GdkGC *gc;
GdkRectangle clip_rect;
+ PangoLayout *layout;
+ PangoContext *context;
+ PangoFontDescription *desc;
- if (icon_item->details->embedded_text_layout == NULL ||
- icon_item->details->embedded_text_rect.width == 0 ||
- icon_item->details->embedded_text_rect.height == 0) {
+ if (item->details->embedded_text == NULL ||
+ item->details->embedded_text_rect.width == 0 ||
+ item->details->embedded_text_rect.height == 0) {
return;
}
+ if (item->details->embedded_text_layout != NULL) {
+ layout = g_object_ref (item->details->embedded_text_layout);
+ } else {
+ context = gtk_widget_get_pango_context (GTK_WIDGET (EEL_CANVAS_ITEM (item)->canvas));
+ layout = pango_layout_new (context);
+ pango_layout_set_text (layout, item->details->embedded_text, -1);
+
+ desc = pango_font_description_from_string ("monospace 6");
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
+
+ if (item->details->is_visible) {
+ item->details->embedded_text_layout = g_object_ref (layout);
+ }
+ }
+
gc = gdk_gc_new (drawable);
- clip_rect.x = x + icon_item->details->embedded_text_rect.x;
- clip_rect.y = y + icon_item->details->embedded_text_rect.y;
- clip_rect.width = icon_item->details->embedded_text_rect.width;
- clip_rect.height = icon_item->details->embedded_text_rect.height;
+ clip_rect.x = x + item->details->embedded_text_rect.x;
+ clip_rect.y = y + item->details->embedded_text_rect.y;
+ clip_rect.width = item->details->embedded_text_rect.width;
+ clip_rect.height = item->details->embedded_text_rect.height;
gdk_gc_set_clip_rectangle (gc, &clip_rect);
gdk_draw_layout (drawable, gc,
- x + icon_item->details->embedded_text_rect.x,
- y + icon_item->details->embedded_text_rect.y,
- icon_item->details->embedded_text_layout);
+ x + item->details->embedded_text_rect.x,
+ y + item->details->embedded_text_rect.y,
+ layout);
g_object_unref (gc);
+ g_object_unref (layout);
}
/* Draw the icon item for non-anti-aliased mode. */
@@ -1680,16 +1717,23 @@ create_label_layout (NautilusIconCanvasItem *item,
}
static PangoLayout *
-get_label_layout (PangoLayout **layout,
+get_label_layout (PangoLayout **layout_cache,
NautilusIconCanvasItem *item,
const char *text)
{
- if (*layout == NULL) {
- *layout = create_label_layout (item, text);
+ PangoLayout *layout;
+
+ if (*layout_cache != NULL) {
+ return g_object_ref (*layout_cache);
+ }
+
+ layout = create_label_layout (item, text);
+
+ if (item->details->is_visible) {
+ *layout_cache = g_object_ref (layout);
}
- g_object_ref (*layout);
- return *layout;
+ return layout;
}
static void
@@ -2735,7 +2779,7 @@ nautilus_icon_canvas_item_accessible_get_offset_at_point (AtkText *text,
gint editable_height;
gint offset = 0;
gint index;
- PangoLayout *layout;
+ PangoLayout *layout, *editable_layout, *additional_layout;
PangoRectangle rect0;
char *icon_text;
gboolean have_editable;
@@ -2756,19 +2800,25 @@ nautilus_icon_canvas_item_accessible_get_offset_at_point (AtkText *text,
have_editable = item->details->editable_text != NULL &&
item->details->editable_text[0] != '\0';
have_additional = item->details->additional_text != NULL &&item->details->additional_text[0] != '\0';
+
+ editable_layout = NULL;
+ additional_layout = NULL;
if (have_editable) {
- pango_layout_get_pixel_size (item->details->editable_text_layout, NULL, &editable_height);
+ editable_layout = get_label_layout (&item->details->editable_text_layout, item, item->details->editable_text);
+ pango_layout_get_pixel_size (editable_layout, NULL, &editable_height);
if (y >= editable_height &&
have_additional) {
- layout = item->details->additional_text_layout;
+ additional_layout = get_label_layout (&item->details->additional_text_layout, item, item->details->additional_text);
+ layout = additional_layout;
icon_text = item->details->additional_text;
y -= editable_height + LABEL_LINE_SPACING;
} else {
- layout = item->details->editable_text_layout;
+ layout = editable_layout;
icon_text = item->details->editable_text;
}
} else if (have_additional) {
- layout = item->details->additional_text_layout;
+ additional_layout = get_label_layout (&item->details->additional_text_layout, item, item->details->additional_text);
+ layout = additional_layout;
icon_text = item->details->additional_text;
} else {
return 0;
@@ -2776,13 +2826,13 @@ nautilus_icon_canvas_item_accessible_get_offset_at_point (AtkText *text,
text_offset = 0;
if (have_editable) {
- pango_layout_index_to_pos (item->details->editable_text_layout, 0, &rect0);
+ pango_layout_index_to_pos (editable_layout, 0, &rect0);
text_offset = PANGO_PIXELS (rect0.x);
}
if (have_additional) {
gint itmp;
- pango_layout_index_to_pos (item->details->additional_text_layout, 0, &rect0);
+ pango_layout_index_to_pos (additional_layout, 0, &rect0);
itmp = PANGO_PIXELS (rect0.x);
if (itmp < text_offset) {
text_offset = itmp;
@@ -2805,9 +2855,18 @@ nautilus_icon_canvas_item_accessible_get_offset_at_point (AtkText *text,
} else {
offset = g_utf8_pointer_to_offset (icon_text, icon_text + index);
}
- if (layout == item->details->additional_text_layout) {
+ if (layout == additional_layout) {
offset += g_utf8_strlen (item->details->editable_text, -1);
}
+
+ if (editable_layout != NULL) {
+ g_object_unref (editable_layout);
+ }
+
+ if (additional_layout != NULL) {
+ g_object_unref (additional_layout);
+ }
+
return offset;
}
@@ -2825,7 +2884,7 @@ nautilus_icon_canvas_item_accessible_get_character_extents (AtkText *text,
gint editable_height;
gchar *icon_text;
NautilusIconCanvasItem *item;
- PangoLayout *layout;
+ PangoLayout *layout, *editable_layout, *additional_layout;
PangoRectangle rect;
PangoRectangle rect0;
gboolean have_editable;
@@ -2846,16 +2905,19 @@ nautilus_icon_canvas_item_accessible_get_character_extents (AtkText *text,
len = 0;
}
+ editable_layout = get_label_layout (&item->details->editable_text_layout, item, item->details->editable_text);
+ additional_layout = get_label_layout (&item->details->additional_text_layout, item, item->details->additional_text);
+
if (offset < len) {
icon_text = item->details->editable_text;
- layout = item->details->editable_text_layout;
+ layout = editable_layout;
} else {
offset -= len;
icon_text = item->details->additional_text;
- layout = item->details->additional_text_layout;
+ layout = additional_layout;
pos_y += LABEL_LINE_SPACING;
if (have_editable) {
- pango_layout_get_pixel_size (item->details->editable_text_layout, NULL, &editable_height);
+ pango_layout_get_pixel_size (editable_layout, NULL, &editable_height);
pos_y += editable_height;
}
}
@@ -2863,20 +2925,23 @@ nautilus_icon_canvas_item_accessible_get_character_extents (AtkText *text,
pango_layout_index_to_pos (layout, byte_offset, &rect);
text_offset = 0;
if (have_editable) {
- pango_layout_index_to_pos (item->details->editable_text_layout, 0, &rect0);
+ pango_layout_index_to_pos (editable_layout, 0, &rect0);
text_offset = PANGO_PIXELS (rect0.x);
}
if (item->details->additional_text != NULL &&
item->details->additional_text[0] != '\0') {
gint itmp;
- pango_layout_index_to_pos (item->details->additional_text_layout, 0, &rect0);
+ pango_layout_index_to_pos (additional_layout, 0, &rect0);
itmp = PANGO_PIXELS (rect0.x);
if (itmp < text_offset) {
text_offset = itmp;
}
}
+ g_object_unref (editable_layout);
+ g_object_unref (additional_layout);
+
*x = pos_x + PANGO_PIXELS (rect.x) - text_offset;
*y = pos_y + PANGO_PIXELS (rect.y);
*width = PANGO_PIXELS (rect.width);
@@ -3064,6 +3129,8 @@ nautilus_icon_canvas_item_class_init (NautilusIconCanvasItemClass *class)
EEL_OBJECT_SET_FACTORY (NAUTILUS_TYPE_ICON_CANVAS_ITEM,
nautilus_icon_canvas_item_accessible);
+
+ g_type_class_add_private (class, sizeof (NautilusIconCanvasItemDetails));
}
GType
diff --git a/libnautilus-private/nautilus-icon-canvas-item.h b/libnautilus-private/nautilus-icon-canvas-item.h
index d0f0841ca..d55c4f706 100644
--- a/libnautilus-private/nautilus-icon-canvas-item.h
+++ b/libnautilus-private/nautilus-icon-canvas-item.h
@@ -91,6 +91,8 @@ ArtDRect nautilus_icon_canvas_item_get_icon_rectangle (const NautilusIc
ArtDRect nautilus_icon_canvas_item_get_text_rectangle (NautilusIconCanvasItem *item);
void nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item,
double i2w_dx, double i2w_dy);
+void nautilus_icon_canvas_item_set_is_visible (NautilusIconCanvasItem *item,
+ gboolean visible);
G_END_DECLS
diff --git a/libnautilus-private/nautilus-icon-container.c b/libnautilus-private/nautilus-icon-container.c
index f9630a7d1..6d3437584 100644
--- a/libnautilus-private/nautilus-icon-container.c
+++ b/libnautilus-private/nautilus-icon-container.c
@@ -121,6 +121,11 @@
#define MINIMUM_EMBEDDED_TEXT_RECT_WIDTH 20
#define MINIMUM_EMBEDDED_TEXT_RECT_HEIGHT 20
+/* If icon size is bigger than this, request large embedded text.
+ * Its selected so that the non-large text should fit in "normal" icon sizes
+ */
+#define ICON_SIZE_FOR_LARGE_EMBEDDED_TEXT 55
+
/* From nautilus-icon-canvas-item.c */
#define MAX_TEXT_WIDTH_BESIDE 90
@@ -183,10 +188,11 @@ static void nautilus_icon_container_stop_monitor_top_left (NautilusIco
gconstpointer client);
static void nautilus_icon_container_start_monitor_top_left (NautilusIconContainer *container,
NautilusIconData *data,
- gconstpointer client);
+ gconstpointer client,
+ gboolean large_text);
static void handle_vadjustment_changed (GtkAdjustment *adjustment,
NautilusIconContainer *container);
-static void nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (NautilusIconContainer *container);
+static void nautilus_icon_container_update_visible_icons (NautilusIconContainer *container);
static void reveal_icon (NautilusIconContainer *container,
NautilusIcon *icon);
@@ -1640,7 +1646,7 @@ redo_layout_internal (NautilusIconContainer *container)
process_pending_icon_to_reveal (container);
process_pending_icon_to_rename (container);
- nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (container);
+ nautilus_icon_container_update_visible_icons (container);
}
static gboolean
@@ -5358,6 +5364,7 @@ nautilus_icon_container_get_icon_images (NautilusIconContainer *container,
NautilusIconData *data,
GList **emblem_icons,
char **embedded_text,
+ gboolean need_large_embeddded_text,
gboolean *embedded_text_needs_loading,
gboolean *has_open_window)
{
@@ -5366,7 +5373,7 @@ nautilus_icon_container_get_icon_images (NautilusIconContainer *container,
klass = NAUTILUS_ICON_CONTAINER_GET_CLASS (container);
g_return_val_if_fail (klass->get_icon_images != NULL, NULL);
- return klass->get_icon_images (container, data, emblem_icons, embedded_text, embedded_text_needs_loading, has_open_window);
+ return klass->get_icon_images (container, data, emblem_icons, embedded_text, need_large_embeddded_text, embedded_text_needs_loading, has_open_window);
}
@@ -5387,14 +5394,15 @@ nautilus_icon_container_get_icon_text (NautilusIconContainer *container,
static void
nautilus_icon_container_start_monitor_top_left (NautilusIconContainer *container,
NautilusIconData *data,
- gconstpointer client)
+ gconstpointer client,
+ gboolean large_text)
{
NautilusIconContainerClass *klass;
klass = NAUTILUS_ICON_CONTAINER_GET_CLASS (container);
g_return_if_fail (klass->start_monitor_top_left != NULL);
- klass->start_monitor_top_left (container, data, client);
+ klass->start_monitor_top_left (container, data, client, large_text);
}
static void
@@ -5424,7 +5432,7 @@ nautilus_icon_container_prioritize_thumbnailing (NautilusIconContainer *containe
}
static void
-nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (NautilusIconContainer *container)
+nautilus_icon_container_update_visible_icons (NautilusIconContainer *container)
{
GtkAdjustment *vadj;
double min_y, max_y;
@@ -5443,7 +5451,9 @@ nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (NautilusIconC
eel_canvas_c2w (EEL_CANVAS (container),
0, max_y, NULL, &max_y);
- /* Do the iteration in reverse to get the render-order from top to bottom */
+ /* Do the iteration in reverse to get the render-order from top to
+ * bottom for the prioritized thumbnails.
+ */
for (node = g_list_last (container->details->icons); node != NULL; node = node->prev) {
icon = node->data;
@@ -5460,10 +5470,12 @@ nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (NautilusIconC
&x1,
&y1);
if (y1 >= min_y && y0 <= max_y) {
+ nautilus_icon_canvas_item_set_is_visible (icon->item, TRUE);
nautilus_icon_container_prioritize_thumbnailing (container,
icon);
+ } else {
+ nautilus_icon_canvas_item_set_is_visible (icon->item, FALSE);
}
-
}
}
}
@@ -5472,7 +5484,7 @@ static void
handle_vadjustment_changed (GtkAdjustment *adjustment,
NautilusIconContainer *container)
{
- nautilus_icon_container_prioritize_thumbnailing_for_visible_icons (container);
+ nautilus_icon_container_update_visible_icons (container);
}
void
@@ -5489,6 +5501,7 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
char *editable_text, *additional_text;
char *embedded_text;
GdkRectangle embedded_text_rect;
+ gboolean large_embedded_text;
gboolean embedded_text_needs_loading;
gboolean has_open_window;
char *modifier;
@@ -5499,15 +5512,6 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
details = container->details;
- /* Get the icons. */
- emblem_icon_names = NULL;
- embedded_text = NULL;
- icon_name = nautilus_icon_container_get_icon_images (
- container, icon->data,
- &emblem_icon_names,
- &embedded_text, &embedded_text_needs_loading,
- &has_open_window);
-
/* compute the maximum size based on the scale factor */
min_image_size = MINIMUM_IMAGE_SIZE * EEL_CANVAS (container)->pixels_per_unit;
max_image_size = MAX (MAXIMUM_IMAGE_SIZE * EEL_CANVAS (container)->pixels_per_unit, NAUTILUS_ICON_MAXIMUM_SIZE);
@@ -5518,6 +5522,16 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
icon_size = MAX (icon_size, min_image_size);
icon_size = MIN (icon_size, max_image_size);
+ /* Get the icons. */
+ emblem_icon_names = NULL;
+ embedded_text = NULL;
+ large_embedded_text = icon_size > ICON_SIZE_FOR_LARGE_EMBEDDED_TEXT;
+ icon_name = nautilus_icon_container_get_icon_images (
+ container, icon->data,
+ &emblem_icon_names,
+ &embedded_text, large_embedded_text, &embedded_text_needs_loading,
+ &has_open_window);
+
modifier = NULL;
if (has_open_window) {
modifier = "visiting";
@@ -5540,7 +5554,7 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
embedded_text_rect.height > MINIMUM_EMBEDDED_TEXT_RECT_HEIGHT &&
embedded_text_needs_loading) {
icon->is_monitored = TRUE;
- nautilus_icon_container_start_monitor_top_left (container, icon->data, icon);
+ nautilus_icon_container_start_monitor_top_left (container, icon->data, icon, large_embedded_text);
}
emblem_pixbufs = NULL;
diff --git a/libnautilus-private/nautilus-icon-container.h b/libnautilus-private/nautilus-icon-container.h
index 83b899ed8..5e7c3b800 100644
--- a/libnautilus-private/nautilus-icon-container.h
+++ b/libnautilus-private/nautilus-icon-container.h
@@ -129,6 +129,7 @@ typedef struct {
NautilusIconData *data,
GList **emblem_icons,
char **embedded_text,
+ gboolean need_large_embeddded_text,
gboolean *embedded_text_needs_loading,
gboolean *has_window_open);
void (* get_icon_text) (NautilusIconContainer *container,
@@ -145,7 +146,8 @@ typedef struct {
NautilusIconData *icon_b);
void (* start_monitor_top_left) (NautilusIconContainer *container,
NautilusIconData *data,
- gconstpointer client);
+ gconstpointer client,
+ gboolean large_text);
void (* stop_monitor_top_left) (NautilusIconContainer *container,
NautilusIconData *data,
gconstpointer client);
diff --git a/libnautilus-private/nautilus-icon-factory.c b/libnautilus-private/nautilus-icon-factory.c
index bd98575e4..66c82ee9c 100644
--- a/libnautilus-private/nautilus-icon-factory.c
+++ b/libnautilus-private/nautilus-icon-factory.c
@@ -79,13 +79,18 @@
* cache if the caller keeps the pixbuf around (we only get rid of
* items from the cache after the caller unref's them).
*/
-#define ICON_CACHE_COUNT 128
+#define ICON_CACHE_COUNT 20
/* This is the number of milliseconds we wait before sweeping out
* items from the cache.
*/
#define ICON_CACHE_SWEEP_TIMEOUT (10 * 1000)
+/* After a pixmap goes out of the recently used queue, and the pixbuf are not
+ * referenced outside the cache this is the number of sweeps an object lives.
+ */
+#define ICON_MAX_AGE 10
+
/* This circular doubly-linked list structure is used to keep a list
* of the most recently used items in the cache.
*/
@@ -118,6 +123,7 @@ typedef struct {
time_t mtime; /* Only used for absolute filenames */
CircularList recently_used_node;
+ int age; /* zero:ed on access, incremented each sweep */
} CacheIcon;
/* The icon factory.
@@ -525,7 +531,7 @@ nautilus_icon_factory_possibly_free_cached_icon (gpointer key,
CacheIcon *icon;
icon = value;
-
+
/* Don't free a cache entry that is in the recently used list. */
if (icon->recently_used_node.next != NULL) {
return FALSE;
@@ -536,6 +542,12 @@ nautilus_icon_factory_possibly_free_cached_icon (gpointer key,
return FALSE;
}
+ icon->age++;
+
+ if (icon->age > ICON_MAX_AGE) {
+ return TRUE;
+ }
+
/* Free the item. */
return TRUE;
}
@@ -1392,7 +1404,8 @@ get_icon_from_cache (const char *icon,
/* Since this item was used, keep it in the cache longer. */
mark_recently_used (&cached_icon->recently_used_node);
-
+ cached_icon->age = 0;
+
/* Come back later and sweep the cache. */
nautilus_icon_factory_schedule_sweep (factory);
diff --git a/libnautilus-private/nautilus-icon-private.h b/libnautilus-private/nautilus-icon-private.h
index 442b2dfa5..fcfc24756 100644
--- a/libnautilus-private/nautilus-icon-private.h
+++ b/libnautilus-private/nautilus-icon-private.h
@@ -54,6 +54,9 @@ typedef struct {
/* Whether this item was selected before rubberbanding. */
eel_boolean_bit was_selected_before_rubberband : 1;
+ /* Whether this item is visible in the view. */
+ eel_boolean_bit is_visible : 1;
+
/* Whether a monitor was set on this icon. */
eel_boolean_bit is_monitored : 1;