made sidebar tabs themable, and implemented Arlo style tabs, which are

made sidebar tabs themable, and implemented Arlo style tabs, which
	are finished yet.
This commit is contained in:
Andy Hertzfeld 2000-07-03 05:00:29 +00:00
parent d30c230b92
commit 109d5ae04a
9 changed files with 325 additions and 36 deletions

View file

@ -1,3 +1,25 @@
2000-07-02 Andy Hertzfeld <andy@eazel.com>
* src/nautilus-sidebar-tabs.c: (parse_rectangle_list),
(nautilus_sidebar_tabs_load_theme_data),
(nautilus_sidebar_tabs_initialize),
(nautilus_sidebar_tabs_destroy), (draw_one_tab_plain),
(draw_tab_piece), (draw_one_tab_themed),
(draw_or_hit_test_all_tabs), (nautilus_sidebar_tabs_expose):
made the sidebar tabs themable and implemented arlo-style tabs
in the arlo theme. This isn't finished yet, because I still have
some details to work out with Arlo.
* icons/arlo/arlo.xml:
added sidebar tab stuff to the arlo theme
* libnautilus-extensions/nautilus-theme.c,h:
(nautilus_theme_get_image_path):
added a routine to access themed images
* src/nautilus-property-browser.c: (make_category_link):
made it access pixmaps with nautilus_pixmap_file instead of gnome_pixmap_file
* data/browser.xml:
removed the "nautilus" from image references
2000-07-02 J Shane Culpepper <pepper@eazel.com>
* components/services/inventory/lib/.cvsignore:

View file

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<categories>
<category name="backgrounds" image="nautilus/backgrounds.png" mode="directory" path="nautilus/backgrounds" type="property/bgimage"/>
<category name="emblems" image="nautilus/emblems.png" mode="directory" path="nautilus/emblems" type="property/keyword"/>
<category name="colors" image="nautilus/colors.png" mode="inline" type="application/x-color">
<category name="backgrounds" image="backgrounds.png" mode="directory" path="nautilus/backgrounds" type="property/bgimage"/>
<category name="emblems" image="emblems.png" mode="directory" path="nautilus/emblems" type="property/keyword"/>
<category name="colors" image="colors.png" mode="inline" type="application/x-color">
<color>rgb:FFFF/FFFF/3333</color>
<color>rgb:FFFF/CCCC/3333</color>
<color>rgb:FFFF/9999/3333</color>

View file

@ -1,5 +1,8 @@
<?xml version="1.0"?>
<theme name="arlo">
<directory BACKGROUND_TILE_IMAGE="backgrounds/white_ribs.png"/>
<sidebar SIDEBAR_BACKGROUND_COLOR="rgb:DDDD/FFFF/BBBB-rgb:7777/DDDD/3333:h" SIDEBAR_BACKGROUND_TILE_IMAGE="backgrounds/.striated.png" COMBINE="TRUE"/>
</theme>
<sidebar SIDEBAR_BACKGROUND_COLOR="rgb:DDDD/FFFF/BBBB-rgb:7777/DDDD/3333:h" SIDEBAR_BACKGROUND_TILE_IMAGE="backgrounds/.striated.png" TAB_PIECE_IMAGE="sidebar_tab_pieces.png" COMBINE="TRUE"
PIECE_OFFSETS="1,1,20,4:1,13,20,13:1,47,20,61:1,123,20,139:1,5,20,8:1,14,20,14:1,62,20,76:1,140,20,156:1,9,20,12:1,15,24,15:1,93,24,107:1,157,20,173"
LEFT_OFFSET="0" />
</theme>

View file

