added anti-aliased, shadowed labels for themed sidebar tabs, as well as

added anti-aliased, shadowed labels for themed sidebar tabs, as
	well as off-screen drawing to minimize flashing, fetching the
	font from the theme and improved layout.
This commit is contained in:
Andy Hertzfeld 2000-08-12 01:53:57 +00:00
parent 5015d1e85c
commit c97b4fcdee
5 changed files with 297 additions and 122 deletions

View file

@ -1,3 +1,22 @@
2000-08-11 Andy Hertzfeld <andy@eazel.com>
* src/nautilus-sidebar-tabs.c:
(nautilus_sidebar_tabs_load_theme_data),
(nautilus_sidebar_tabs_hit_test), (measure_total_height),
(recalculate_size), (nautilus_sidebar_tabs_size_request),
(draw_one_tab_plain), (draw_tab_piece_aa), (draw_one_tab_themed),
(get_tab_width), (draw_pixbuf_tiled_aa), (allocate_cleared_pixbuf),
(draw_or_layout_all_tabs), (nautilus_sidebar_tabs_expose):
added anti-aliased, shadowed labels for themed sidebar tabs, as
well as off-screen drawing to minimize flashing, fetching the
font from the theme and improved layout.
* icons/arlo/arlo.xml:
added a font for the labels
* libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c:
(nautilus_gdk_pixbuf_draw_text):
added a check for too small a box to draw in to fix a case for
the sidebar tabs
2000-08-11 Gene Z. Ragan <gzr@eazel.com>
* libnautilus-extensions/nautilus-icon-container.c:

View file

@ -4,7 +4,7 @@
LIGHT_INFO_COLOR="0xAAAAAA" SELECTION_BOX_COLOR_RGBA="0x497B7E40" SELECTION_BOX_COLOR="rgb:4949/7B7B/7E7E" />
<sidebar SIDEBAR_BACKGROUND_COLOR="rgb:6666/9999/9999-rgb:0000/3333/3333|90-rgb:0000/0000/0000:h" SIDEBAR_BACKGROUND_TILE_IMAGE="backgrounds/.striated.png" TAB_PIECE_IMAGES="sidebar_tab_pieces" COMBINE="TRUE"
LEFT_OFFSET="0" TEXT_H_OFFSET="-4" LABEL_COLOR="rgb:FFFF/FFFF/FFFF" />
LEFT_OFFSET="0" TEXT_H_OFFSET="-4" LABEL_COLOR="rgb:FFFF/FFFF/FFFF" TAB_FONT="-*-helvetica-bold-r-normal-*-24-*-*-*-*-*-*-*" />
<desktop BACKGROUND_TILE_IMAGE="./backgrounds/background_pattern.png"/>
<zoom_control NUMBER_V_OFFSET="-6" DIGIT_WIDTH="6"/>
</theme>

View file