@ -128,3 +128,38 @@ nautilus_theme_get_theme_data(const char *resource_name, const char *property_na
return theme_data;
}
/* given the current theme, fetch the full path name of an image with the passed-in name */
/* return NULL if there isn't a corresponding image */
char *
nautilus_theme_get_image_path (const char *image_name)
{
char *theme_name, *image_path, *temp_str;
theme_name = nautilus_preferences_get (NAUTILUS_PREFERENCES_THEME, "default");
if (nautilus_strcmp (theme_name, "default") != 0) {
temp_str = g_strdup_printf ("%s/%s", theme_name, image_name);
image_path = nautilus_pixmap_file (temp_str);
g_free (theme_name);
g_free (temp_str);
/* see if a theme-specific image exists; if so, return it */
if (g_file_exists (image_path))
return image_path;
g_free (image_path);
}
/* we couldn't find a theme specific one, so look for a general image */
image_path = nautilus_pixmap_file (image_name);
if (g_file_exists (image_path))
return image_path;
/* we couldn't find anything, so return NULL */
g_free (image_path);
return NULL;
}

View file

@ -33,7 +33,8 @@ char *nautilus_theme_get_theme(void);
void nautilus_theme_set_theme(const char *new_theme);
/* fetch data from the current theme */
char *nautilus_theme_get_theme_data(const char *resource_name, const char *property_name);
char *nautilus_theme_get_theme_data (const char *resource_name, const char *property_name);
/* given the current theme, get the path name of an image with the passed-in name */
char *nautilus_theme_get_image_path (const char *image_name);
#endif /* NAUTILUS_THEME_H */

View file

@ -128,3 +128,38 @@ nautilus_theme_get_theme_data(const char *resource_name, const char *property_na
return theme_data;
}
/* given the current theme, fetch the full path name of an image with the passed-in name */
/* return NULL if there isn't a corresponding image */
char *
nautilus_theme_get_image_path (const char *image_name)
{
char *theme_name, *image_path, *temp_str;
theme_name = nautilus_preferences_get (NAUTILUS_PREFERENCES_THEME, "default");
if (nautilus_strcmp (theme_name, "default") != 0) {
temp_str = g_strdup_printf ("%s/%s", theme_name, image_name);
image_path = nautilus_pixmap_file (temp_str);
g_free (theme_name);
g_free (temp_str);
/* see if a theme-specific image exists; if so, return it */
if (g_file_exists (image_path))
return image_path;
g_free (image_path);
}
/* we couldn't find a theme specific one, so look for a general image */
image_path = nautilus_pixmap_file (image_name);
if (g_file_exists (image_path))
return image_path;
/* we couldn't find anything, so return NULL */
g_free (image_path);
return NULL;
}

View file

@ -33,7 +33,8 @@ char *nautilus_theme_get_theme(void);
void nautilus_theme_set_theme(const char *new_theme);
/* fetch data from the current theme */
char *nautilus_theme_get_theme_data(const char *resource_name, const char *property_name);
char *nautilus_theme_get_theme_data (const char *resource_name, const char *property_name);
/* given the current theme, get the path name of an image with the passed-in name */
char *nautilus_theme_get_image_path (const char *image_name);
#endif /* NAUTILUS_THEME_H */

View file

@ -1359,11 +1359,8 @@ static void
make_category_link(NautilusPropertyBrowser *property_browser, char* name, char* image, int index)
{
GtkWidget *label, *pix_widget, *button, *temp_vbox;
/* FIXME: Need to look at data files and see if there's a
* "nautilus/" in there. If so, we need to strip the
* "nautilus/" and change this to call nautilus_pixmap_file.
*/
char *file_name = gnome_pixmap_file (image);
char *file_name = nautilus_pixmap_file (image);
GtkWidget* temp_box = gtk_vbox_new (FALSE, 0);
/* generate a pixmap widget from the image file name */

View file

@ -19,7 +19,7 @@
*
* Author: Andy Hertzfeld <andy@eazel.com>
*
* This is the tabs widget for the sidebar, which represents panels as nice tabs
* This is the tabs widget for the sidebar, which represents closed panels as folder tabs
*/
#include <config.h>
@ -28,11 +28,31 @@
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <libnautilus-extensions/nautilus-global-preferences.h>
#include <libnautilus-extensions/nautilus-gtk-macros.h>
#include <libnautilus-extensions/nautilus-theme.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-util.h>
/* constants for the tab rectangle array */
#define TAB_NORMAL_LEFT 0
#define TAB_NORMAL_FILL 1
#define TAB_NORMAL_NEXT 2
#define TAB_NORMAL_RIGHT 3
#define TAB_PRELIGHT_LEFT 4
#define TAB_PRELIGHT_FILL 5
#define TAB_PRELIGHT_NEXT 6
#define TAB_PRELIGHT_RIGHT 7
#define TAB_ACTIVE_LEFT 8
#define TAB_ACTIVE_FILL 9
#define TAB_ACTIVE_NEXT 10
#define TAB_ACTIVE_RIGHT 11
#define LAST_TAB_OFFSET 12
/* data structures */
typedef struct {
@ -55,7 +75,10 @@ struct NautilusSidebarTabsDetails {
GdkColor prelight_color;
GdkColor text_color;
GdkColor prelit_text_color;
GdkPixbuf *tab_pieces;
GdkRectangle piece_offsets[LAST_TAB_OFFSET];
int tab_left_offset;
char *title;
gboolean title_prelit;
GList *tab_items;
@ -68,6 +91,7 @@ struct NautilusSidebarTabsDetails {
#define TAB_H_GAP 8
#define TAB_TOP_GAP 3
#define TAB_ROW_V_OFFSET 3
#define TAB_DEFAULT_LEFT_OFFSET 4
/* headers */
@ -122,6 +146,80 @@ setup_dark_text(NautilusSidebarTabs *sidebar_tabs)
&sidebar_tabs->details->text_color, FALSE, TRUE);
}
static void
parse_rectangle_list (NautilusSidebarTabs *sidebar_tabs, const char *rect_text)
{
int index, top, left, bottom, right;
char **text_rect_array;
GdkRectangle *current_rect;
/* split the input into separate entries */
text_rect_array = g_strsplit (rect_text, ":", LAST_TAB_OFFSET);
/* coordinates in the xml file are 1-based and ordered top, left, bottom, right */
for (index = 0; index < LAST_TAB_OFFSET; index++) {
sscanf (text_rect_array[index],
"%d,%d,%d,%d",
&top,
&left,
&bottom,
&right);
current_rect = &sidebar_tabs->details->piece_offsets[index];
current_rect->x = left - 1;
current_rect->y = top - 1;
current_rect->width = right - left + 1;
current_rect->height = bottom - top + 1;
}
g_strfreev (text_rect_array);
}
/* load the data required by the current theme */
static void
nautilus_sidebar_tabs_load_theme_data (NautilusSidebarTabs *sidebar_tabs)
{
char *temp_str;
char *tab_pieces, *tab_piece_path, *sidebar_rect_text;
/* set up the default values */
sidebar_tabs->details->tab_left_offset = TAB_DEFAULT_LEFT_OFFSET;
/* unload the old theme image if necessary */
if (sidebar_tabs->details->tab_pieces != NULL) {
gdk_pixbuf_unref (sidebar_tabs->details->tab_pieces);
sidebar_tabs->details->tab_pieces = NULL;
}
/* load the tab_pieces image if necessary */
tab_pieces = nautilus_theme_get_theme_data ("sidebar", "TAB_PIECE_IMAGE");
if (tab_pieces) {
tab_piece_path = nautilus_theme_get_image_path (tab_pieces);
g_free (tab_pieces);
if (tab_piece_path) {
sidebar_tabs->details->tab_pieces = gdk_pixbuf_new_from_file (tab_piece_path);
g_free (tab_piece_path);
if (sidebar_tabs->details->tab_pieces) {
/* we got the image, so load the rectangles from the current theme */
sidebar_rect_text = nautilus_theme_get_theme_data ("sidebar", "PIECE_OFFSETS");
if (sidebar_rect_text != NULL) {
parse_rectangle_list (sidebar_tabs, sidebar_rect_text);
g_free (sidebar_rect_text);
}
/* also load the left offset */
temp_str = nautilus_theme_get_theme_data ("sidebar", "LEFT_OFFSET");
if (temp_str) {
sidebar_tabs->details->tab_left_offset = atoi(temp_str);
g_free (temp_str);
}
}
}
}
}
/* initialize a newly allocated object */
static void
nautilus_sidebar_tabs_initialize (NautilusSidebarTabs *sidebar_tabs)
{
@ -136,7 +234,7 @@ nautilus_sidebar_tabs_initialize (NautilusSidebarTabs *sidebar_tabs)
sidebar_tabs->details->title_mode = FALSE;
sidebar_tabs->details->title = NULL;
sidebar_tabs->details->title_prelit = FALSE;
/* set up the colors */
gdk_color_parse ("rgb:99/99/99", &sidebar_tabs->details->tab_color);
gdk_colormap_alloc_color (gtk_widget_get_colormap (GTK_WIDGET (sidebar_tabs)),
@ -159,6 +257,12 @@ nautilus_sidebar_tabs_initialize (NautilusSidebarTabs *sidebar_tabs)
&sidebar_tabs->details->hilight_color, FALSE, TRUE);
setup_light_text(sidebar_tabs);
nautilus_sidebar_tabs_load_theme_data (sidebar_tabs);
/* add callback to be notified for theme changes */
nautilus_preferences_add_callback(NAUTILUS_PREFERENCES_THEME,
(NautilusPreferencesCallback) nautilus_sidebar_tabs_load_theme_data,
sidebar_tabs);
sidebar_tabs->details->title_prelit = FALSE;
}
@ -192,9 +296,12 @@ nautilus_sidebar_tabs_destroy (GtkObject *object)
g_list_free (sidebar_tabs->details->tab_items);
}
nautilus_preferences_remove_callback(NAUTILUS_PREFERENCES_THEME,
(NautilusPreferencesCallback) nautilus_sidebar_tabs_load_theme_data,
sidebar_tabs);
g_free (sidebar_tabs->details->title);
g_free (sidebar_tabs->details->title);
g_free (sidebar_tabs->details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
@ -257,10 +364,9 @@ nautilus_sidebar_tabs_size_request (GtkWidget *widget, GtkRequisition *requisiti
requisition->height = sidebar_tabs->details->total_height + TAB_TOP_GAP;
}
/* draw a single tab at the passed-in position, return the total width */
/* draw a single tab using the default, non-themed approach */
static int
draw_one_tab (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
draw_one_tab_plain (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
char *tab_name, int x, int y, gboolean prelight_flag)
{
int text_y_offset;
@ -317,8 +423,76 @@ draw_one_tab (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
return name_width + 2*TAB_MARGIN;
}
/* draw or hit test all of the currently visible tabs */
/* utility to draw the specified portion of a tab */
static int
draw_tab_piece (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc, int x, int y, int which_piece)
{
GtkWidget *widget;
GdkRectangle *piece_rect;
widget = GTK_WIDGET (sidebar_tabs);
piece_rect = &sidebar_tabs->details->piece_offsets[which_piece];
gdk_pixbuf_render_to_drawable (sidebar_tabs->details->tab_pieces,
widget->window, gc,
piece_rect->x, piece_rect->y,
x, y,
piece_rect->width, piece_rect->height,
GDK_RGB_DITHER_MAX,
0, 0);
return piece_rect->width;
}
/* draw a single tab using the theme image to define it's appearance */
static int
draw_one_tab_themed (NautilusSidebarTabs *sidebar_tabs, GdkGC *gc,
char *tab_name, int x, int y, gboolean prelight_flag, gboolean first_flag, int end_offset)
{
GtkWidget *widget;
int name_width, piece_width;
int current_pos, right_edge_pos;
int text_x_pos, text_y_offset;
int highlight_offset;
widget = GTK_WIDGET (sidebar_tabs);
highlight_offset = prelight_flag ? TAB_PRELIGHT_LEFT : 0;
/* measure the size of the name */
name_width = gdk_string_width (GTK_WIDGET (sidebar_tabs)->style->font, tab_name);
/* draw the left edge piece */
current_pos = x;
if (first_flag) {
piece_width = draw_tab_piece (sidebar_tabs, gc, current_pos, y, TAB_NORMAL_LEFT + highlight_offset);
current_pos += piece_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);
current_pos += piece_width;
}
/* draw the right edge piece */
piece_width = draw_tab_piece (sidebar_tabs, gc, current_pos, y, TAB_NORMAL_NEXT + end_offset + highlight_offset);
current_pos += piece_width;
/* draw the name */
text_y_offset = y + (TAB_HEIGHT >> 1) + 5;
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);
/* return the total tab width */
return current_pos - x;
}
/* draw or hit test all of the currently visible tabs */
static int
draw_or_hit_test_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean draw_flag, int test_x, int test_y)
{
@ -330,14 +504,17 @@ draw_or_hit_test_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean draw_flag
int x_pos;
int y_pos;
int total_height;
gboolean is_themed;
gboolean first_flag;
g_assert (NAUTILUS_IS_SIDEBAR_TABS (sidebar_tabs));
next_tab = sidebar_tabs->details->tab_items;
widget = GTK_WIDGET (sidebar_tabs);
x_pos = widget->allocation.x + 4;
is_themed = sidebar_tabs->details->tab_pieces != NULL;
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;
@ -367,12 +544,17 @@ draw_or_hit_test_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean draw_flag
/* draw as many tabs per row as will fit */
first_flag = TRUE;
while (next_tab != NULL) {
TabItem *this_item = next_tab->data;
if (draw_flag && this_item->visible)
tab_width = draw_one_tab(sidebar_tabs, temp_gc, this_item->tab_text, x_pos, y_pos, this_item->prelit);
else {
if (draw_flag && this_item->visible) {
if (is_themed)
tab_width = draw_one_tab_themed (sidebar_tabs, temp_gc, this_item->tab_text, x_pos, y_pos, this_item->prelit, first_flag, 0);
else
tab_width = draw_one_tab_plain (sidebar_tabs, temp_gc, this_item->tab_text, x_pos, y_pos, this_item->prelit);
} else {
int edge_width = 2 * TAB_MARGIN;
name_width = gdk_string_width(GTK_WIDGET (sidebar_tabs)->style->font,
this_item->tab_text);
@ -381,20 +563,29 @@ draw_or_hit_test_all_tabs (NautilusSidebarTabs *sidebar_tabs, gboolean draw_flag
(test_x >= x_pos) && (test_x <= x_pos + tab_width))
return this_item->notebook_page;
}
first_flag = FALSE;
next_tab = next_tab->next;
if (next_tab != NULL)
this_item = (TabItem*) next_tab->data;
/* bump the x-position, and see if it fits */
x_pos += tab_width + TAB_H_GAP;
x_pos += tab_width;
if (!is_themed)
x_pos += TAB_H_GAP;
if (x_pos > (widget->allocation.x + widget->allocation.width - 48)) {
/* wrap to the next line */
x_pos = widget->allocation.x + 4;
y_pos -= TAB_HEIGHT + TAB_ROW_V_OFFSET;
if ((next_tab != NULL) && ((next_tab->next != NULL) || this_item->visible))
total_height += TAB_HEIGHT + TAB_ROW_V_OFFSET;
x_pos = widget->allocation.x + sidebar_tabs->details->tab_left_offset;
y_pos -= TAB_HEIGHT;
if (!is_themed)
y_pos -= TAB_ROW_V_OFFSET;
first_flag = TRUE;
if ((next_tab != NULL) && ((next_tab->next != NULL) || this_item->visible)) {
total_height += TAB_HEIGHT;
if (!is_themed)
total_height += TAB_ROW_V_OFFSET;
}
}
}
@ -449,7 +640,11 @@ nautilus_sidebar_tabs_expose (GtkWidget *widget, GdkEventExpose *event)
int x_pos = widget->allocation.x;
int y_pos = widget->allocation.y;
draw_one_tab (sidebar_tabs, temp_gc, sidebar_tabs->details->title, x_pos + TITLE_TAB_OFFSET, y_pos, sidebar_tabs->details->title_prelit);
if (sidebar_tabs->details->tab_pieces)
draw_one_tab_themed (sidebar_tabs, temp_gc, sidebar_tabs->details->title, x_pos, y_pos, sidebar_tabs->details->title_prelit, TRUE, 1);
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);
gdk_gc_unref (temp_gc);
} else {
if (sidebar_tabs->details->tab_count > 0) {