@ -473,6 +473,10 @@ nautilus_gdk_pixbuf_draw_text (GdkPixbuf *pixbuf,
width = dest_width / font_scale;
height = dest_height / font_scale;
/* cut out if it's too small for comfort */
if (width <= 8 || height <= 8)
return;
pixmap = gdk_pixmap_new (NULL, width, height, visual->depth);
gc = gdk_gc_new (pixmap);

View file

@ -473,6 +473,10 @@ nautilus_gdk_pixbuf_draw_text (GdkPixbuf *pixbuf,
width = dest_width / font_scale;
height = dest_height / font_scale;
/* cut out if it's too small for comfort */
if (width <= 8 || height <= 8)
return;
pixmap = gdk_pixmap_new (NULL, width, height, visual->depth);
gc = gdk_gc_new (pixmap);

View file

@ -1,16 +1,14 @@
/* -*- mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
* Nautilus
*
/* Nautilus
* Copyright (C) 2000 Eazel, Inc.
*
* Nautilus is free software; you can redistribute it and/or modify
* 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.
* (at your option) any later version.
*
* Nautilus is distributed in the hope that it will be useful,
* 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.
@ -21,9 +19,7 @@
*
* Author: Andy Hertzfeld <andy@eazel.com>
*
*/
/* This is the tabs widget for the sidebar, which represents closed panels as folder tabs
* This is the tabs widget for the sidebar, which represents closed panels as folder tabs
*/
#include <config.h>
@ -32,13 +28,17 @@
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <libnautilus-extensions/nautilus-gdk-extensions.h>
#include <libnautilus-extensions/nautilus-global-preferences.h>
#include <libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h>
#include <libnautilus-extensions/nautilus-gnome-extensions.h>
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
#include <libnautilus-extensions/nautilus-gtk-macros.h>
#include <libnautilus-extensions/nautilus-theme.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libart_lgpl/art_rect.h>
#include <libart_lgpl/art_rgb.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-util.h>
@ -71,7 +71,7 @@ typedef struct {
char *tab_text;
int notebook_page;
GtkWidget *tab_view;
GdkRectangle tab_rect;
GdkRectangle tab_rect;
} TabItem;
struct NautilusSidebarTabsDetails {
@ -79,7 +79,7 @@ struct NautilusSidebarTabsDetails {
int total_height;
gboolean title_mode;
GdkRectangle title_rect;
GdkFont *tab_font;
GdkColor tab_color;
GdkColor background_color;
GdkColor line_color;
@ -89,6 +89,7 @@ struct NautilusSidebarTabsDetails {
GdkColor prelit_text_color;
GdkPixbuf *tab_piece_images[LAST_TAB_OFFSET];
int tab_height;
int tab_left_offset;
char *title;
gboolean title_prelit;
@ -98,7 +99,7 @@ struct NautilusSidebarTabsDetails {
/* constants */
#define TAB_MARGIN 8
#define TITLE_TAB_OFFSET 8
#define TAB_HEIGHT 18
#define NOMINAL_TAB_HEIGHT 18
#define TAB_H_GAP 8
#define TAB_TOP_GAP 3
#define TAB_ROW_V_OFFSET 3
@ -162,13 +163,14 @@ setup_dark_text(NautilusSidebarTabs *sidebar_tabs)
static void
nautilus_sidebar_tabs_load_theme_data (NautilusSidebarTabs *sidebar_tabs)
{
char *temp_str;
char *font_name, *temp_str;
char *tab_pieces, *tab_piece_path;
GdkColor color;
int intensity;
/* set up the default values */
sidebar_tabs->details->tab_left_offset = TAB_DEFAULT_LEFT_OFFSET;
sidebar_tabs->details->tab_height = NOMINAL_TAB_HEIGHT;
/* unload the old theme image if necessary */
if (sidebar_tabs->details->tab_piece_images[0] != NULL) {
@ -192,6 +194,7 @@ nautilus_sidebar_tabs_load_theme_data (NautilusSidebarTabs *sidebar_tabs)
sidebar_tabs->details->tab_left_offset = atoi(temp_str);
g_free (temp_str);
}
sidebar_tabs->details->tab_height = gdk_pixbuf_get_height (sidebar_tabs->details->tab_piece_images[0]);
/* set the text color according to the pixbuf */
nautilus_gdk_pixbuf_average_value (sidebar_tabs->details->tab_piece_images[TAB_NORMAL_FILL], &color);
@ -205,6 +208,20 @@ nautilus_sidebar_tabs_load_theme_data (NautilusSidebarTabs *sidebar_tabs)
}
}
}
/* unload the old font if necessary */
if (sidebar_tabs->details->tab_font) {
gdk_font_unref (sidebar_tabs->details->tab_font);
}
/* load the font, using a default if none is specified */
font_name = nautilus_theme_get_theme_data ("sidebar", "TAB_FONT");
if (font_name == NULL) {
font_name = g_strdup ("-*-charter-regular-r-normal-*-24-*-*-*-*-*-*-*");
}
sidebar_tabs->details->tab_font = gdk_font_load (font_name);
g_free (font_name);
}
/* initialize a newly allocated sidebar tabs object */
@ -340,17 +357,16 @@ nautilus_sidebar_tabs_load_tab_pieces (NautilusSidebarTabs *sidebar_tabs, const
}
/* determine the tab associated with the passed-in coordinates, and pass back the notebook
page index associated with it. It also measures the total height. */
page index associated with it. */
int nautilus_sidebar_tabs_hit_test (NautilusSidebarTabs *sidebar_tabs, int x, int y)
{
GList *current_item;
TabItem *tab_item;
GdkRectangle *rect_ptr;
int min_y, max_y;
int result;
sidebar_tabs->details->total_height = TAB_HEIGHT;
sidebar_tabs->details->total_height = sidebar_tabs->details->tab_height;
current_item = sidebar_tabs->details->tab_items;
/* if we're in title mode, see if we're in the title rectangle */
@ -371,25 +387,13 @@ int nautilus_sidebar_tabs_hit_test (NautilusSidebarTabs *sidebar_tabs, int x, in
if (!tab_item->visible && current_item->next) {
tab_item = (TabItem*) current_item->next->data;
}
min_y = tab_item->tab_rect.y;
max_y = min_y + tab_item->tab_rect.height;
result = -1;
while (current_item != NULL) {
tab_item = (TabItem*) current_item->data;
rect_ptr = &tab_item->tab_rect;
if (tab_item->visible) {
if (rect_ptr->y < min_y) {
min_y = rect_ptr->y;
}
if ((rect_ptr->y + rect_ptr->height) > max_y) {
max_y = rect_ptr->y + rect_ptr->height;
}
if (tab_item->visible) {
if ((x >= rect_ptr->x) && (x < rect_ptr->x + rect_ptr->width) &&
(y >= rect_ptr->y) && (y< rect_ptr->y + rect_ptr->height))
result = tab_item->notebook_page;
@ -397,14 +401,6 @@ int nautilus_sidebar_tabs_hit_test (NautilusSidebarTabs *sidebar_tabs, int x, in
current_item = current_item->next;
}
/* set up the total height of the tabs */
sidebar_tabs->details->total_height = max_y - min_y;
if (sidebar_tabs->details->total_height < TAB_HEIGHT) {
sidebar_tabs->details->total_height = TAB_HEIGHT;
}
return result;
}
@ -412,10 +408,8 @@ int nautilus_sidebar_tabs_hit_test (NautilusSidebarTabs *sidebar_tabs, int x, in
static int
measure_total_height (NautilusSidebarTabs *sidebar_tabs)
{
/* relayout the tabs */
/* relayout the tabs and report the result */
draw_or_layout_all_tabs (sidebar_tabs, TRUE);
/* measure the height */
nautilus_sidebar_tabs_hit_test (sidebar_tabs, -10000, -10000);
return sidebar_tabs->details->total_height;
}
@ -431,7 +425,7 @@ recalculate_size(NautilusSidebarTabs *sidebar_tabs)
widget->requisition.width = widget->parent ? widget->parent->allocation.width: 136;
if (sidebar_tabs->details->title_mode)
widget->requisition.height = TAB_HEIGHT;
widget->requisition.height = sidebar_tabs->details->tab_height;
else
widget->requisition.height = sidebar_tabs->details->total_height + TAB_TOP_GAP;
gtk_widget_queue_resize (widget);
@ -464,7 +458,7 @@ nautilus_sidebar_tabs_size_request (GtkWidget *widget, GtkRequisition *requisiti
requisition->width = widget->parent ? widget->parent->allocation.width: 136;
if (sidebar_tabs->details->title_mode)
requisition->height = TAB_HEIGHT;
requisition->height = sidebar_tabs->details->tab_height;
else
requisition->height = sidebar_tabs->details->total_height + TAB_TOP_GAP;
}
@ -494,7 +488,7 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
tab_rect->x = x;
tab_rect->y = y;
tab_rect->width = total_width;
tab_rect->height = TAB_HEIGHT;
tab_rect->height = sidebar_tabs->details->tab_height;
}
/* FIXME bugzilla.eazel.com 668:
@ -503,21 +497,21 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
/* fill the tab rectangle with the tab color */
gdk_gc_set_foreground (gc, prelight_flag ? &sidebar_tabs->details->prelight_color : &sidebar_tabs->details->tab_color);
gdk_draw_rectangle (widget->window, gc, TRUE, x, y + 1, total_width, TAB_HEIGHT - 1);
gdk_draw_rectangle (widget->window, gc, TRUE, x, y + 1, total_width, sidebar_tabs->details->tab_height - 1);
/* draw the border */
gdk_gc_set_foreground (gc, &sidebar_tabs->details->line_color);
gdk_draw_line(widget->window, gc, x + 1, y, x + total_width - 2, y);
gdk_draw_line(widget->window, gc, x, y + 1, x, y + TAB_HEIGHT - 1);
gdk_draw_line(widget->window, gc, x + total_width - 1, y + 1, x + total_width - 1, y + TAB_HEIGHT - 1);
gdk_draw_line(widget->window, gc, x, y + 1, x, y + sidebar_tabs->details->tab_height - 1);
gdk_draw_line(widget->window, gc, x + total_width - 1, y + 1, x + total_width - 1, y + sidebar_tabs->details->tab_height - 1);
/* draw the highlights for extra dimensionality */
gdk_gc_set_foreground (gc, &sidebar_tabs->details->hilight_color);
gdk_draw_line(widget->window, gc, x + 2, y + 2, x + total_width - 3, y + 2);
gdk_draw_line(widget->window, gc, x + 2, y + 2, x + 2, y + TAB_HEIGHT - 1);
gdk_draw_line(widget->window, gc, x + 2, y + 2, x + 2, y + sidebar_tabs->details->tab_height - 1);
/* draw the name */
text_y_offset = y + (TAB_HEIGHT >> 1) + 5;
text_y_offset = y + (sidebar_tabs->details->tab_height >> 1) + 5;
gdk_gc_set_foreground (gc, prelight_flag ? &sidebar_tabs->details->prelit_text_color : &sidebar_tabs->details->text_color);
gdk_draw_string (widget->window,
GTK_WIDGET (sidebar_tabs)->style->font,
@ -525,7 +519,7 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
/* draw the bottom lines */
tab_bottom = y + TAB_HEIGHT - 1;
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_width;
gdk_gc_set_foreground (gc, &sidebar_tabs->details->line_color);
@ -535,46 +529,72 @@ draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
return name_width + 2*TAB_MARGIN;
}
/* utility to draw a single tab piece */
/* utility to draw a single tab piece into a pixbuf */
static int
draw_tab_piece (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc, int x, int y, int which_piece)
draw_tab_piece_aa (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *dest_pixbuf, int x, int y, int x_limit, int which_piece)
{
GtkWidget *widget;
GdkPixbuf *pixbuf;
int width, height;
int dest_width, dest_height;
int blit_width, blit_height;
widget = GTK_WIDGET (sidebar_tabs);
pixbuf = sidebar_tabs->details->tab_piece_images[which_piece];
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
dest_width = gdk_pixbuf_get_width (dest_pixbuf);
dest_height = gdk_pixbuf_get_height (dest_pixbuf);
gdk_pixbuf_render_to_drawable_alpha (pixbuf,
widget->window,
0, 0,
x, y,
width, height,
GDK_PIXBUF_ALPHA_BILEVEL, 128,
GDK_RGB_DITHER_MAX,
0, 0);
/* trim tab piece to fit within the destination and the passed in limits */
if (x_limit > 0) {
if (x_limit < dest_width) {
dest_width = x_limit;
}
}
if (x + width > dest_width) {
blit_width = dest_width - x;
} else {
blit_width = width;
}
if (y + height > dest_height) {
blit_height = dest_height - y;
} else {
blit_height = height;
}
if (x >= 0 && y >= 0 && width > 0 && height > 0) {
gdk_pixbuf_copy_area (pixbuf,
0, 0,
blit_width, blit_height,
dest_pixbuf,
x, y);
}
return width;
}
/* draw a single tab using the theme image to define it's appearance. This does not
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 */
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, GdkGC *gc,
draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkPixbuf *tab_pixbuf,
char *tab_name, int x, int y, gboolean prelight_flag,
gboolean first_flag, gboolean prev_invisible, int text_h_offset,
GdkRectangle *tab_rect)
{
GtkWidget *widget;
int name_width, piece_width;
int name_width, piece_width, tab_width;
int current_pos, right_edge_pos;
int text_x_pos, text_y_offset;
int text_x_pos, text_y_offset, left_width;
int highlight_offset;
ArtIRect text_rect;
double font_scale_factor;
widget = GTK_WIDGET (sidebar_tabs);
/* FIXME: can't prelight active state yet */
@ -582,45 +602,58 @@ draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
if (sidebar_tabs->details->title_mode) {
highlight_offset += TAB_ACTIVE_LEFT - TAB_NORMAL_LEFT;
}
font_scale_factor = 0.5;
/* measure the size of the name */
name_width = gdk_string_width (GTK_WIDGET (sidebar_tabs)->style->font, tab_name);
name_width = gdk_string_width (sidebar_tabs->details->tab_font, tab_name) * font_scale_factor;
/* draw the left edge piece */
current_pos = x;
current_pos = x - widget->allocation.x;
if (first_flag) {
piece_width = draw_tab_piece (sidebar_tabs, gc, current_pos, y, TAB_NORMAL_LEFT + highlight_offset);
current_pos += piece_width;
left_width = draw_tab_piece_aa (sidebar_tabs, tab_pixbuf, x, y - widget->allocation.y,
-1, TAB_NORMAL_LEFT + highlight_offset);
current_pos += left_width;
}
/* draw the middle portion in a loop */
text_x_pos = current_pos;
right_edge_pos = current_pos + name_width;
while (current_pos < right_edge_pos) {
piece_width = draw_tab_piece (sidebar_tabs, gc, current_pos, y, TAB_NORMAL_FILL + highlight_offset);
piece_width = draw_tab_piece_aa (sidebar_tabs, tab_pixbuf, current_pos, y - widget->allocation.y,
right_edge_pos, TAB_NORMAL_FILL + highlight_offset);
current_pos += piece_width;
}
/* draw the name */
text_y_offset = y + (TAB_HEIGHT >> 1) + 5;
/* draw the name using a large font and shrinking it for anti-aliased text */
text_y_offset = (sidebar_tabs->details->tab_height >> 1) + 5;
if (!first_flag && !prev_invisible) {
text_x_pos += text_h_offset;
}
gdk_gc_set_foreground (gc, &sidebar_tabs->details->text_color);
gdk_draw_string (widget->window,
GTK_WIDGET (sidebar_tabs)->style->font,
gc, text_x_pos, text_y_offset, tab_name);
text_rect.x0 = text_x_pos + 1;
text_rect.y0 = y - widget->allocation.y + 5;
text_rect.x1 = text_x_pos + 1 + name_width;
text_rect.y1 = y + sidebar_tabs->details->tab_height;
nautilus_gdk_pixbuf_draw_text (tab_pixbuf, sidebar_tabs->details->tab_font, font_scale_factor,
&text_rect, tab_name, NAUTILUS_RGB_COLOR_BLACK, 191);
text_rect.x0 -= 1;
text_rect.y0 -= 1;
nautilus_gdk_pixbuf_draw_text (tab_pixbuf, sidebar_tabs->details->tab_font, font_scale_factor, &text_rect,
tab_name, NAUTILUS_RGB_COLOR_WHITE, 255);
/* set up the bounds rectangle for later hit-testing */
if (tab_rect) {
tab_rect->x = x;
tab_rect->y = y;
tab_rect->width = current_pos - x;
tab_rect->height = TAB_HEIGHT;
tab_rect->height = sidebar_tabs->details->tab_height;
}
/* return the total tab width */
return current_pos - x;
tab_width = left_width + name_width;
return tab_width;
}
static int
@ -642,29 +675,101 @@ get_text_offset (void)
/* utility to return the width of the passed in tab */
static int
get_tab_width (NautilusSidebarTabs *sidebar_tabs, TabItem *this_tab, gboolean is_themed)
get_tab_width (NautilusSidebarTabs *sidebar_tabs, TabItem *this_tab, gboolean is_themed, gboolean first_flag)
{
int edge_width, name_width;
if (this_tab == NULL)
return 0;
if (is_themed)
edge_width = gdk_pixbuf_get_width (sidebar_tabs->details->tab_piece_images[TAB_NORMAL_LEFT]);
else
/* FIXME: the font scale shouldn't be hardwired */
if (is_themed) {
if (first_flag)
edge_width = gdk_pixbuf_get_width (sidebar_tabs->details->tab_piece_images[TAB_NORMAL_LEFT]);
else
edge_width = 0;
name_width = gdk_string_width(sidebar_tabs->details->tab_font, this_tab->tab_text) / 2;
} else {
edge_width = 2 * TAB_MARGIN;
name_width = gdk_string_width(GTK_WIDGET (sidebar_tabs)->style->font, this_tab->tab_text);
name_width = gdk_string_width(GTK_WIDGET (sidebar_tabs)->style->font, this_tab->tab_text);
}
return name_width + edge_width;
}
/* fill the canvas buffer with a tiled pixmap */
static void
draw_pixbuf_tiled_aa (GdkPixbuf *src_pixbuf, GdkPixbuf *dest_pixbuf, int offset)
{
int x, y;
int start_x, start_y;
int end_x, end_y;
int tile_width, tile_height;
int blit_width, blit_height;
tile_width = gdk_pixbuf_get_width (src_pixbuf);
tile_height = gdk_pixbuf_get_height (src_pixbuf);
start_x = 0;
start_y = offset;
end_x = gdk_pixbuf_get_width (dest_pixbuf);
end_y = gdk_pixbuf_get_height (dest_pixbuf);
for (y = start_y; y < end_y; y += tile_height) {
for (x = start_x; x < end_x; x += tile_width) {
if (x + tile_width < end_x) {
blit_width = tile_width;
} else {
blit_width = end_x - x;
}
if (y + tile_height < end_y) {
blit_height = tile_height;
} else {
blit_height = end_y - y;
}
gdk_pixbuf_copy_area (src_pixbuf,
0, 0,
blit_width, blit_height,
dest_pixbuf,
x, y);
}
}
}
/* allocate_cleared_pixbuf allocates a new pixbuf with the passed-in dimensions and
clears it to be transparent */
static GdkPixbuf*
allocate_cleared_pixbuf (int width, int height)
{
guchar *pixels_ptr;
GdkPixbuf *pixbuf;
int y_index, row_stride;
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
/* clear it */
row_stride = gdk_pixbuf_get_rowstride (pixbuf);
pixels_ptr = gdk_pixbuf_get_pixels (pixbuf);
for (y_index = 0; y_index < height; y_index++) {
memset (pixels_ptr, 0, row_stride);
pixels_ptr += row_stride;
}
return pixbuf;
}
/* draw or hit test all of the currently visible tabs */
static void
draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only)
{
GdkGC *temp_gc;
GdkRectangle temp_rect;
GdkPixbuf *tab_pixbuf;
TabItem *prev_item;
int tab_width;
int extra_fill;
@ -677,23 +782,32 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
int total_width, total_height, tab_select;
int piece_width, text_h_offset;
int end_piece_width;
gboolean is_themed;
gboolean first_flag, prev_invisible;
g_assert (NAUTILUS_IS_SIDEBAR_TABS (sidebar_tabs));
next_tab = sidebar_tabs->details->tab_items;
widget = GTK_WIDGET (sidebar_tabs);
if (widget->allocation.width <= 0 || widget->allocation.height <= 0)
return;
is_themed = sidebar_tabs->details->tab_piece_images[0] != NULL;
if (is_themed) {
text_h_offset = get_text_offset ();
/* allocate a pixbuf to draw into, and clear it */
if (!layout_only) {
tab_pixbuf = allocate_cleared_pixbuf (widget->allocation.width, widget->allocation.height);
}
}
/* set up the initial positions from the widget */
x_pos = widget->allocation.x + sidebar_tabs->details->tab_left_offset;
y_pos = widget->allocation.y + widget->allocation.height - TAB_HEIGHT;
total_height = TAB_HEIGHT;
y_pos = widget->allocation.y + widget->allocation.height - sidebar_tabs->details->tab_height;
total_height = sidebar_tabs->details->tab_height;
total_width = widget->allocation.x + widget->allocation.width;
if (sidebar_tabs->details->tab_piece_images[TAB_NORMAL_RIGHT]) {
@ -703,22 +817,14 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
}
/* allocate a graphic context and clear the space below the top tabs to the background color */
y_top = widget->allocation.y + TAB_HEIGHT + TAB_TOP_GAP;
y_top = widget->allocation.y + sidebar_tabs->details->tab_height + TAB_TOP_GAP;
fill_height = widget->allocation.y + widget->allocation.height - y_top;
if (!layout_only) {
temp_gc = gdk_gc_new (widget->window);
if (is_themed) {
temp_rect.x = widget->allocation.x;
temp_rect.y = y_top;
temp_rect.width = widget->allocation.width;
temp_rect.height = fill_height;
nautilus_gdk_pixbuf_render_to_drawable_tiled (sidebar_tabs->details->tab_piece_images[TAB_BACKGROUND],
widget->window, temp_gc,
&temp_rect, GDK_RGB_DITHER_NORMAL,
0, 0);
draw_pixbuf_tiled_aa (sidebar_tabs->details->tab_piece_images[TAB_BACKGROUND], tab_pixbuf, sidebar_tabs->details->tab_height + TAB_TOP_GAP);
} else {
gdk_gc_set_foreground (temp_gc, &sidebar_tabs->details->background_color);
gdk_draw_rectangle (widget->window, temp_gc, TRUE, widget->allocation.x, y_top, widget->allocation.width, fill_height);
@ -737,15 +843,14 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
if (this_item->visible && !layout_only) {
prev_invisible = prev_item && !prev_item->visible;
if (is_themed)
tab_width = draw_one_tab_themed (sidebar_tabs, temp_gc, this_item->tab_text, x_pos, y_pos,
draw_one_tab_themed (sidebar_tabs, tab_pixbuf, this_item->tab_text, x_pos, y_pos,
this_item->prelit, first_flag, prev_invisible,
text_h_offset, &this_item->tab_rect);
else
tab_width = draw_one_tab_plain (sidebar_tabs, temp_gc, this_item->tab_text,
draw_one_tab_plain (sidebar_tabs, temp_gc, this_item->tab_text,
x_pos, y_pos, this_item->prelit, &this_item->tab_rect);
} else {
tab_width = get_tab_width (sidebar_tabs, this_item, is_themed);
}
}
tab_width = get_tab_width (sidebar_tabs, this_item, is_themed, first_flag);
first_flag = FALSE;
@ -764,16 +869,17 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
if (!is_themed)
x_pos += TAB_H_GAP;
if (x_pos + get_tab_width (sidebar_tabs, this_item, is_themed) > (total_width - end_piece_width - 8)) {
if (x_pos + get_tab_width (sidebar_tabs, this_item, is_themed, FALSE) > (total_width - end_piece_width - 8)) {
/* wrap to the next line */
x_pos = widget->allocation.x + sidebar_tabs->details->tab_left_offset;
if (is_themed)
y_pos -= gdk_pixbuf_get_height (sidebar_tabs->details->tab_piece_images[TAB_NORMAL_LEFT]);
y_pos -= sidebar_tabs->details->tab_height;
else
y_pos -= TAB_HEIGHT + TAB_ROW_V_OFFSET;
y_pos -= sidebar_tabs->details->tab_height + TAB_ROW_V_OFFSET;
first_flag = TRUE;
if ((next_tab != NULL) && ((next_tab->next != NULL) || this_item->visible)) {
total_height += TAB_HEIGHT;
total_height += sidebar_tabs->details->tab_height;
if (!is_themed)
total_height += TAB_ROW_V_OFFSET;
}
@ -781,7 +887,7 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
/* finish drawing the right edge */
if (is_themed) {
if (y_pos != last_y_pos && this_item != NULL && this_item->visible) {
if (y_pos != last_y_pos && this_item != NULL /* && this_item->visible */) {
if (prev_item->prelit) {
tab_select = TAB_PRELIGHT_RIGHT;
extra_fill = TAB_PRELIGHT_FILL;
@ -791,13 +897,17 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
}
/* we must do some extra drawing of the fill pattern here, to stretch it out to the edge */
cur_x_pos = last_x_pos + tab_width;
extra_width = gdk_pixbuf_get_width (sidebar_tabs->details->tab_piece_images[extra_fill]);
cur_x_pos = last_x_pos + tab_width;
last_x_pos = total_width - gdk_pixbuf_get_width (sidebar_tabs->details->tab_piece_images[tab_select]) - tab_width;
if (prev_item->visible && !layout_only) {
int x = widget->allocation.x;
int y = widget->allocation.y;
while (cur_x_pos < total_width) {
draw_tab_piece (sidebar_tabs, temp_gc, cur_x_pos, last_y_pos, extra_fill);
draw_tab_piece_aa (sidebar_tabs, tab_pixbuf, cur_x_pos - x,
last_y_pos - y, total_width, extra_fill);
cur_x_pos += extra_width;
}
}
@ -817,7 +927,10 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
if (tab_select >= 0) {
if (!layout_only)
piece_width = draw_tab_piece (sidebar_tabs, temp_gc, last_x_pos + tab_width, last_y_pos, tab_select);
piece_width = draw_tab_piece_aa (sidebar_tabs, tab_pixbuf,
last_x_pos + tab_width - widget->allocation.x,
last_y_pos - widget->allocation.y, -1,
tab_select);
else
piece_width = 0;
prev_item->tab_rect.width = last_x_pos + tab_width + piece_width - prev_item->tab_rect.x;
@ -829,8 +942,24 @@ draw_or_layout_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean layout_only
}
}
if (!layout_only)
/* draw the off-screen buffer to the screen if necessary, then release it */
if (!layout_only) {
gdk_gc_unref(temp_gc);
if (is_themed) {
/* draw the pixbuf onto the widget and release it */
gdk_pixbuf_render_to_drawable_alpha (tab_pixbuf,
widget->window,
0, 0,
widget->allocation.x, widget->allocation.y,
widget->allocation.width, widget->allocation.height,
GDK_PIXBUF_ALPHA_BILEVEL, 128,
GDK_RGB_DITHER_MAX,
0, 0);
gdk_pixbuf_unref (tab_pixbuf);
}
}
sidebar_tabs->details->total_height = total_height;
}
@ -878,20 +1007,39 @@ nautilus_sidebar_tabs_expose (GtkWidget *widget, GdkEventExpose *event)
/* draw the tabs */
if (sidebar_tabs->details->title_mode) {
GdkPixbuf *pixbuf;
GdkGC* temp_gc = gdk_gc_new(widget->window);
int tab_height;
int x_pos = widget->allocation.x;
int y_pos = widget->allocation.y;
if (sidebar_tabs->details->tab_piece_images[0]) {
tab_width = draw_one_tab_themed (sidebar_tabs, temp_gc, sidebar_tabs->details->title, x_pos, y_pos,
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,
sidebar_tabs->details->title_prelit, TRUE, FALSE, text_offset, &sidebar_tabs->details->title_rect);
/* draw the right edge piece */
draw_tab_piece (sidebar_tabs, temp_gc, x_pos + tab_width, y_pos, TAB_ACTIVE_RIGHT);
/* draw the right edge */
draw_tab_piece_aa (sidebar_tabs, pixbuf, tab_width, 0, -1, TAB_ACTIVE_RIGHT);
/* transfer the pixmap to the screen */
gdk_pixbuf_render_to_drawable_alpha (pixbuf,
widget->window,
0, 0,
x_pos, y_pos,
widget->allocation.width, tab_height,
GDK_PIXBUF_ALPHA_BILEVEL, 128,
GDK_RGB_DITHER_MAX,
0, 0);
gdk_pixbuf_unref (pixbuf);
} else {
draw_one_tab_plain (sidebar_tabs, temp_gc, sidebar_tabs->details->title,
x_pos + TITLE_TAB_OFFSET, y_pos, sidebar_tabs->details->title_prelit, &sidebar_tabs->details->title_rect);
x_pos + TITLE_TAB_OFFSET, y_pos, sidebar_tabs->details->title_prelit, &sidebar_tabs->details->title_rect);
}
gdk_gc_unref (temp_gc);
} else {
if (sidebar_tabs->details->tab_count > 0) {
draw_or_layout_all_tabs (sidebar_tabs, FALSE);