diff options
Diffstat (limited to 'libs/clearlooks-newer')
26 files changed, 11437 insertions, 0 deletions
diff --git a/libs/clearlooks-newer/SConscript b/libs/clearlooks-newer/SConscript new file mode 100644 index 0000000000..ca527c70da --- /dev/null +++ b/libs/clearlooks-newer/SConscript @@ -0,0 +1,50 @@ +# -*- python -*- + +import os.path +import glob + +libclearlooks_files = [ + 'animation.c', + 'cairo-support.c', + 'clearlooks_draw.c', + 'clearlooks_draw_glossy.c', + 'clearlooks_draw_gummy.c', + 'clearlooks_draw_inverted.c', + 'clearlooks_rc_style.c', + 'clearlooks_style.c', + 'clearlooks_theme_main.c', + 'support.c', + 'widget-information.c' + ] + +Import ('env install_prefix') + +clearlooks = env.Clone() + +clearlooks.Replace(CCFLAGS = ' `pkg-config --cflags gtk+-2.0 cairo` ', + LINKFLAGS = ' `pkg-config --libs gtk+-2.0 cairo` ') + +if env['GTKOSX']: + clearlooks.Append (CCFLAGS = '-DGTKOSX') + +libclearlooks = clearlooks.SharedLibrary('clearlooks', libclearlooks_files) +usable_libclearlooks = clearlooks.Install ('engines', libclearlooks) + +if env['GTKOSX']: + # GTK looks only for foo.so, not foo.dylib + print ("GTKOSX part"); + really_usable_module = clearlooks.Command ('engines/libclearlooks.so', usable_libclearlooks, 'ln -s libclearlooks.dylib libclearlooks.so', chdir=1) + Default (really_usable_module) +else: + print ("non-GTKOSX part"); + Default (usable_libclearlooks) + +env.Alias('install', env.Install ( + os.path.join(install_prefix,env['LIBDIR'], 'ardour2', 'engines'), + libclearlooks)) + +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript', 'bits.c'] + + libclearlooks_files + + glob.glob('*.h') + )) diff --git a/libs/clearlooks-newer/animation.c b/libs/clearlooks-newer/animation.c new file mode 100644 index 0000000000..82af498949 --- /dev/null +++ b/libs/clearlooks-newer/animation.c @@ -0,0 +1,337 @@ +/* Clearlooks theme engine + * + * Copyright (C) 2006 Kulyk Nazar <schamane@myeburg.net> + * Copyright (C) 2006 Benjamin Berg <benjamin@sipsolutions.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +/* This code is responsible for the clearlooks animation support. The code + * works by forcing a redraw on the animated widget. + */ + +#include "animation.h" + +#ifdef HAVE_ANIMATION +#include <glib/gtimer.h> + +struct _AnimationInfo { + GTimer *timer; + + gdouble start_modifier; + gdouble stop_time; + GtkWidget *widget; +}; +typedef struct _AnimationInfo AnimationInfo; + +struct _SignalInfo { + GtkWidget *widget; + gulong handler_id; +}; +typedef struct _SignalInfo SignalInfo; + +static GSList *connected_widgets = NULL; +static GHashTable *animated_widgets = NULL; +static int animation_timer_id = 0; + + +static gboolean animation_timeout_handler (gpointer data); + +/* This forces a redraw on a widget */ +static void +force_widget_redraw (GtkWidget *widget) +{ + if (GE_IS_PROGRESS_BAR (widget)) + gtk_widget_queue_resize (widget); + else + gtk_widget_queue_draw (widget); +} + +/* ensures that the timer is running */ +static void +start_timer () +{ + if (animation_timer_id == 0) + animation_timer_id = g_timeout_add (ANIMATION_DELAY, animation_timeout_handler, NULL); +} + +/* ensures that the timer is stopped */ +static void +stop_timer () +{ + if (animation_timer_id != 0) + { + g_source_remove(animation_timer_id); + animation_timer_id = 0; + } +} + + +/* destroys an AnimationInfo structure including the GTimer */ +static void +animation_info_destroy (AnimationInfo *animation_info) +{ + g_timer_destroy (animation_info->timer); + g_free (animation_info); +} + + +/* This function does not unref the weak reference, because the object + * is beeing destroyed currently. */ +static void +on_animated_widget_destruction (gpointer data, GObject *object) +{ + /* steal the animation info from the hash table (destroying it would + * result in the weak reference to be unrefed, which does not work + * as the widget is already destroyed. */ + g_hash_table_steal (animated_widgets, object); + animation_info_destroy ((AnimationInfo*) data); +} + +/* This function also needs to unref the weak reference. */ +static void +destroy_animation_info_and_weak_unref (gpointer data) +{ + AnimationInfo *animation_info = data; + + /* force a last redraw. This is so that if the animation is removed, + * the widget is left in a sane state. */ + force_widget_redraw (animation_info->widget); + + g_object_weak_unref (G_OBJECT (animation_info->widget), on_animated_widget_destruction, data); + animation_info_destroy (animation_info); +} + +/* Find and return a pointer to the data linked to this widget, if it exists */ +static AnimationInfo* +lookup_animation_info (const GtkWidget *widget) +{ + if (animated_widgets) + return g_hash_table_lookup (animated_widgets, widget); + + return NULL; +} + +/* Create all the relevant information for the animation, and insert it into the hash table. */ +static void +add_animation (const GtkWidget *widget, gdouble stop_time) +{ + AnimationInfo *value; + + /* object already in the list, do not add it twice */ + if (lookup_animation_info (widget)) + return; + + if (animated_widgets == NULL) + animated_widgets = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, destroy_animation_info_and_weak_unref); + + value = g_new(AnimationInfo, 1); + + value->widget = (GtkWidget*) widget; + + value->timer = g_timer_new (); + value->stop_time= stop_time; + value->start_modifier = 0.0; + + g_object_weak_ref (G_OBJECT (widget), on_animated_widget_destruction, value); + g_hash_table_insert (animated_widgets, (GtkWidget*) widget, value); + + start_timer (); +} + +/* update the animation information for each widget. This will also queue a redraw + * and stop the animation if it is done. */ +static gboolean +update_animation_info (gpointer key, gpointer value, gpointer user_data) +{ + AnimationInfo *animation_info = value; + GtkWidget *widget = key; + + g_assert ((widget != NULL) && (animation_info != NULL)); + + /* remove the widget from the hash table if it is not drawable */ + if (!GTK_WIDGET_DRAWABLE (widget)) + { + return TRUE; + } + + if (GE_IS_PROGRESS_BAR (widget)) + { + gfloat fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (widget)); + + /* stop animation for filled/not filled progress bars */ + if (fraction <= 0.0 || fraction >= 1.0) + return TRUE; + } + + force_widget_redraw (widget); + + /* stop at stop_time */ + if (animation_info->stop_time != 0 && + g_timer_elapsed (animation_info->timer, NULL) > animation_info->stop_time) + return TRUE; + + return FALSE; +} + +/* This gets called by the glib main loop every once in a while. */ +static gboolean +animation_timeout_handler (gpointer data) +{ + /*g_print("** TICK **\n");*/ + + /* enter threads as update_animation_info will use gtk/gdk. */ + gdk_threads_enter (); + g_hash_table_foreach_remove (animated_widgets, update_animation_info, NULL); + /* leave threads again */ + gdk_threads_leave (); + + if(g_hash_table_size(animated_widgets)==0) + { + stop_timer (); + return FALSE; + } + + return TRUE; +} + +static void +on_checkbox_toggle (GtkWidget *widget, gpointer data) +{ + AnimationInfo *animation_info = lookup_animation_info (widget); + + if (animation_info != NULL) + { + gfloat elapsed = g_timer_elapsed (animation_info->timer, NULL); + + animation_info->start_modifier = elapsed - animation_info->start_modifier; + } + else + { + add_animation (widget, CHECK_ANIMATION_TIME); + } +} + +static void +on_connected_widget_destruction (gpointer data, GObject *widget) +{ + connected_widgets = g_slist_remove (connected_widgets, data); + g_free (data); +} + +static void +disconnect_all_signals () +{ + GSList * item = connected_widgets; + while (item != NULL) + { + SignalInfo *signal_info = (SignalInfo*) item->data; + + g_signal_handler_disconnect (signal_info->widget, signal_info->handler_id); + g_object_weak_unref (G_OBJECT (signal_info->widget), on_connected_widget_destruction, signal_info); + g_free (signal_info); + + item = g_slist_next (item); + } + + g_slist_free (connected_widgets); + connected_widgets = NULL; +} + +/* helper function for clearlooks_animation_connect_checkbox */ +static gint +find_signal_info (gconstpointer signal_info, gconstpointer widget) +{ + if (((SignalInfo*)signal_info)->widget == widget) + return 0; + else + return 1; +} + + +/* external interface */ + +/* adds a progress bar */ +void +clearlooks_animation_progressbar_add (GtkWidget *progressbar) +{ + gdouble fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progressbar)); + + if (fraction < 1.0 && fraction > 0.0) + add_animation ((GtkWidget*) progressbar, 0.0); +} + +/* hooks up the signals for check and radio buttons */ +void +clearlooks_animation_connect_checkbox (GtkWidget *widget) +{ + if (GE_IS_CHECK_BUTTON (widget)) + { + if (!g_slist_find_custom (connected_widgets, widget, find_signal_info)) + { + SignalInfo * signal_info = g_new (SignalInfo, 1); + + signal_info->widget = widget; + signal_info->handler_id = g_signal_connect ((GObject*)widget, "toggled", G_CALLBACK (on_checkbox_toggle), NULL); + + connected_widgets = g_slist_append (connected_widgets, signal_info); + g_object_weak_ref (G_OBJECT (widget), on_connected_widget_destruction, signal_info); + } + } +} + +/* returns TRUE if the widget is animated, and FALSE otherwise */ +gboolean +clearlooks_animation_is_animated (GtkWidget *widget) +{ + return lookup_animation_info (widget) != NULL ? TRUE : FALSE; +} + +/* returns the elapsed time for the animation */ +gdouble +clearlooks_animation_elapsed (gpointer data) +{ + AnimationInfo *animation_info = lookup_animation_info (data); + + if (animation_info) + return g_timer_elapsed (animation_info->timer, NULL) + - animation_info->start_modifier; + else + return 0.0; +} + +/* cleans up all resources of the animation system */ +void +clearlooks_animation_cleanup () +{ + disconnect_all_signals (); + + if (animated_widgets != NULL) + { + g_hash_table_destroy (animated_widgets); + animated_widgets = NULL; + } + + stop_timer (); +} +#else /* !HAVE_ANIMATION */ +static void clearlooks_animation_dummy_function_so_wall_shuts_up_when_animations_is_disabled() +{ + clearlooks_animation_dummy_function_so_wall_shuts_up_when_animations_is_disabled(); +} +#endif /* HAVE_ANIMATION */ diff --git a/libs/clearlooks-newer/animation.h b/libs/clearlooks-newer/animation.h new file mode 100644 index 0000000000..da70b6ce66 --- /dev/null +++ b/libs/clearlooks-newer/animation.h @@ -0,0 +1,34 @@ +/* Clearlooks Engine + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#ifdef HAVE_ANIMATION +#include <gtk/gtk.h> +#include <ge-support.h> + +#define CL_IS_PROGRESS_BAR(widget) GE_IS_PROGRESS_BAR(widget) && widget->allocation.x != -1 && widget->allocation.y != -1 +#define ANIMATION_DELAY 100 +#define CHECK_ANIMATION_TIME 0.5 + +GE_INTERNAL void clearlooks_animation_progressbar_add (GtkWidget *progressbar); +GE_INTERNAL void clearlooks_animation_connect_checkbox (GtkWidget *widget); +GE_INTERNAL gboolean clearlooks_animation_is_animated (GtkWidget *widget); +GE_INTERNAL gdouble clearlooks_animation_elapsed (gpointer data); +GE_INTERNAL void clearlooks_animation_cleanup (); +#endif /* HAVE_ANIMATION */ diff --git a/libs/clearlooks-newer/bits.c b/libs/clearlooks-newer/bits.c new file mode 100644 index 0000000000..1e871bc5d3 --- /dev/null +++ b/libs/clearlooks-newer/bits.c @@ -0,0 +1,121 @@ +static unsigned char dot_intensity[] = { +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x98,0xb9,0xc6,0xb9,0x91,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0xbd,0xac,0x9e,0x65,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xc6,0xac,0x9e,0x96,0x5c,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0x9e,0x96,0x62,0x55,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x91,0x65,0x5c,0x55,0x68,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +}; +static unsigned char dot_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static unsigned char circle_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x23,0x62,0x92,0xb3,0xb2,0x95,0x2b,0x00,0x00,0x00, +0x00,0x00,0x3e,0xab,0xc9,0xeb,0xf9,0xf5,0xfd,0xff,0x57,0x00,0x00, +0x00,0x1f,0xb5,0xd8,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x67,0xb9,0xf2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x9a,0xe2,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0xba,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xc0,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0x9b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x2b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x00,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0x00,0x00, +0x00,0x00,0x00,0x2b,0x9c,0xe5,0xff,0xe5,0x9c,0x2b,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char outline_alpha[] = { +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +}; +static unsigned char inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_base_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, 137, 151,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, 183, 172, 7,0x00,0x00, +0x00,0x00, 12, 18,0x00,0x00, 3, 161, 233, 27,0x00,0x00,0x00, +0x00,0x00, 199, 239, 101,0x00, 85, 253, 108,0x00,0x00,0x00,0x00, +0x00,0x00, 83, 245, 250, 75, 206, 230, 8,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 104, 252, 243, 253, 124,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 2, 162, 255, 241, 28,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, 18, 228, 163,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00, 78, 62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; diff --git a/libs/clearlooks-newer/cairo-support.c b/libs/clearlooks-newer/cairo-support.c new file mode 100644 index 0000000000..dbe6fd3d34 --- /dev/null +++ b/libs/clearlooks-newer/cairo-support.c @@ -0,0 +1,815 @@ +#include <math.h> +#include "general-support.h" +#include "cairo-support.h" + +/*********************************************** + * ge_hsb_from_color - + * + * Get HSB values from RGB values. + * + * Modified from Smooth but originated in GTK+ + ***********************************************/ +void +ge_hsb_from_color (const CairoColor *color, + gdouble *hue, + gdouble *saturation, + gdouble *brightness) +{ + gdouble min, max, delta; + gdouble red, green, blue; + + red = color->r; + green = color->g; + blue = color->b; + + if (red > green) + { + max = MAX(red, blue); + min = MIN(green, blue); + } + else + { + max = MAX(green, blue); + min = MIN(red, blue); + } + + *brightness = (max + min) / 2; + + if (fabs(max - min) < 0.0001) + { + *hue = 0; + *saturation = 0; + } + else + { + if (*brightness <= 0.5) + *saturation = (max - min) / (max + min); + else + *saturation = (max - min) / (2 - max - min); + + delta = max -min; + + if (red == max) + *hue = (green - blue) / delta; + else if (green == max) + *hue = 2 + (blue - red) / delta; + else if (blue == max) + *hue = 4 + (red - green) / delta; + + *hue *= 60; + if (*hue < 0.0) + *hue += 360; + } +} + +/*********************************************** + * ge_color_from_hsb - + * + * Get RGB values from HSB values. + * + * Modified from Smooth but originated in GTK+ + ***********************************************/ +#define MODULA(number, divisor) (((gint)number % divisor) + (number - (gint)number)) +void +ge_color_from_hsb (gdouble hue, + gdouble saturation, + gdouble brightness, + CairoColor *color) +{ + gint i; + gdouble hue_shift[3], color_shift[3]; + gdouble m1, m2, m3; + + if (!color) return; + + if (brightness <= 0.5) + m2 = brightness * (1 + saturation); + else + m2 = brightness + saturation - brightness * saturation; + + m1 = 2 * brightness - m2; + + hue_shift[0] = hue + 120; + hue_shift[1] = hue; + hue_shift[2] = hue - 120; + + color_shift[0] = color_shift[1] = color_shift[2] = brightness; + + i = (saturation == 0)?3:0; + + for (; i < 3; i++) + { + m3 = hue_shift[i]; + + if (m3 > 360) + m3 = MODULA(m3, 360); + else if (m3 < 0) + m3 = 360 - MODULA(ABS(m3), 360); + + if (m3 < 60) + color_shift[i] = m1 + (m2 - m1) * m3 / 60; + else if (m3 < 180) + color_shift[i] = m2; + else if (m3 < 240) + color_shift[i] = m1 + (m2 - m1) * (240 - m3) / 60; + else + color_shift[i] = m1; + } + + color->r = color_shift[0]; + color->g = color_shift[1]; + color->b = color_shift[2]; + color->a = 1.0; +} + +void +ge_gdk_color_to_cairo (const GdkColor *c, CairoColor *cc) +{ + gdouble r, g, b; + + g_return_if_fail (c && cc); + + r = c->red / 65535.0; + g = c->green / 65535.0; + b = c->blue / 65535.0; + + cc->r = r; + cc->g = g; + cc->b = b; + cc->a = 1.0; +} + +void +ge_cairo_color_to_gtk (const CairoColor *cc, GdkColor *c) +{ + gdouble r, g, b; + + g_return_if_fail (c && cc); + + r = cc->r * 65535.0; + g = cc->g * 65535.0; + b = cc->b * 65535.0; + + c->red = r; + c->green = g; + c->blue = b; +} + +void +ge_gtk_style_to_cairo_color_cube (GtkStyle * style, CairoColorCube *cube) +{ + int i; + + g_return_if_fail (style && cube); + + for (i = 0; i < 5; i++) + { + ge_gdk_color_to_cairo (&style->bg[i], &cube->bg[i]); + ge_gdk_color_to_cairo (&style->fg[i], &cube->fg[i]); + + ge_gdk_color_to_cairo (&style->dark[i], &cube->dark[i]); + ge_gdk_color_to_cairo (&style->light[i], &cube->light[i]); + ge_gdk_color_to_cairo (&style->mid[i], &cube->mid[i]); + + ge_gdk_color_to_cairo (&style->base[i], &cube->base[i]); + ge_gdk_color_to_cairo (&style->text[i], &cube->text[i]); + ge_gdk_color_to_cairo (&style->text_aa[i], &cube->text_aa[i]); + } + + cube->black.r = cube->black.g = cube->black.b = 0; + cube->black.a = 1; + + cube->white.r = cube->white.g = cube->white.b = 1; + cube->white.a = 1; +} + +void +ge_shade_color(const CairoColor *base, gdouble shade_ratio, CairoColor *composite) +{ + gdouble hue = 0; + gdouble saturation = 0; + gdouble brightness = 0; + + g_return_if_fail (base && composite); + + ge_hsb_from_color (base, &hue, &saturation, &brightness); + + brightness = MIN(brightness*shade_ratio, 1.0); + brightness = MAX(brightness, 0.0); + + saturation = MIN(saturation*shade_ratio, 1.0); + saturation = MAX(saturation, 0.0); + + ge_color_from_hsb (hue, saturation, brightness, composite); + composite->a = base->a; +} + +void +ge_saturate_color (const CairoColor *base, gdouble saturate_level, CairoColor *composite) +{ + gdouble hue = 0; + gdouble saturation = 0; + gdouble brightness = 0; + + g_return_if_fail (base && composite); + + ge_hsb_from_color (base, &hue, &saturation, &brightness); + + saturation = MIN(saturation*saturate_level, 1.0); + saturation = MAX(saturation, 0.0); + + ge_color_from_hsb (hue, saturation, brightness, composite); + composite->a = base->a; +} + +void +ge_mix_color (const CairoColor *color1, const CairoColor *color2, + gdouble mix_factor, CairoColor *composite) +{ + g_return_if_fail (color1 && color2 && composite); + + composite->r = color1->r * (1-mix_factor) + color2->r * mix_factor; + composite->g = color1->g * (1-mix_factor) + color2->g * mix_factor; + composite->b = color1->b * (1-mix_factor) + color2->b * mix_factor; + composite->a = 1.0; +} + +cairo_t * +ge_gdk_drawable_to_cairo (GdkDrawable *window, GdkRectangle *area) +{ + cairo_t *cr; + + g_return_val_if_fail (window != NULL, NULL); + + cr = (cairo_t*) gdk_cairo_create (window); + cairo_set_line_width (cr, 1.0); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); + + if (area) + { + cairo_rectangle (cr, area->x, area->y, area->width, area->height); + cairo_clip_preserve (cr); + cairo_new_path (cr); + } + + return cr; +} + +void +ge_cairo_set_color (cairo_t *cr, const CairoColor *color) +{ + g_return_if_fail (cr && color); + + cairo_set_source_rgba (cr, color->r, color->g, color->b, color->a); +} + +void +ge_cairo_set_gdk_color_with_alpha (cairo_t *cr, const GdkColor *color, gdouble alpha) +{ + g_return_if_fail (cr && color); + + cairo_set_source_rgba (cr, color->red / 65535.0, + color->green / 65535.0, + color->blue / 65535.0, + alpha); +} + +void +ge_cairo_pattern_add_color_stop_color (cairo_pattern_t *pattern, + gfloat offset, + const CairoColor *color) +{ + g_return_if_fail (pattern && color); + + cairo_pattern_add_color_stop_rgba (pattern, offset, color->r, color->g, color->b, color->a); +} + +void +ge_cairo_pattern_add_color_stop_shade(cairo_pattern_t *pattern, + gdouble offset, + const CairoColor *color, + gdouble shade) +{ + CairoColor shaded; + + g_return_if_fail (pattern && color && (shade >= 0) && (shade <= 3)); + + shaded = *color; + + if (shade != 1) + { + ge_shade_color(color, shade, &shaded); + } + + ge_cairo_pattern_add_color_stop_color(pattern, offset, &shaded); +} + +/* This function will draw a rounded corner at position x,y. If the radius + * is very small (or negative) it will instead just do a line_to. + * ge_cairo_rounded_corner assumes clockwise drawing. */ +void +ge_cairo_rounded_corner (cairo_t *cr, + double x, + double y, + double radius, + CairoCorners corner) +{ + if (radius < 0.0001) + { + cairo_line_to (cr, x, y); + } + else + { + switch (corner) { + case CR_CORNER_NONE: + cairo_line_to (cr, x, y); + break; + case CR_CORNER_TOPLEFT: + cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 3/2); + break; + case CR_CORNER_TOPRIGHT: + cairo_arc (cr, x - radius, y + radius, radius, G_PI * 3/2, G_PI * 2); + break; + case CR_CORNER_BOTTOMRIGHT: + cairo_arc (cr, x - radius, y - radius, radius, 0, G_PI * 1/2); + break; + case CR_CORNER_BOTTOMLEFT: + cairo_arc (cr, x + radius, y - radius, radius, G_PI * 1/2, G_PI); + break; + + default: + /* A bitfield and not a sane value ... */ + g_assert_not_reached (); + cairo_line_to (cr, x, y); + return; + } + } +} + +void +ge_cairo_rounded_rectangle (cairo_t *cr, + double x, double y, double w, double h, + double radius, CairoCorners corners) +{ + g_return_if_fail (cr != NULL); + + if (radius < 0.0001 || corners == CR_CORNER_NONE) + { + cairo_rectangle (cr, x, y, w, h); + return; + } +#ifdef DEVELOPMENT + if ((corners == CR_CORNER_ALL) && (radius > w / 2.0 || radius > h / 2.0)) + g_warning ("Radius is too large for width/height in ge_rounded_rectangle.\n"); + else if (radius > w || radius > h) /* This isn't perfect. Assumes that only one corner is set. */ + g_warning ("Radius is too large for width/height in ge_rounded_rectangle.\n"); +#endif + + if (corners & CR_CORNER_TOPLEFT) + cairo_move_to (cr, x+radius, y); + else + cairo_move_to (cr, x, y); + + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x+w-radius, y+radius, radius, G_PI * 1.5, G_PI * 2); + else + cairo_line_to (cr, x+w, y); + + if (corners & CR_CORNER_BOTTOMRIGHT) + cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, G_PI * 0.5); + else + cairo_line_to (cr, x+w, y+h); + + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x+radius, y+h-radius, radius, G_PI * 0.5, G_PI); + else + cairo_line_to (cr, x, y+h); + + if (corners & CR_CORNER_TOPLEFT) + cairo_arc (cr, x+radius, y+radius, radius, G_PI, G_PI * 1.5); + else + cairo_line_to (cr, x, y); +} + + +/* ge_cairo_stroke_rectangle. + * + * A simple function to stroke the rectangle { x, y, w, h}. + * (This function only exists because of a cairo performance bug that + * has been fixed and it may be a good idea to get rid of it again.) + */ +void +ge_cairo_stroke_rectangle (cairo_t *cr, double x, double y, double w, double h) +{ + cairo_rectangle (cr, x, y, w, h); + cairo_stroke (cr); +} + +/*********************************************** + * ge_cairo_simple_border - + * + * A simple routine to draw thin squared + * borders with a topleft and bottomright color. + * + * It originated in Smooth-Engine. + ***********************************************/ +void +ge_cairo_simple_border (cairo_t *cr, + const CairoColor * tl, const CairoColor * br, + gint x, gint y, gint width, gint height, + gboolean topleft_overlap) +{ + gboolean solid_color; + + g_return_if_fail (cr != NULL); + g_return_if_fail (tl != NULL); + g_return_if_fail (br != NULL); + + + solid_color = (tl == br) || ((tl->r == br->r) && (tl->g == br->g) && (tl->b == br->b) && (tl->a == br->a)); + + topleft_overlap &= !solid_color; + + cairo_save(cr); + + cairo_set_line_width (cr, 1); + + if (topleft_overlap) + { + ge_cairo_set_color(cr, br); + + cairo_move_to(cr, x + 0.5, y + height - 0.5); + cairo_line_to(cr, x + width - 0.5, y + height - 0.5); + cairo_line_to(cr, x + width - 0.5, y + 0.5); + + cairo_stroke (cr); + } + + ge_cairo_set_color(cr, tl); + + cairo_move_to(cr, x + 0.5, y + height - 0.5); + cairo_line_to(cr, x + 0.5, y + 0.5); + cairo_line_to(cr, x + width - 0.5, y + 0.5); + + if (!topleft_overlap) + { + if (!solid_color) + { + cairo_stroke(cr); + ge_cairo_set_color(cr, br); + } + + cairo_move_to(cr, x + 0.5, y + height - 0.5); + cairo_line_to(cr, x + width - 0.5, y + height - 0.5); + cairo_line_to(cr, x + width - 0.5, y + 0.5); + } + + cairo_stroke(cr); + + cairo_restore(cr); +} + +void ge_cairo_polygon (cairo_t *cr, + const CairoColor *color, + GdkPoint *points, + gint npoints) +{ + int i = 0; + + cairo_save(cr); + + ge_cairo_set_color(cr, color); + cairo_move_to(cr, points[0].x, points[0].y); + + for (i = 1; i < npoints; i++) + { + if (!((points[i].x == points[i + 1].x) && + (points[i].y == points[i + 1].y))) + { + cairo_line_to(cr, points[i].x, points[i].y); + } + } + + if ((points[npoints-1].x != points[0].y) || + (points[npoints-1].y != points[0].y)) + { + cairo_line_to(cr, points[0].x, points[0].y); + } + + cairo_fill(cr); + + cairo_restore(cr); +} + +void ge_cairo_line (cairo_t *cr, + const CairoColor *color, + gint x1, + gint y1, + gint x2, + gint y2) +{ + cairo_save(cr); + + ge_cairo_set_color(cr, color); + cairo_set_line_width (cr, 1); + + cairo_move_to(cr, x1 + 0.5, y1 + 0.5); + cairo_line_to(cr, x2 + 0.5, y2 + 0.5); + + cairo_stroke(cr); + + cairo_restore(cr); +} + +void +ge_cairo_mirror (cairo_t *cr, + CairoMirror mirror, + gint *x, + gint *y, + gint *width, + gint *height) +{ + cairo_matrix_t matrix; + + cairo_matrix_init_identity (&matrix); + + cairo_translate (cr, *x, *y); + *x = 0; + *y = 0; + + if (mirror & CR_MIRROR_HORIZONTAL) + { + cairo_matrix_scale (&matrix, -1, 1); + *x = -*width; + } + if (mirror & CR_MIRROR_VERTICAL) + { + cairo_matrix_scale (&matrix, 1, -1); + *y = -*height; + } + + cairo_transform (cr, &matrix); +} + +void +ge_cairo_exchange_axis (cairo_t *cr, + gint *x, + gint *y, + gint *width, + gint *height) +{ + gint tmp; + cairo_matrix_t matrix; + + cairo_translate (cr, *x, *y); + cairo_matrix_init (&matrix, 0, 1, 1, 0, 0, 0); + + cairo_transform (cr, &matrix); + + /* swap width/height */ + tmp = *width; + *x = 0; + *y = 0; + *width = *height; + *height = tmp; +} + + +/*********************************************** + * ge_cairo_pattern_fill - + * + * Fill an area with some pattern + * Scaling or tiling if needed + ***********************************************/ +void +ge_cairo_pattern_fill(cairo_t *canvas, + CairoPattern *pattern, + gint x, + gint y, + gint width, + gint height) +{ + cairo_matrix_t original_matrix, current_matrix; + + if (pattern->operator == CAIRO_OPERATOR_DEST) + { + return; + } + + cairo_pattern_get_matrix(pattern->handle, &original_matrix); + current_matrix = original_matrix; + + if (pattern->scale != GE_DIRECTION_NONE) + { + gdouble scale_x = 1.0; + gdouble scale_y = 1.0; + + if ((pattern->scale == GE_DIRECTION_VERTICAL) || (pattern->scale == GE_DIRECTION_BOTH)) + { + scale_x = 1.0/width; + } + + if ((pattern->scale == GE_DIRECTION_HORIZONTAL) || (pattern->scale == GE_DIRECTION_BOTH)) + { + scale_y = 1.0/height; + } + + cairo_matrix_scale(¤t_matrix, scale_x, scale_y); + } + + if (pattern->translate != GE_DIRECTION_NONE) + { + gdouble translate_x = 0; + gdouble translate_y = 0; + + if ((pattern->translate == GE_DIRECTION_VERTICAL) || (pattern->translate == GE_DIRECTION_BOTH)) + { + translate_x = 0.0-x; + } + + if ((pattern->translate == GE_DIRECTION_HORIZONTAL) || (pattern->translate == GE_DIRECTION_BOTH)) + { + translate_y = 0.0-y; + } + + cairo_matrix_translate(¤t_matrix, translate_x, translate_y); + } + + cairo_pattern_set_matrix(pattern->handle, ¤t_matrix); + + cairo_save(canvas); + + cairo_set_source(canvas, pattern->handle); + cairo_set_operator(canvas, pattern->operator); + cairo_rectangle(canvas, x, y, width, height); + + cairo_fill (canvas); + + cairo_restore(canvas); + + cairo_pattern_set_matrix(pattern->handle, &original_matrix); +} + +/*********************************************** + * ge_cairo_color_pattern - + * + * Create A Solid Color Pattern + ***********************************************/ +CairoPattern* +ge_cairo_color_pattern(CairoColor *base) +{ + CairoPattern * result = g_new0(CairoPattern, 1); + + #if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) + result->type = CAIRO_PATTERN_TYPE_SOLID; + #endif + + result->scale = GE_DIRECTION_NONE; + result->translate = GE_DIRECTION_NONE; + + result->handle = cairo_pattern_create_rgba(base->r, + base->g, + base->b, + base->a); + + result->operator = CAIRO_OPERATOR_SOURCE; + + return result; +} + +/*********************************************** + * ge_cairo_pixbuf_pattern - + * + * Create A Tiled Pixbuf Pattern + ***********************************************/ +CairoPattern* +ge_cairo_pixbuf_pattern(GdkPixbuf *pixbuf) +{ + CairoPattern * result = g_new0(CairoPattern, 1); + + cairo_t *canvas; + cairo_surface_t * surface; + gint width, height; + + #if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) + result->type = CAIRO_PATTERN_TYPE_SURFACE; + #endif + + result->scale = GE_DIRECTION_NONE; + result->translate = GE_DIRECTION_BOTH; + + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + + canvas = cairo_create(surface); + + gdk_cairo_set_source_pixbuf (canvas, pixbuf, 0, 0); + cairo_rectangle (canvas, 0, 0, width, height); + cairo_fill (canvas); + cairo_destroy(canvas); + + result->handle = cairo_pattern_create_for_surface (surface); + cairo_surface_destroy(surface); + + cairo_pattern_set_extend (result->handle, CAIRO_EXTEND_REPEAT); + + result->operator = CAIRO_OPERATOR_SOURCE; + + return result; +} + +/*********************************************** + * ge_cairo_pixmap_pattern - + * + * Create A Tiled Pixmap Pattern + ***********************************************/ +CairoPattern* +ge_cairo_pixmap_pattern(GdkPixmap *pixmap) +{ + CairoPattern * result = NULL; + + GdkPixbuf * pixbuf; + gint width, height; + + gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height); + + pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE (pixmap), + gdk_drawable_get_colormap(GDK_DRAWABLE (pixmap)), + 0, 0, 0, 0, width, height); + + result = ge_cairo_pixbuf_pattern(pixbuf); + + g_object_unref (pixbuf); + + return result; +} + +/*********************************************** + * ge_cairo_linear_shade_gradient_pattern - + * + * Create A Linear Shade Gradient Pattern + * Aka Smooth Shade Gradient, from/to gradient + * With End points defined as shades of the + * base color + ***********************************************/ +CairoPattern * +ge_cairo_linear_shade_gradient_pattern(CairoColor *base, + gdouble shade1, + gdouble shade2, + gboolean vertical) +{ + CairoPattern * result = g_new0(CairoPattern, 1); + + #if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) + result->type = CAIRO_PATTERN_TYPE_LINEAR; + #endif + + if (vertical) + { + result->scale = GE_DIRECTION_VERTICAL; + + result->handle = cairo_pattern_create_linear(0, 0, 1, 0); + } + else + { + result->scale = GE_DIRECTION_HORIZONTAL; + + result->handle = cairo_pattern_create_linear(0, 0, 0, 1); + } + + result->translate = GE_DIRECTION_BOTH; + result->operator = CAIRO_OPERATOR_SOURCE; + + ge_cairo_pattern_add_color_stop_shade(result->handle, 0, base, shade1); + ge_cairo_pattern_add_color_stop_shade(result->handle, 1, base, shade2); + + return result; +} + +void +ge_cairo_pattern_destroy(CairoPattern *pattern) +{ + if (pattern) + { + if (pattern->handle) + cairo_pattern_destroy(pattern->handle); + + g_free(pattern); + } +} + +/* The following function will be called by GTK+ when the module + * is loaded and checks to see if we are compatible with the + * version of GTK+ that loads us. + */ +GE_EXPORT const gchar* g_module_check_init (GModule *module); +const gchar* +g_module_check_init (GModule *module) +{ + return gtk_check_version (GTK_MAJOR_VERSION, + GTK_MINOR_VERSION, + GTK_MICRO_VERSION - GTK_INTERFACE_AGE); +} diff --git a/libs/clearlooks-newer/cairo-support.h b/libs/clearlooks-newer/cairo-support.h new file mode 100644 index 0000000000..12163b0469 --- /dev/null +++ b/libs/clearlooks-newer/cairo-support.h @@ -0,0 +1,118 @@ +/* Helpful functions when dealing with cairo in gtk engines */ + +#include <gtk/gtk.h> +#include <math.h> + +typedef struct +{ + gdouble r; + gdouble g; + gdouble b; + gdouble a; +} CairoColor; + +typedef struct +{ + CairoColor bg[5]; + CairoColor fg[5]; + + CairoColor dark[5]; + CairoColor light[5]; + CairoColor mid[5]; + + CairoColor base[5]; + CairoColor text[5]; + CairoColor text_aa[5]; + + CairoColor black; + CairoColor white; +} CairoColorCube; + +typedef enum +{ + CR_CORNER_NONE = 0, + CR_CORNER_TOPLEFT = 1, + CR_CORNER_TOPRIGHT = 2, + CR_CORNER_BOTTOMLEFT = 4, + CR_CORNER_BOTTOMRIGHT = 8, + CR_CORNER_ALL = 15 +} CairoCorners; + +typedef enum +{ + CR_MIRROR_NONE = 0, + CR_MIRROR_HORIZONTAL = 1 << 0, + CR_MIRROR_VERTICAL = 1 << 1 +} CairoMirror; + +/*****************************/ +/* Pattern Fills */ +/*****************************/ +typedef enum { + GE_DIRECTION_VERTICAL, + GE_DIRECTION_HORIZONTAL, + GE_DIRECTION_BOTH, + GE_DIRECTION_NONE +} GeDirection; + +#if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) +typedef enum _cairo_pattern_type { + CAIRO_PATTERN_TYPE_SOLID, + CAIRO_PATTERN_TYPE_SURFACE, + CAIRO_PATTERN_TYPE_LINEAR, + CAIRO_PATTERN_TYPE_RADIAL +} cairo_pattern_type_t; + +# define CAIRO_PATTERN_TYPE(pattern) pattern->type; +#else +# define CAIRO_PATTERN_TYPE(pattern) cairo_pattern_get_type (pattern->handle); +#endif + +typedef struct +{ +#if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) + cairo_pattern_type_t type; +#endif + GeDirection scale; + GeDirection translate; + + cairo_pattern_t *handle; + cairo_operator_t operator; +} CairoPattern; + +GE_INTERNAL void ge_hsb_from_color (const CairoColor *color, gdouble *hue, gdouble *saturation, gdouble *brightness); +GE_INTERNAL void ge_color_from_hsb (gdouble hue, gdouble saturation, gdouble brightness, CairoColor *color); + +GE_INTERNAL void ge_gdk_color_to_cairo (const GdkColor * gc, CairoColor * cc); +GE_INTERNAL void ge_cairo_color_to_gtk (const CairoColor *cc, GdkColor *c); +GE_INTERNAL void ge_gtk_style_to_cairo_color_cube (GtkStyle * style, CairoColorCube *cube); + +GE_INTERNAL void ge_shade_color(const CairoColor *base, gdouble shade_ratio, CairoColor *composite); +GE_INTERNAL void ge_saturate_color (const CairoColor * base, gdouble saturate_level, CairoColor *composite); +GE_INTERNAL void ge_mix_color (const CairoColor *color1, const CairoColor *color2, gdouble mix_factor, CairoColor *composite); + +GE_INTERNAL cairo_t * ge_gdk_drawable_to_cairo (GdkDrawable *window, GdkRectangle *area); +GE_INTERNAL void ge_cairo_set_color (cairo_t *cr, const CairoColor *color); +GE_INTERNAL void ge_cairo_set_gdk_color_with_alpha (cairo_t *cr, const GdkColor *color, gdouble alpha); +GE_INTERNAL void ge_cairo_pattern_add_color_stop_color (cairo_pattern_t *pattern, gfloat offset, const CairoColor *color); +GE_INTERNAL void ge_cairo_pattern_add_color_stop_shade (cairo_pattern_t *pattern, gdouble offset, const CairoColor *color, gdouble shade); + +GE_INTERNAL void ge_cairo_rounded_corner (cairo_t *cr, double x, double y, double radius, CairoCorners corner); +GE_INTERNAL void ge_cairo_rounded_rectangle (cairo_t *cr, double x, double y, double w, double h, double radius, CairoCorners corners); + +GE_INTERNAL void ge_cairo_stroke_rectangle (cairo_t *cr, double x, double y, double w, double h); +GE_INTERNAL void ge_cairo_simple_border (cairo_t *cr, const CairoColor * tl, const CairoColor * br, gint x, gint y, gint width, gint height, gboolean topleft_overlap); + +GE_INTERNAL void ge_cairo_line (cairo_t *cr, const CairoColor *color, gint x1, gint y1, gint x2, gint y2); +GE_INTERNAL void ge_cairo_polygon (cairo_t *cr, const CairoColor *color, GdkPoint *points, gint npoints); + +GE_INTERNAL void ge_cairo_mirror (cairo_t *cr, CairoMirror mirror, gint *x, gint *y, gint *width, gint *height); +GE_INTERNAL void ge_cairo_exchange_axis (cairo_t *cr, gint *x, gint *y, gint *width, gint *height); + +GE_INTERNAL void ge_cairo_pattern_fill(cairo_t *canvas, CairoPattern *pattern, gint x, gint y, gint width, gint height); + +GE_INTERNAL CairoPattern *ge_cairo_color_pattern(CairoColor *base); +GE_INTERNAL CairoPattern *ge_cairo_pixbuf_pattern(GdkPixbuf *pixbuf); +GE_INTERNAL CairoPattern *ge_cairo_pixmap_pattern(GdkPixmap *pixmap); +GE_INTERNAL CairoPattern *ge_cairo_linear_shade_gradient_pattern(CairoColor *base, gdouble shade1, gdouble shade2, gboolean vertical); +GE_INTERNAL void ge_cairo_pattern_destroy(CairoPattern *pattern); diff --git a/libs/clearlooks-newer/clearlooks_draw.c b/libs/clearlooks-newer/clearlooks_draw.c new file mode 100644 index 0000000000..614317ea3b --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_draw.c @@ -0,0 +1,2279 @@ +/* Clearlooks theme engine + * Copyright (C) 2006 Richard Stellingwerff + * Copyright (C) 2006 Daniel Borgman + * Copyright (C) 2007 Benjamin Berg + * Copyright (C) 2007 Andrea Cimitan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "clearlooks_draw.h" +#include "clearlooks_style.h" +#include "clearlooks_types.h" + +#include "support.h" +#include <ge-support.h> +#include <math.h> + +#include <cairo.h> + +typedef void (*menubar_draw_proto) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const MenuBarParameters *menubar, + int x, int y, int width, int height); + +static void +clearlooks_draw_inset (cairo_t *cr, + const CairoColor *bg_color, + double x, double y, double w, double h, + double radius, uint8 corners) +{ + CairoColor shadow; + CairoColor highlight; + + /* not really sure of shading ratios... we will think */ + ge_shade_color (bg_color, 0.94, &shadow); + ge_shade_color (bg_color, 1.06, &highlight); + + /* highlight */ + cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */ + + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.75, G_PI * 2); + else + cairo_line_to (cr, x + w, y); + + if (corners & CR_CORNER_BOTTOMRIGHT) + cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, G_PI * 0.5); + else + cairo_line_to (cr, x + w, y + h); + + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.5, G_PI * 0.75); + else + cairo_line_to (cr, x, y + h); + + ge_cairo_set_color (cr, &highlight); + cairo_stroke (cr); + + /* shadow */ + cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188)); + + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI); + else + cairo_line_to (cr, x, y + h); + + if (corners & CR_CORNER_TOPLEFT) + cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5); + else + cairo_line_to (cr, x, y); + + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75); + else + cairo_line_to (cr, x + w, y); + + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); +} + +static void +clearlooks_draw_shadow (cairo_t *cr, const ClearlooksColors *colors, gfloat radius, int width, int height) +{ + CairoColor shadow; + ge_shade_color (&colors->shade[6], 0.92, &shadow); + + cairo_set_line_width (cr, 1.0); + + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1); + + cairo_move_to (cr, width, radius); + ge_cairo_rounded_corner (cr, width, height, radius, CR_CORNER_BOTTOMRIGHT); + cairo_line_to (cr, radius, height); + + cairo_stroke (cr); +} + +static void +clearlooks_draw_top_left_highlight (cairo_t *cr, const CairoColor *color, + const WidgetParameters *params, + int width, int height, gdouble radius) +{ + CairoColor hilight; + + double light_top = params->ythickness-1, + light_bottom = height - params->ythickness - 1, + light_left = params->xthickness-1, + light_right = width - params->xthickness - 1; + + ge_shade_color (color, 1.3, &hilight); + cairo_move_to (cr, light_left, light_bottom - (int)radius/2); + + ge_cairo_rounded_corner (cr, light_left, light_top, radius, params->corners & CR_CORNER_TOPLEFT); + + cairo_line_to (cr, light_right - (int)radius/2, light_top); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + cairo_stroke (cr); +} + +#ifdef DEVELOPMENT +#warning seems to be very slow in scrollbar_stepper +#endif + +static void +clearlooks_draw_highlight_and_shade (cairo_t *cr, const ClearlooksColors *colors, + const ShadowParameters *params, + int width, int height, gdouble radius) +{ + CairoColor hilight; + CairoColor shadow; + uint8 corners = params->corners; + double x = 1.0; + double y = 1.0; + + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 1.06, &hilight); + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 0.94, &shadow); + + width -= 3; + height -= 3; + + cairo_save (cr); + + /* Top/Left highlight */ + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_move_to (cr, x, y+height-radius); + else + cairo_move_to (cr, x, y+height); + + ge_cairo_rounded_corner (cr, x, y, radius, corners & CR_CORNER_TOPLEFT); + + if (corners & CR_CORNER_TOPRIGHT) + cairo_line_to (cr, x+width-radius, y); + else + cairo_line_to (cr, x+width, y); + + if (params->shadow & CL_SHADOW_OUT) + ge_cairo_set_color (cr, &hilight); + else + ge_cairo_set_color (cr, &shadow); + + cairo_stroke (cr); + + /* Bottom/Right highlight -- this includes the corners */ + cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */ + ge_cairo_rounded_corner (cr, x+width, y, radius, corners & CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, x+width, y+height, radius, corners & CR_CORNER_BOTTOMRIGHT); + ge_cairo_rounded_corner (cr, x, y+height, radius, corners & CR_CORNER_BOTTOMLEFT); + + if (params->shadow & CL_SHADOW_OUT) + ge_cairo_set_color (cr, &shadow); + else + ge_cairo_set_color (cr, &hilight); + + cairo_stroke (cr); + + cairo_restore (cr); +} + +static void +clearlooks_set_border_gradient (cairo_t *cr, const CairoColor *color, double hilight, int width, int height) +{ + cairo_pattern_t *pattern; + + CairoColor bottom_shade; + ge_shade_color (color, hilight, &bottom_shade); + + pattern = cairo_pattern_create_linear (0, 0, width, height); + cairo_pattern_add_color_stop_rgb (pattern, 0, color->r, color->g, color->b); + cairo_pattern_add_color_stop_rgb (pattern, 1, bottom_shade.r, bottom_shade.g, bottom_shade.b); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); +} + +static void +clearlooks_draw_gripdots (cairo_t *cr, const ClearlooksColors *colors, int x, int y, + int width, int height, int xr, int yr, + float contrast) +{ + const CairoColor *dark = &colors->shade[4]; + CairoColor hilight; + int i, j; + int xoff, yoff; + + ge_shade_color (dark, 1.5, &hilight); + + for ( i = 0; i < xr; i++ ) + { + for ( j = 0; j < yr; j++ ) + { + xoff = x -(xr * 3 / 2) + 3 * i; + yoff = y -(yr * 3 / 2) + 3 * j; + + cairo_rectangle (cr, width/2+0.5+xoff, height/2+0.5+yoff, 2, 2); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8+contrast); + cairo_fill (cr); + cairo_rectangle (cr, width/2+0.5+xoff, height/2+0.5+yoff, 1, 1); + cairo_set_source_rgba (cr, dark->r, dark->g, dark->b, 0.8+contrast); + cairo_fill (cr); + } + } +} + +static void +clearlooks_draw_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + double xoffset = 0, yoffset = 0; + double radius = params->radius; + const CairoColor *fill = &colors->bg[params->state_type]; + const CairoColor *border_normal = &colors->shade[6]; + const CairoColor *border_disabled = &colors->shade[4]; + + CairoColor shadow; + ge_shade_color (border_normal, 0.925, &shadow); + + cairo_save (cr); + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + if (params->xthickness == 3 || params->ythickness == 3) + { + if (params->xthickness == 3) + xoffset = 1; + if (params->ythickness == 3) + yoffset = 1; + } + + radius = MIN (radius, MIN ((width - 2.0 - xoffset * 2.0) / 2.0, (height - 2.0 - yoffset * 2) / 2.0)); + + if (params->xthickness == 3 || params->ythickness == 3) + { + cairo_translate (cr, 0.5, 0.5); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); + } + + ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, + width-(xoffset*2)-2, + height-(yoffset*2)-2, + radius, params->corners); + + if (!params->active) + { + cairo_pattern_t *pattern; + gdouble shade_size = ((100.0/height)*8.0)/100.0; + CairoColor top_shade, bottom_shade, middle_shade; + + ge_shade_color (fill, 1.1, &top_shade); + ge_shade_color (fill, 0.98, &middle_shade); + ge_shade_color (fill, 0.93, &bottom_shade); + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, top_shade.r, top_shade.g, top_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, shade_size, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0 - shade_size, middle_shade.r, middle_shade.g, middle_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, (height-(yoffset*2)-1)/height, bottom_shade.r, bottom_shade.g, bottom_shade.b); + cairo_pattern_add_color_stop_rgba (pattern, (height-(yoffset*2)-1)/height, bottom_shade.r, bottom_shade.g, bottom_shade.b, 0.7); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, bottom_shade.r, bottom_shade.g, bottom_shade.b, 0.7); + + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + cairo_pattern_t *pattern; + + ge_cairo_set_color (cr, fill); + cairo_fill_preserve (cr); + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 0.4, shadow.r, shadow.g, shadow.b, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.2); + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + pattern = cairo_pattern_create_linear (0, yoffset+1, 0, 3+yoffset); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + pattern = cairo_pattern_create_linear (xoffset+1, 0, 3+xoffset, 0); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + + + /* Drawing the border */ + if (!params->active && params->is_default) + { + const CairoColor *l = &colors->shade[4]; + const CairoColor *d = &colors->shade[4]; + ge_cairo_set_color (cr, l); + ge_cairo_stroke_rectangle (cr, 2.5, 2.5, width-5, height-5); + + ge_cairo_set_color (cr, d); + ge_cairo_stroke_rectangle (cr, 3.5, 3.5, width-7, height-7); + } + + ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, radius, params->corners); + + if (params->disabled) + ge_cairo_set_color (cr, border_disabled); + else + if (!params->active) + clearlooks_set_border_gradient (cr, border_normal, 1.32, 0, height); + else + ge_cairo_set_color (cr, border_normal); + + cairo_stroke (cr); + + /* Draw the "shadow" */ + if (!params->active) + { + cairo_translate (cr, 0.5, 0.5); + /* Draw right shadow */ + cairo_move_to (cr, width-params->xthickness, params->ythickness - 1); + cairo_line_to (cr, width-params->xthickness, height - params->ythickness - 1); + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1); + cairo_stroke (cr); + + /* Draw topleft shadow */ + clearlooks_draw_top_left_highlight (cr, fill, params, width, height, radius); + } + cairo_restore (cr); +} + +static void +clearlooks_draw_entry (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *base = &colors->base[params->state_type]; + CairoColor border = colors->shade[params->disabled ? 4 : 6]; + double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0)); + + if (params->focus) + border = colors->spot[2]; + + cairo_translate (cr, x+0.5, y+0.5); + cairo_set_line_width (cr, 1.0); + + /* Fill the background (shouldn't have to) */ + cairo_rectangle (cr, -0.5, -0.5, width, height); + ge_cairo_set_color (cr, ¶ms->parentbg); + cairo_fill (cr); + + /* Fill the entry's base color (why isn't is large enough by default?) */ + cairo_rectangle (cr, 1.5, 1.5, width-4, height-4); + ge_cairo_set_color (cr, base); + cairo_fill (cr); + + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); + + /* Draw the inner shadow */ + if (params->focus) + { + /* ge_cairo_rounded_rectangle (cr, 2, 2, width-5, height-5, RADIUS-1, params->corners); */ + ge_cairo_set_color (cr, &colors->spot[0]); + ge_cairo_stroke_rectangle (cr, 2, 2, width-5, height-5); + } + else + { + CairoColor shadow; + ge_shade_color (&border, 0.925, &shadow); + + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, params->disabled ? 0.05 : 0.1); + /* + cairo_move_to (cr, 2, height-3); + cairo_arc (cr, params->xthickness+RADIUS-1, params->ythickness+RADIUS-1, RADIUS, G_PI, 270*(G_PI/180)); + cairo_line_to (cr, width-3, 2);*/ + cairo_move_to (cr, 2, height-3); + cairo_line_to (cr, 2, 2); + cairo_line_to (cr, width-3, 2); + cairo_stroke (cr); + } + + ge_cairo_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, params->corners); + if (params->focus || params->disabled) + ge_cairo_set_color (cr, &border); + else + clearlooks_set_border_gradient (cr, &border, 1.32, 0, height); + cairo_stroke (cr); +} + +static void +clearlooks_draw_spinbutton (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[!params->disabled ? 5 : 3]; + CairoColor hilight; + + params->style_functions->draw_button (cr, colors, params, x, y, width, height); + + ge_shade_color (border, 1.5, &hilight); + + cairo_translate (cr, x, y); + + cairo_move_to (cr, params->xthickness + 0.5, (height/2) + 0.5); + cairo_line_to (cr, width-params->xthickness - 0.5, (height/2) + 0.5); + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + cairo_move_to (cr, params->xthickness + 0.5, (height/2)+1.5); + cairo_line_to (cr, width-params->xthickness - 0.5, (height/2)+1.5); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); +} + +static void +clearlooks_draw_spinbutton_down (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + cairo_pattern_t *pattern; + double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0)); + CairoColor shadow; + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 0.8, &shadow); + + cairo_translate (cr, x+1, y+1); + + ge_cairo_rounded_rectangle (cr, 1, 1, width-4, height-4, radius, params->corners); + + ge_cairo_set_color (cr, &colors->bg[params->state_type]); + + cairo_fill_preserve (cr); + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, shadow.r, shadow.g, shadow.b); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + + cairo_set_source (cr, pattern); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); +} + +static void +clearlooks_scale_draw_gradient (cairo_t *cr, + const CairoColor *c1, + const CairoColor *c2, + const CairoColor *c3, + int x, int y, int width, int height, + boolean horizontal) +{ + cairo_pattern_t *pattern; + + pattern = cairo_pattern_create_linear (0, 0, horizontal ? 0 : width, horizontal ? height : 0); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b); + + cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, c3); + ge_cairo_stroke_rectangle (cr, x, y, width, height); +} + +#define TROUGH_SIZE 6 +static void +clearlooks_draw_scale_trough (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + int trough_width, trough_height; + double translate_x, translate_y; + + if (slider->horizontal) + { + trough_width = width-3; + trough_height = TROUGH_SIZE-2; + + translate_x = x + 0.5; + translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2); + } + else + { + trough_width = TROUGH_SIZE-2; + trough_height = height-3; + + translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2); + translate_y = y + 0.5; + } + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, translate_x, translate_y); + + if (!slider->fill_level) + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0); + + cairo_translate (cr, 1, 1); + + if (!slider->lower && ! slider->fill_level) + clearlooks_scale_draw_gradient (cr, &colors->shade[3], /* top */ + &colors->shade[2], /* bottom */ + &colors->shade[6], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal); + else + clearlooks_scale_draw_gradient (cr, &colors->spot[1], /* top */ + &colors->spot[0], /* bottom */ + &colors->spot[2], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal); +} + +static void +clearlooks_draw_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[params->disabled ? 4 : 6]; + const CairoColor *spot = &colors->spot[1]; + const CairoColor *fill = &colors->shade[2]; + double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0)); + + cairo_pattern_t *pattern; + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y); + + if (params->prelight) + border = &colors->spot[2]; + + /* fill the widget */ + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); + + /* Fake light */ + if (!params->disabled) + { + const CairoColor *top = &colors->shade[0]; + const CairoColor *bot = &colors->shade[2]; + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, top->r, top->g, top->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bot->r, bot->g, bot->b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + ge_cairo_set_color (cr, fill); + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); + cairo_fill (cr); + } + + /* Set the clip */ + cairo_save (cr); + cairo_rectangle (cr, 0.5, 0.5, 6, height-2); + cairo_rectangle (cr, width-7.5, 0.5, 6 , height-2); + cairo_clip_preserve (cr); + + cairo_new_path (cr); + + /* Draw the handles */ + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners); + pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, 0.5+height); + + if (params->prelight) + { + CairoColor highlight; + ge_shade_color (spot, 1.5, &highlight); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, highlight.r, highlight.g, highlight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, spot->r, spot->g, spot->b); + cairo_set_source (cr, pattern); + } + else + { + CairoColor hilight; + ge_shade_color (fill, 1.5, &hilight); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + } + + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); + + /* Draw the border */ + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + if (params->prelight || params->disabled) + ge_cairo_set_color (cr, border); + else + clearlooks_set_border_gradient (cr, border, 1.2, 0, height); + cairo_stroke (cr); + + /* Draw handle lines */ + if (width > 14) + { + cairo_move_to (cr, 6, 0.5); + cairo_line_to (cr, 6, height-1); + + cairo_move_to (cr, width-7, 0.5); + cairo_line_to (cr, width-7, height-1); + + cairo_set_line_width (cr, 1.0); + cairo_set_source_rgba (cr, border->r, + border->g, + border->b, + 0.3); + cairo_stroke (cr); + } +} + +static void +clearlooks_draw_slider_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + cairo_set_line_width (cr, 1.0); + + if (!slider->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + cairo_translate (cr, x+0.5, y+0.5); + + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); + params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); + + if (width > 24) + params->style_functions->draw_gripdots (cr, colors, 0, 0, width-2, height-2, 3, 3, 0); +} + +static void +clearlooks_draw_progressbar_trough (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[6]; + CairoColor shadow; + cairo_pattern_t *pattern; + double radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0)); + + cairo_save (cr); + + cairo_set_line_width (cr, 1.0); + + /* Fill with bg color */ + ge_cairo_set_color (cr, &colors->bg[params->state_type]); + + cairo_rectangle (cr, x, y, width, height); + cairo_fill (cr); + + /* Create trough box */ + ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); + ge_cairo_set_color (cr, &colors->shade[3]); + cairo_fill (cr); + + /* Draw border */ + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners); + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + /* clip the corners of the shadows */ + ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); + cairo_clip (cr); + + ge_shade_color (border, 0.925, &shadow); + + /* Top shadow */ + cairo_rectangle (cr, x+1, y+1, width-2, 4); + pattern = cairo_pattern_create_linear (x, y, x, y+4); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + /* Left shadow */ + cairo_rectangle (cr, x+1, y+1, 4, height-2); + pattern = cairo_pattern_create_linear (x, y, x+4, y); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); +} + +static void +clearlooks_draw_progressbar_fill (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ProgressBarParameters *progressbar, + int x, int y, int width, int height, + gint offset) +{ + boolean is_horizontal = progressbar->orientation < 2; + double tile_pos = 0; + double stroke_width; + double radius; + int x_step; + + cairo_pattern_t *pattern; + CairoColor bg_shade; + CairoColor border; + CairoColor shadow; + + radius = MAX (0, params->radius - params->xthickness); + + cairo_save (cr); + + if (!is_horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP)) + ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height); + + /* Clamp the radius so that the _height_ fits ... */ + radius = MIN (radius, height / 2.0); + + stroke_width = height*2; + x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */ + + cairo_translate (cr, x, y); + + cairo_save (cr); + /* This is kind of nasty ... Clip twice from each side in case the length + * of the fill is smaller than twice the radius. */ + ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + /* Draw the background gradient */ + ge_shade_color (&colors->spot[1], 1.1, &bg_shade); + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, bg_shade.r, bg_shade.g, bg_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.6, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg_shade.r, bg_shade.g, bg_shade.b); + cairo_set_source (cr, pattern); + cairo_paint (cr); + cairo_pattern_destroy (pattern); + + /* Draw the Strokes */ + while (tile_pos <= width+x_step) + { + cairo_move_to (cr, stroke_width/2-x_step, 0); + cairo_line_to (cr, stroke_width-x_step, 0); + cairo_line_to (cr, stroke_width/2-x_step, height); + cairo_line_to (cr, -x_step, height); + + cairo_translate (cr, stroke_width, 0); + tile_pos += stroke_width; + } + + cairo_set_source_rgba (cr, colors->spot[2].r, + colors->spot[2].g, + colors->spot[2].b, + 0.15); + + cairo_fill (cr); + cairo_restore (cr); /* rounded clip region */ + + /* inner highlight border + * This is again kinda ugly. Draw once from each side, clipping away the other. */ + cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.5); + + /* left side */ + cairo_save (cr); + cairo_rectangle (cr, 0, 0, width / 2, height); + cairo_clip (cr); + + if (progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + else + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + /* right side */ + cairo_save (cr); + cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height); + cairo_clip (cr); + + if (progressbar->value < 1.0 || progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + else + ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + + /* Draw the dark lines and the shadow */ + cairo_save (cr); + /* Again, this weird clip area. */ + ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + border = colors->spot[2]; + border.a = 0.5; + shadow.r = 0.0; + shadow.g = 0.0; + shadow.b = 0.0; + shadow.a = 0.1; + + if (progressbar->pulsing) + { + /* At the beginning of the bar. */ + cairo_move_to (cr, 0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, -0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + if (progressbar->value < 1.0 || progressbar->pulsing) + { + /* At the end of the bar. */ + cairo_move_to (cr, width - 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, width + 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + + cairo_restore (cr); + + cairo_restore (cr); /* rotation, mirroring */ +} + +static void +clearlooks_draw_optionmenu (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const OptionMenuParameters *optionmenu, + int x, int y, int width, int height) +{ + SeparatorParameters separator; + int offset = params->ythickness + 1; + + params->style_functions->draw_button (cr, colors, params, x, y, width, height); + + separator.horizontal = FALSE; + params->style_functions->draw_separator (cr, colors, params, &separator, x+optionmenu->linepos, y + offset, 2, height - offset*2); +} + +static void +clearlooks_draw_menu_item_separator (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SeparatorParameters *separator, + int x, int y, int width, int height) +{ + cairo_save (cr); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + ge_cairo_set_color (cr, &colors->shade[5]); + + if (separator->horizontal) + cairo_rectangle (cr, x, y, width, 1); + else + cairo_rectangle (cr, x, y, 1, height); + + cairo_fill (cr); + + cairo_restore (cr); +} + +static void +clearlooks_draw_menubar0 (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const MenuBarParameters *menubar, + int x, int y, int width, int height) +{ +/* const CairoColor *light = &colors->shade[0]; */ + const CairoColor *dark = &colors->shade[3]; + + cairo_set_line_width (cr, 1); + cairo_translate (cr, x, y+0.5); + +/* cairo_move_to (cr, 0, 0); */ +/* cairo_line_to (cr, width, 0); */ +/* ge_cairo_set_color (cr, light); */ +/* cairo_stroke (cr); */ + + cairo_move_to (cr, 0, height-1); + cairo_line_to (cr, width, height-1); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); +} + +static void +clearlooks_draw_menubar2 (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const MenuBarParameters *menubar, + int x, int y, int width, int height) +{ + CairoColor lower; + cairo_pattern_t *pattern; + + ge_shade_color (&colors->bg[0], 0.96, &lower); + + cairo_translate (cr, x, y); + cairo_rectangle (cr, 0, 0, width, height); + + /* Draw the gradient */ + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, colors->bg[0].r, + colors->bg[0].g, + colors->bg[0].b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r, + lower.g, + lower.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + /* Draw bottom line */ + cairo_set_line_width (cr, 1.0); + cairo_move_to (cr, 0, height-0.5); + cairo_line_to (cr, width, height-0.5); + ge_cairo_set_color (cr, &colors->shade[3]); + cairo_stroke (cr); +} + +static void +clearlooks_draw_menubar1 (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const MenuBarParameters *menubar, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[3]; + + clearlooks_draw_menubar2 (cr, colors, params, menubar, + x, y, width, height); + + ge_cairo_set_color (cr, border); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); +} + + +static menubar_draw_proto clearlooks_menubar_draw[3] = +{ + clearlooks_draw_menubar0, + clearlooks_draw_menubar1, + clearlooks_draw_menubar2 +}; + +static void +clearlooks_draw_menubar (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const MenuBarParameters *menubar, + int x, int y, int width, int height) +{ + if (menubar->style < 0 || menubar->style > 3) + return; + + clearlooks_menubar_draw[menubar->style](cr, colors, params, menubar, + x, y, width, height); +} + +static void +clearlooks_get_frame_gap_clip (int x, int y, int width, int height, + const FrameParameters *frame, + ClearlooksRectangle *bevel, + ClearlooksRectangle *border) +{ + if (frame->gap_side == CL_GAP_TOP) + { + CLEARLOOKS_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, -0.5, + frame->gap_width - 3, 2.0); + CLEARLOOKS_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, -0.5, + frame->gap_width - 2, 2.0); + } + else if (frame->gap_side == CL_GAP_BOTTOM) + { + CLEARLOOKS_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, height - 2.5, + frame->gap_width - 3, 2.0); + CLEARLOOKS_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, height - 1.5, + frame->gap_width - 2, 2.0); + } + else if (frame->gap_side == CL_GAP_LEFT) + { + CLEARLOOKS_RECTANGLE_SET ((*bevel), -0.5, 1.5 + frame->gap_x, + 2.0, frame->gap_width - 3); + CLEARLOOKS_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x, + 1.0, frame->gap_width - 2); + } + else if (frame->gap_side == CL_GAP_RIGHT) + { + CLEARLOOKS_RECTANGLE_SET ((*bevel), width - 2.5, 1.5 + frame->gap_x, + 2.0, frame->gap_width - 3); + CLEARLOOKS_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x, + 1.0, frame->gap_width - 2); + } +} + +static void +clearlooks_draw_frame (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const FrameParameters *frame, + int x, int y, int width, int height) +{ + const CairoColor *border = frame->border; + const CairoColor *dark = (CairoColor*)&colors->shade[4]; + ClearlooksRectangle bevel_clip = {0, 0, 0, 0}; + ClearlooksRectangle frame_clip = {0, 0, 0, 0}; + double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + CairoColor hilight; + + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 1.05, &hilight); + + if (frame->shadow == CL_SHADOW_NONE) + return; + + if (frame->gap_x != -1) + clearlooks_get_frame_gap_clip (x, y, width, height, + frame, &bevel_clip, &frame_clip); + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y+0.5); + + /* save everything */ + cairo_save (cr); + /* Set clip for the bevel */ + if (frame->gap_x != -1) + { + /* Set clip for gap */ + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_rectangle (cr, -0.5, -0.5, width, height); + cairo_rectangle (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height); + cairo_clip (cr); + } + + /* Draw the bevel */ + if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT) + { + ge_cairo_set_color (cr, &hilight); + if (frame->shadow == CL_SHADOW_ETCHED_IN) + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, params->corners); + else + ge_cairo_rounded_rectangle (cr, 0, 0, width-2, height-2, radius, params->corners); + cairo_stroke (cr); + } + else if (frame->shadow != CL_SHADOW_NONE) + { + ShadowParameters shadow; + shadow.corners = params->corners; + shadow.shadow = frame->shadow; + clearlooks_draw_highlight_and_shade (cr, colors, &shadow, width, height, 0); + } + + /* restore the previous clip region */ + cairo_restore (cr); + cairo_save (cr); + if (frame->gap_x != -1) + { + /* Set clip for gap */ + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_rectangle (cr, -0.5, -0.5, width, height); + cairo_rectangle (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height); + cairo_clip (cr); + } + + /* Draw frame */ + if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT) + { + ge_cairo_set_color (cr, dark); + if (frame->shadow == CL_SHADOW_ETCHED_IN) + ge_cairo_rounded_rectangle (cr, 0, 0, width-2, height-2, radius, params->corners); + else + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, params->corners); + } + else + { + ge_cairo_set_color (cr, border); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + } + cairo_stroke (cr); + + cairo_restore (cr); +} + +static void +clearlooks_draw_tab (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const TabParameters *tab, + int x, int y, int width, int height) +{ + const CairoColor *border1 = &colors->shade[6]; + const CairoColor *border2 = &colors->shade[5]; + const CairoColor *stripe_fill = &colors->spot[1]; + const CairoColor *stripe_border = &colors->spot[2]; + const CairoColor *fill; + CairoColor hilight; + + cairo_pattern_t *pattern; + + double radius; + double strip_size; + + radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + /* Set clip */ + cairo_rectangle (cr, x, y, width, height); + cairo_clip (cr); + cairo_new_path (cr); + + /* Translate and set line width */ + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y+0.5); + + + /* Make the tabs slightly bigger than they should be, to create a gap */ + /* And calculate the strip size too, while you're at it */ + if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) + { + height += 3.0; + strip_size = 2.0/height; /* 2 pixel high strip */ + + if (tab->gap_side == CL_GAP_TOP) + cairo_translate (cr, 0.0, -3.0); /* gap at the other side */ + } + else + { + width += 3.0; + strip_size = 2.0/width; + + if (tab->gap_side == CL_GAP_LEFT) + cairo_translate (cr, -3.0, 0.0); /* gap at the other side */ + } + + /* Set the fill color */ + fill = &colors->bg[params->state_type]; + + /* Set tab shape */ + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, + radius, params->corners); + + /* Draw fill */ + ge_cairo_set_color (cr, fill); + cairo_fill (cr); + + + ge_shade_color (fill, 1.3, &hilight); + + /* Draw highlight */ + if (!params->active) + { + ShadowParameters shadow; + + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = params->corners; + + clearlooks_draw_highlight_and_shade (cr, colors, &shadow, + width, + height, radius); + } + + + if (params->active) + { + CairoColor shadow; + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + ge_shade_color (fill, 0.92, &shadow); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, hilight.r, hilight.g, hilight.b, 0.4); + cairo_pattern_add_color_stop_rgba (pattern, 1.0/height, hilight.r, hilight.g, hilight.b, 0.4); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, fill->r,fill->g,fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r,shadow.g,shadow.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + /* Draw shade */ + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b); + cairo_pattern_add_color_stop_rgba (pattern, strip_size, hilight.r, hilight.g, hilight.b, 0.5); + cairo_pattern_add_color_stop_rgba (pattern, 0.8, hilight.r, hilight.g, hilight.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + if (params->active) + { + ge_cairo_set_color (cr, border2); + cairo_stroke (cr); + } + else + { + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2 ); + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, border1->r, border1->g, border1->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, border2->r, border2->g, border2->b); + cairo_set_source (cr, pattern); + cairo_stroke (cr); + cairo_pattern_destroy (pattern); + } +} + +static void +clearlooks_draw_separator (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SeparatorParameters *separator, + int x, int y, int width, int height) +{ + CairoColor color = colors->shade[3]; + CairoColor hilight; + ge_shade_color (&color, 1.4, &hilight); + + cairo_save (cr); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + + if (separator->horizontal) + { + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y+0.5); + + cairo_move_to (cr, 0.0, 0.0); + cairo_line_to (cr, width, 0.0); + ge_cairo_set_color (cr, &color); + cairo_stroke (cr); + + cairo_move_to (cr, 0.0, 1.0); + cairo_line_to (cr, width, 1.0); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); + } + else + { + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y); + + cairo_move_to (cr, 0.0, 0.0); + cairo_line_to (cr, 0.0, height); + ge_cairo_set_color (cr, &color); + cairo_stroke (cr); + + cairo_move_to (cr, 1.0, 0.0); + cairo_line_to (cr, 1.0, height); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); + } + + cairo_restore (cr); +} + +static void +clearlooks_draw_list_view_header (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ListViewHeaderParameters *header, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[5]; + cairo_pattern_t *pattern; + CairoColor hilight; + CairoColor shadow; + + ge_shade_color (border, 1.5, &hilight); + ge_shade_color (border, 0.925, &shadow); + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + /* Draw highlight */ + if (header->order == CL_ORDER_FIRST) + { + cairo_move_to (cr, 0.5, height-1); + cairo_line_to (cr, 0.5, 0.5); + } + else + cairo_move_to (cr, 0.0, 0.5); + + cairo_line_to (cr, width, 0.5); + + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); + + /* Draw bottom border */ + cairo_move_to (cr, 0.0, height-0.5); + cairo_line_to (cr, width, height-0.5); + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + /* Draw bottom shade */ + pattern = cairo_pattern_create_linear (0.0, height-5.0, 0.0, height-1.0); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.3); + + cairo_rectangle (cr, 0.0, height-5.0, width, 4.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + /* Draw resize grip */ + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) + { + SeparatorParameters separator; + separator.horizontal = FALSE; + + if (params->ltr) + params->style_functions->draw_separator (cr, colors, params, &separator, + width-1.5, 4.0, 2, height-8.0); + else + params->style_functions->draw_separator (cr, colors, params, &separator, + 1.5, 4.0, 2, height-8.0); + } +} + +/* We can't draw transparent things here, since it will be called on the same + * surface multiple times, when placed on a handlebox_bin or dockitem_bin */ +static void +clearlooks_draw_toolbar (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ToolbarParameters *toolbar, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; + const CairoColor *dark = &colors->shade[3]; + CairoColor light; + ge_shade_color (fill, 1.1, &light); + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y); + + ge_cairo_set_color (cr, fill); + cairo_paint (cr); + + if (!toolbar->topmost) + { + /* Draw highlight */ + cairo_move_to (cr, 0, 0.5); + cairo_line_to (cr, width-1, 0.5); + ge_cairo_set_color (cr, &light); + cairo_stroke (cr); + } + + /* Draw shadow */ + cairo_move_to (cr, 0, height-0.5); + cairo_line_to (cr, width-1, height-0.5); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); +} + +static void +clearlooks_draw_menuitem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->spot[1]; + CairoColor fill_shade; + CairoColor border = colors->spot[2]; + cairo_pattern_t *pattern; + + ge_shade_color (&border, 1.05, &border); + ge_shade_color (fill, 0.85, &fill_shade); + cairo_set_line_width (cr, 1.0); + + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, widget->radius, widget->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); +} + +static void +clearlooks_draw_menubaritem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->spot[1]; + CairoColor fill_shade; + CairoColor border = colors->spot[2]; + cairo_pattern_t *pattern; + + ge_shade_color (&border, 1.05, &border); + ge_shade_color (fill, 0.85, &fill_shade); + + cairo_set_line_width (cr, 1.0); + ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1, height, widget->radius, widget->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill_shade.r, fill_shade.g, fill_shade.b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, &border); + cairo_stroke_preserve (cr); +} + +static void +clearlooks_draw_selected_cell (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + CairoColor upper_color; + CairoColor lower_color; + CairoColor border; + cairo_pattern_t *pattern; + cairo_save (cr); + + cairo_translate (cr, x, y); + + if (params->focus) + upper_color = colors->base[params->state_type]; + else + upper_color = colors->base[GTK_STATE_ACTIVE]; + + ge_shade_color(&upper_color, 0.92, &lower_color); + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, upper_color.r, + upper_color.g, + upper_color.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower_color.r, + lower_color.g, + lower_color.b); + + cairo_set_source (cr, pattern); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); + + ge_shade_color(&upper_color, 0.8, &border); + + cairo_move_to (cr, 0, 0.5); + cairo_rel_line_to (cr, width, 0); + cairo_move_to (cr, 0, height-0.5); + cairo_rel_line_to (cr, width, 0); + + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_restore (cr); +} + + +static void +clearlooks_draw_scrollbar_trough (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height) +{ + const CairoColor *bg = &colors->shade[2]; + const CairoColor *border = &colors->shade[5]; + CairoColor bg_shade; + cairo_pattern_t *pattern; + + ge_shade_color (bg, 0.95, &bg_shade); + + cairo_set_line_width (cr, 1); + /* cairo_translate (cr, x, y); */ + + if (scrollbar->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + cairo_translate (cr, x, y); + + /* Draw fill */ + cairo_rectangle (cr, 1, 0, width-2, height); + ge_cairo_set_color (cr, bg); + cairo_fill (cr); + + /* Draw shadow */ + pattern = cairo_pattern_create_linear (1, 0, 3, 0); + cairo_pattern_add_color_stop_rgb (pattern, 0, bg_shade.r, bg_shade.g, bg_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg->r, bg->g, bg->b); + cairo_rectangle (cr, 1, 0, 4, height); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + /* Draw border */ + ge_cairo_set_color (cr, border); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); +} + +static void +clearlooks_draw_scrollbar_stepper (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + const ScrollBarStepperParameters *stepper, + int x, int y, int width, int height) +{ + CairoCorners corners = CR_CORNER_NONE; + CairoColor border; + CairoColor s1, s2, s3, s4; + cairo_pattern_t *pattern; + ShadowParameters shadow; + double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + ge_shade_color(&colors->shade[6], 1.05, &border); + + if (scrollbar->horizontal) + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + } + else + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; + } + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners); + + if (scrollbar->horizontal) + pattern = cairo_pattern_create_linear (0, 0, 0, height); + else + pattern = cairo_pattern_create_linear (0, 0, width, 0); + + s2 = colors->bg[widget->state_type]; + ge_shade_color(&s2, 1.06, &s1); + ge_shade_color(&s2, 0.98, &s3); + ge_shade_color(&s2, 0.94, &s4); + + cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, s2.r, s2.g, s2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_translate (cr, 0.5, 0.5); + clearlooks_draw_top_left_highlight (cr, &s2, widget, width, height, (stepper->stepper == CL_STEPPER_A) ? radius : 0); + cairo_translate (cr, -0.5, -0.5); + + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); + clearlooks_set_border_gradient (cr, &border, 1.2, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0)); + cairo_stroke (cr); + + cairo_translate (cr, 0.5, 0.5); + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = corners; + /* + clearlooks_draw_highlight_and_shade (cr, &shadow, + width, + height, params->radius);*/ +} + +static void +clearlooks_draw_scrollbar_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height) +{ + if (scrollbar->junction & CL_JUNCTION_BEGIN) + { + if (scrollbar->horizontal) + { + x -= 1; + width += 1; + } + else + { + y -= 1; + height += 1; + } + } + if (scrollbar->junction & CL_JUNCTION_END) + { + if (scrollbar->horizontal) + width += 1; + else + height += 1; + } + + if (!scrollbar->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + cairo_translate (cr, x, y); + + if (scrollbar->has_color) + { + const CairoColor *border = &colors->shade[7]; + CairoColor fill = scrollbar->color; + CairoColor hilight; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + + if (widget->prelight) + ge_shade_color (&fill, 1.1, &fill); + + cairo_set_line_width (cr, 1); + + ge_shade_color (&fill, 1.3, &hilight); + ge_shade_color (&fill, 1.1, &shade1); + ge_shade_color (&fill, 1.05, &shade2); + ge_shade_color (&fill, 0.98, &shade3); + + pattern = cairo_pattern_create_linear (1, 1, 1, height-2); + cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade3.r, shade3.g, shade3.b); + cairo_pattern_add_color_stop_rgb (pattern, 1, fill.r, fill.g, fill.b); + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3); + + ge_cairo_set_color (cr, border); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); + } + else + { + const CairoColor *dark = &colors->shade[4]; + const CairoColor *light = &colors->shade[0]; + CairoColor border; + CairoColor s1, s2, s3, s4, s5; + cairo_pattern_t *pattern; + int bar_x, i; + + ge_shade_color(&colors->shade[6], 1.05, &border); + + s2 = colors->bg[widget->state_type]; + ge_shade_color(&s2, 1.06, &s1); + ge_shade_color(&s2, 0.98, &s3); + ge_shade_color(&s2, 0.94, &s4); + + pattern = cairo_pattern_create_linear(1, 1, 1, height-1); + cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, s2.r, s2.g, s2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b); + + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source(cr, pattern); + cairo_fill(cr); + cairo_pattern_destroy(pattern); + + clearlooks_set_border_gradient (cr, &border, 1.2, 0, height); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); + + cairo_move_to (cr, 1.5, height-1.5); + cairo_line_to (cr, 1.5, 1.5); + cairo_line_to (cr, width-1.5, 1.5); + ge_shade_color (&s2, 1.3, &s5); + cairo_set_source_rgba (cr, s5.r, s5.g, s5.b, 0.5); + cairo_stroke(cr); + + /* draw handles */ + cairo_set_line_width (cr, 1); + + bar_x = width/2 - 4; + cairo_translate(cr, 0.5, 0.5); + for (i=0; i<3; i++) + { + cairo_move_to (cr, bar_x, 4); + cairo_line_to (cr, bar_x, height-5); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); + + cairo_move_to (cr, bar_x+1, 4); + cairo_line_to (cr, bar_x+1, height-5); + ge_cairo_set_color (cr, light); + cairo_stroke (cr); + + bar_x += 3; + } + } + +} + +static void +clearlooks_draw_statusbar (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + const CairoColor *dark = &colors->shade[3]; + CairoColor hilight; + + ge_shade_color (dark, 1.4, &hilight); + + cairo_set_line_width (cr, 1); + cairo_translate (cr, x, y+0.5); + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, width, 0); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); + + cairo_translate (cr, 0, 1); + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, width, 0); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); +} + +static void +clearlooks_draw_menu_frame (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[5]; + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); +/* + cairo_set_source_rgba (cr, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b, 0.9); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); +*/ + ge_cairo_set_color (cr, border); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); +} + +static void +clearlooks_draw_tooltip (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + CairoColor border; + + ge_shade_color (&colors->bg[widget->state_type], 0.6, &border); + + cairo_save (cr); + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + ge_cairo_set_color (cr, &colors->bg[widget->state_type]); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + ge_cairo_set_color (cr, &border); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); + + cairo_restore (cr); +} + +static void +clearlooks_draw_handle (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const HandleParameters *handle, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->bg[params->state_type]; + int num_bars = 6; /* shut up gcc warnings */ + int bar_spacing; + + switch (handle->type) + { + case CL_HANDLE_TOOLBAR: + num_bars = 6; + bar_spacing = 3; + break; + case CL_HANDLE_SPLITTER: + num_bars = 16; + bar_spacing = 3; + break; + } + + if (params->prelight) + { + cairo_rectangle (cr, x, y, width, height); + ge_cairo_set_color (cr, fill); + cairo_fill (cr); + } + + cairo_translate (cr, x+0.5, y+0.5); + + cairo_set_line_width (cr, 1); + + if (handle->horizontal) + { + params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, num_bars, 2, 0.1); + } + else + { + params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, 2, num_bars, 0.1); + } +} + +static void +clearlooks_draw_resize_grip (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ResizeGripParameters *grip, + int x, int y, int width, int height) +{ + const CairoColor *dark = &colors->shade[4]; + CairoColor hilight; + int lx, ly; + int x_down; + int y_down; + int dots; + + ge_shade_color (dark, 1.5, &hilight); + + /* The number of dots fitting into the area. Just hardcoded to 4 right now. */ + /* dots = MIN (width - 2, height - 2) / 3; */ + dots = 4; + + cairo_save (cr); + + switch (grip->edge) + { + case CL_WINDOW_EDGE_NORTH_EAST: + x_down = 0; + y_down = 0; + cairo_translate (cr, x + width - 3*dots + 2, y + 1); + break; + case CL_WINDOW_EDGE_SOUTH_EAST: + x_down = 0; + y_down = 1; + cairo_translate (cr, x + width - 3*dots + 2, y + height - 3*dots + 2); + break; + case CL_WINDOW_EDGE_SOUTH_WEST: + x_down = 1; + y_down = 1; + cairo_translate (cr, x + 1, y + height - 3*dots + 2); + break; + case CL_WINDOW_EDGE_NORTH_WEST: + x_down = 1; + y_down = 0; + cairo_translate (cr, x + 1, y + 1); + break; + default: + /* Not implemented. */ + return; + } + + for (lx = 0; lx < dots; lx++) /* horizontally */ + { + for (ly = 0; ly <= lx; ly++) /* vertically */ + { + int mx, my; + mx = x_down * dots + (1 - x_down * 2) * lx - x_down; + my = y_down * dots + (1 - y_down * 2) * ly - y_down; + + ge_cairo_set_color (cr, &hilight); + cairo_rectangle (cr, mx*3-1, my*3-1, 2, 2); + cairo_fill (cr); + + ge_cairo_set_color (cr, dark); + cairo_rectangle (cr, mx*3-1, my*3-1, 1, 1); + cairo_fill (cr); + } + } + + cairo_restore (cr); +} + +static void +clearlooks_draw_radiobutton (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height) +{ + const CairoColor *border; + const CairoColor *dot; + CairoColor shadow; + CairoColor highlight; + cairo_pattern_t *pt; + gboolean inconsistent; + gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); + draw_bullet |= inconsistent; + + if (widget->disabled) + { + border = &colors->shade[5]; + dot = &colors->shade[6]; + } + else + { + border = &colors->shade[6]; + dot = &colors->text[0]; + } + + ge_shade_color (&widget->parentbg, 0.9, &shadow); + ge_shade_color (&widget->parentbg, 1.1, &highlight); + + pt = cairo_pattern_create_linear (0, 0, 13, 13); + cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g); + cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5); + cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5); + cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b); + + cairo_translate (cr, x, y); + + cairo_set_line_width (cr, 2); + cairo_arc (cr, 7, 7, 6, 0, G_PI*2); + cairo_set_source (cr, pt); + cairo_stroke (cr); + cairo_pattern_destroy (pt); + + cairo_set_line_width (cr, 1); + + cairo_arc (cr, 7, 7, 5.5, 0, G_PI*2); + + if (!widget->disabled) + { + ge_cairo_set_color (cr, &colors->base[0]); + cairo_fill_preserve (cr); + } + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + if (draw_bullet) + { + if (inconsistent) + { + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width (cr, 4); + + cairo_move_to(cr, 5, 7); + cairo_line_to(cr, 9, 7); + + ge_cairo_set_color (cr, dot); + cairo_stroke (cr); + } + else + { + cairo_arc (cr, 7, 7, 3, 0, G_PI*2); + ge_cairo_set_color (cr, dot); + cairo_fill (cr); + + cairo_arc (cr, 6, 6, 1, 0, G_PI*2); + cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); + cairo_fill (cr); + } + } +} + +static void +clearlooks_draw_checkbox (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height) +{ + const CairoColor *border; + const CairoColor *dot; + gboolean inconsistent = FALSE; + gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); + draw_bullet |= inconsistent; + + if (widget->disabled) + { + border = &colors->shade[5]; + dot = &colors->shade[6]; + } + else + { + border = &colors->shade[6]; + dot = &colors->text[GTK_STATE_NORMAL]; + } + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + if (widget->xthickness > 2 && widget->ythickness > 2) + { + widget->style_functions->draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, 1, CR_CORNER_ALL); + + /* Draw the rectangle for the checkbox itself */ + ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + } + else + { + /* Draw the rectangle for the checkbox itself */ + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + } + + if (!widget->disabled) + { + ge_cairo_set_color (cr, &colors->base[0]); + cairo_fill_preserve (cr); + } + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + if (draw_bullet) + { + if (inconsistent) /* Inconsistent */ + { + cairo_set_line_width (cr, 2.0); + cairo_move_to (cr, 3, height*0.5); + cairo_line_to (cr, width-3, height*0.5); + } + else + { + cairo_set_line_width (cr, 1.7); + cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5)); + cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7)); + + cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7), + 0.5 + (width*0.5), (height*0.4), + 0.5 + (width*0.70), (height*0.25)); + + } + + ge_cairo_set_color (cr, dot); + cairo_stroke (cr); + } +} + +static void +clearlooks_draw_normal_arrow (cairo_t *cr, const CairoColor *color, + double x, double y, double width, double height) +{ + double arrow_width; + double arrow_height; + double line_width_2; + + cairo_save (cr); + + arrow_width = MIN (height * 2.0 + MAX (1.0, ceil (height * 2.0 / 6.0 * 2.0) / 2.0) / 2.0, width); + line_width_2 = MAX (1.0, ceil (arrow_width / 6.0 * 2.0) / 2.0) / 2.0; + arrow_height = arrow_width / 2.0 + line_width_2; + + cairo_translate (cr, x, y - arrow_height / 2.0); + + cairo_move_to (cr, -arrow_width / 2.0, line_width_2); + cairo_line_to (cr, -arrow_width / 2.0 + line_width_2, 0); + /* cairo_line_to (cr, 0, arrow_height - line_width_2); */ + cairo_arc_negative (cr, 0, arrow_height - 2*line_width_2 - 2*line_width_2 * sqrt(2), 2*line_width_2, G_PI_2 + G_PI_4, G_PI_4); + cairo_line_to (cr, arrow_width / 2.0 - line_width_2, 0); + cairo_line_to (cr, arrow_width / 2.0, line_width_2); + cairo_line_to (cr, 0, arrow_height); + cairo_close_path (cr); + + ge_cairo_set_color (cr, color); + cairo_fill (cr); + + cairo_restore (cr); +} + +static void +clearlooks_draw_combo_arrow (cairo_t *cr, const CairoColor *color, + double x, double y, double width, double height) +{ + double arrow_width = MIN (height * 2 / 3.0, width); + double arrow_height = arrow_width / 2.0; + double gap_size = 1.0 * arrow_height; + + cairo_save (cr); + cairo_translate (cr, x, y - (arrow_height + gap_size) / 2.0); + cairo_rotate (cr, G_PI); + clearlooks_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height); + cairo_restore (cr); + + clearlooks_draw_normal_arrow (cr, color, x, y + (arrow_height + gap_size) / 2.0, arrow_width, arrow_height); +} + +static void +_clearlooks_draw_arrow (cairo_t *cr, const CairoColor *color, + ClearlooksDirection dir, ClearlooksArrowType type, + double x, double y, double width, double height) +{ + double rotate; + + if (dir == CL_DIRECTION_LEFT) + rotate = G_PI*1.5; + else if (dir == CL_DIRECTION_RIGHT) + rotate = G_PI*0.5; + else if (dir == CL_DIRECTION_UP) + rotate = G_PI; + else if (dir == CL_DIRECTION_DOWN) + rotate = 0; + else + return; + + if (type == CL_ARROW_NORMAL) + { + cairo_translate (cr, x, y); + cairo_rotate (cr, -rotate); + clearlooks_draw_normal_arrow (cr, color, 0, 0, width, height); + } + else if (type == CL_ARROW_COMBO) + { + cairo_translate (cr, x, y); + clearlooks_draw_combo_arrow (cr, color, 0, 0, width, height); + } +} + +static void +clearlooks_draw_arrow (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ArrowParameters *arrow, + int x, int y, int width, int height) +{ + const CairoColor *color = &colors->fg[widget->state_type]; + gdouble tx, ty; + + tx = x + width/2.0; + ty = y + height/2.0; + + if (widget->disabled) + { + _clearlooks_draw_arrow (cr, &colors->shade[0], + arrow->direction, arrow->type, + tx+0.5, ty+0.5, width, height); + } + + cairo_identity_matrix (cr); + + _clearlooks_draw_arrow (cr, color, arrow->direction, arrow->type, + tx, ty, width, height); +} + +void +clearlooks_register_style_classic (ClearlooksStyleFunctions *functions) +{ + g_assert (functions); + + functions->draw_button = clearlooks_draw_button; + functions->draw_scale_trough = clearlooks_draw_scale_trough; + functions->draw_progressbar_trough = clearlooks_draw_progressbar_trough; + functions->draw_progressbar_fill = clearlooks_draw_progressbar_fill; + functions->draw_slider_button = clearlooks_draw_slider_button; + functions->draw_entry = clearlooks_draw_entry; + functions->draw_spinbutton = clearlooks_draw_spinbutton; + functions->draw_spinbutton_down = clearlooks_draw_spinbutton_down; + functions->draw_optionmenu = clearlooks_draw_optionmenu; + functions->draw_inset = clearlooks_draw_inset; + functions->draw_menubar = clearlooks_draw_menubar; + functions->draw_tab = clearlooks_draw_tab; + functions->draw_frame = clearlooks_draw_frame; + functions->draw_separator = clearlooks_draw_separator; + functions->draw_menu_item_separator = clearlooks_draw_menu_item_separator; + functions->draw_list_view_header = clearlooks_draw_list_view_header; + functions->draw_toolbar = clearlooks_draw_toolbar; + functions->draw_menuitem = clearlooks_draw_menuitem; + functions->draw_menubaritem = clearlooks_draw_menubaritem; + functions->draw_selected_cell = clearlooks_draw_selected_cell; + functions->draw_scrollbar_stepper = clearlooks_draw_scrollbar_stepper; + functions->draw_scrollbar_slider = clearlooks_draw_scrollbar_slider; + functions->draw_scrollbar_trough = clearlooks_draw_scrollbar_trough; + functions->draw_statusbar = clearlooks_draw_statusbar; + functions->draw_menu_frame = clearlooks_draw_menu_frame; + functions->draw_tooltip = clearlooks_draw_tooltip; + functions->draw_handle = clearlooks_draw_handle; + functions->draw_resize_grip = clearlooks_draw_resize_grip; + functions->draw_arrow = clearlooks_draw_arrow; + functions->draw_checkbox = clearlooks_draw_checkbox; + functions->draw_radiobutton = clearlooks_draw_radiobutton; + functions->draw_shadow = clearlooks_draw_shadow; + functions->draw_slider = clearlooks_draw_slider; + functions->draw_gripdots = clearlooks_draw_gripdots; +} diff --git a/libs/clearlooks-newer/clearlooks_draw.h b/libs/clearlooks-newer/clearlooks_draw.h new file mode 100644 index 0000000000..a3f26764da --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_draw.h @@ -0,0 +1,17 @@ +#ifndef CLEARLOOKS_DRAW_H +#define CLEARLOOKS_DRAW_H + +#include "clearlooks_types.h" +#include "clearlooks_style.h" + +#include <gtk/gtk.h> +#include <gdk/gdk.h> + +#include <cairo.h> + +GE_INTERNAL void clearlooks_register_style_classic (ClearlooksStyleFunctions *functions); +GE_INTERNAL void clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions); +GE_INTERNAL void clearlooks_register_style_gummy (ClearlooksStyleFunctions *functions); +GE_INTERNAL void clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions); + +#endif /* CLEARLOOKS_DRAW_H */ diff --git a/libs/clearlooks-newer/clearlooks_draw_glossy.c b/libs/clearlooks-newer/clearlooks_draw_glossy.c new file mode 100644 index 0000000000..8a5921efc2 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_draw_glossy.c @@ -0,0 +1,1422 @@ +/* Clearlooks Glossy style + * Copyright (C) 2006 Benjamin Berg + * Copyright (C) 2007 Andrea Cimitan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Andrea Cimitan <andrea.cimitan@gmail.com> + * and Benjamin Berg <benjamin@sipsolutions.net> + * Based on code by Richard Stellingwerff <remenic@gmail.com> + * and Daniel Borgmann <daniel.borgmann@gmail.com> + * from the ubuntulooks engine. + */ + +#include "clearlooks_draw.h" +#include "clearlooks_style.h" +#include "clearlooks_types.h" + +#include "support.h" +#include <ge-support.h> + +#include <cairo.h> + + +static void +clearlooks_draw_glossy_gradient (cairo_t *cr, + double x, double y, int width, int height, + const CairoColor *color, + gboolean disabled, gboolean radius, CairoCorners corners) +{ + CairoColor a, b, c, d; + cairo_pattern_t *pt; + + ge_shade_color (color, disabled? 1.06 : 1.16, &a); + ge_shade_color (color, disabled? 1.02 : 1.08, &b); + ge_shade_color (color, disabled? 0.98 : 1.00, &c); + ge_shade_color (color, disabled? 1.02 : 1.08, &d); + + pt = cairo_pattern_create_linear (x, y, x, y+height); + cairo_pattern_add_color_stop_rgb (pt, 0.0, a.r, a.g, a.b); + cairo_pattern_add_color_stop_rgb (pt, 0.5, b.r, b.g, b.b); + cairo_pattern_add_color_stop_rgb (pt, 0.5, c.r, c.g, c.b); + cairo_pattern_add_color_stop_rgb (pt, 1.0, d.r, d.g, d.b); + + cairo_set_source (cr, pt); + ge_cairo_rounded_rectangle (cr, x, y, width, height, radius, corners); + cairo_fill (cr); + + cairo_pattern_destroy (pt); +} + +static void +clearlooks_set_mixed_color (cairo_t *cr, + const CairoColor *color1, + const CairoColor *color2, + gdouble mix_factor) +{ + CairoColor composite; + + ge_mix_color (color1, color2, mix_factor, &composite); + ge_cairo_set_color (cr, &composite); +} + +static void +clearlooks_glossy_draw_inset (cairo_t *cr, + const CairoColor *bg_color, + double x, double y, double w, double h, + double radius, uint8 corners) +{ + CairoColor shadow; + CairoColor highlight; + + /* not really sure of shading ratios... we will think */ + ge_shade_color (bg_color, 0.93, &shadow); + ge_shade_color (bg_color, 1.07, &highlight); + + /* highlight */ + cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */ + + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.75, G_PI * 2); + else + cairo_line_to (cr, x + w, y); + + if (corners & CR_CORNER_BOTTOMRIGHT) + cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, G_PI * 0.5); + else + cairo_line_to (cr, x + w, y + h); + + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.5, G_PI * 0.75); + else + cairo_line_to (cr, x, y + h); + + ge_cairo_set_color (cr, &highlight); + cairo_stroke (cr); + + /* shadow */ + cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188)); + + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI); + else + cairo_line_to (cr, x, y + h); + + if (corners & CR_CORNER_TOPLEFT) + cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5); + else + cairo_line_to (cr, x, y); + + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75); + else + cairo_line_to (cr, x + w, y); + + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); +} + +static void +clearlooks_glossy_draw_light_inset (cairo_t *cr, + const CairoColor *bg_color, + double x, double y, double w, double h, + double radius, uint8 corners) +{ + CairoColor shadow; + CairoColor highlight; + + /* not really sure of shading ratios... we will think */ + ge_shade_color (bg_color, 0.95, &shadow); + ge_shade_color (bg_color, 1.05, &highlight); + + /* highlight */ + cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */ + + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.75, G_PI * 2); + else + cairo_line_to (cr, x + w, y); + + if (corners & CR_CORNER_BOTTOMRIGHT) + cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, G_PI * 0.5); + else + cairo_line_to (cr, x + w, y + h); + + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.5, G_PI * 0.75); + else + cairo_line_to (cr, x, y + h); + + ge_cairo_set_color (cr, &highlight); + cairo_stroke (cr); + + /* shadow */ + cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188)); + + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI); + else + cairo_line_to (cr, x, y + h); + + if (corners & CR_CORNER_TOPLEFT) + cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5); + else + cairo_line_to (cr, x, y); + + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75); + else + cairo_line_to (cr, x + w, y); + + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); +} + +static void +clearlooks_glossy_draw_highlight_and_shade (cairo_t *cr, + const CairoColor *bg_color, + const ShadowParameters *params, + int width, int height, gdouble radius) +{ + CairoColor shadow; + CairoColor highlight; + uint8 corners = params->corners; + double x = 1.0; + double y = 1.0; + + /* not really sure of shading ratios... we will think */ + ge_shade_color (bg_color, 0.8, &shadow); + ge_shade_color (bg_color, 1.2, &highlight); + + cairo_save (cr); + + /* Top/Left highlight */ + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_move_to (cr, x, y+height-radius); + else + cairo_move_to (cr, x, y+height); + + ge_cairo_rounded_corner (cr, x, y, radius, corners & CR_CORNER_TOPLEFT); + + if (corners & CR_CORNER_TOPRIGHT) + cairo_line_to (cr, x+width-radius, y); + else + cairo_line_to (cr, x+width, y); + + if (params->shadow & CL_SHADOW_OUT) + cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); + else + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5); + + cairo_stroke (cr); + + /* Bottom/Right highlight -- this includes the corners */ + cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */ + ge_cairo_rounded_corner (cr, x+width, y, radius, corners & CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, x+width, y+height, radius, corners & CR_CORNER_BOTTOMRIGHT); + ge_cairo_rounded_corner (cr, x, y+height, radius, corners & CR_CORNER_BOTTOMLEFT); + + if (params->shadow & CL_SHADOW_OUT) + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5); + else + cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); + + cairo_stroke (cr); + + cairo_restore (cr); +} + +static void +clearlooks_glossy_draw_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + double xoffset = 0, yoffset = 0; + CairoColor fill = colors->bg[params->state_type]; + CairoColor border_normal = colors->shade[6]; + CairoColor border_disabled = colors->shade[4]; + double radius; + + cairo_pattern_t *pattern; + + cairo_save (cr); + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + /* Shadows and Glow */ + if (params->xthickness == 3 || params->ythickness == 3) + { + if (params->xthickness == 3) + xoffset = 1; + if (params->ythickness == 3) + yoffset = 1; + } + + radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0, (height - 2.0 - 2*yoffset) / 2.0)); + + if (params->xthickness == 3 || params->ythickness == 3) + { + cairo_translate (cr, 0.5, 0.5); + + /* if (params->enable_glow && !params->active && !params->disabled) */ + if (params->prelight && params->enable_glow && !params->active) + { + /* Glow becomes a shadow to have 3d prelight buttons :) */ + CairoColor glow; + + radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0)); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius+1, params->corners); + ge_shade_color (¶ms->parentbg, 0.96, &glow); + ge_cairo_set_color (cr, &glow); + cairo_stroke (cr); + + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius+1, params->corners); + ge_shade_color (¶ms->parentbg, 0.92, &glow); + ge_cairo_set_color (cr, &glow); + cairo_stroke (cr); + } + + /* if (!(params->enable_glow && !params->active && !params->disabled)) */ + if (!(params->prelight && params->enable_glow && !params->active)) + if (!(params->disabled)) + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, params->radius+1, params->corners); + else + /*Draw a lighter inset */ + clearlooks_glossy_draw_light_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, params->radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); + } + + clearlooks_draw_glossy_gradient (cr, xoffset+1, yoffset+1, + width-(xoffset*2)-2, height-(yoffset*2)-2, + &fill, params->disabled, radius, params->corners); + + /* Pressed button shadow */ + if (params->active) + { + CairoColor shadow; + ge_shade_color (&fill, 0.92, &shadow); + + cairo_save (cr); + + ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height, radius, params->corners & (CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMLEFT)); + cairo_clip (cr); + cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3); + + pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2); + + pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); + } + + /* Default button highlight */ + if (params->is_default && !params->active && !params->disabled) + { + const CairoColor *glow = &colors->spot[0]; + double hh = (height-5)/2.0 + 1; + + cairo_rectangle (cr, 3.5, 3.5, width-7, height-7); + ge_cairo_set_color (cr, glow); + cairo_stroke (cr); + + glow = &colors->spot[0]; + cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, -hh); + cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, hh); + ge_cairo_set_color (cr, glow); + cairo_stroke (cr); + + hh--; + + glow = &colors->spot[1]; + cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, hh); + cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, -hh); + ge_cairo_set_color (cr, glow); + cairo_stroke (cr); + } + + /* Border */ + if (params->is_default || (params->prelight && params->enable_glow)) + border_normal = colors->spot[2]; + /* ge_mix_color (&border_normal, &colors->spot[2], 0.5, &border_normal); */ + if (params->disabled) + ge_cairo_set_color (cr, &border_disabled); + else + clearlooks_set_mixed_color (cr, &border_normal, &fill, 0.2); + ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5, + width-(xoffset*2)-1, height-(yoffset*2)-1, + radius, params->corners); + cairo_stroke (cr); + cairo_restore (cr); +} + +static void +clearlooks_glossy_draw_progressbar_trough (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[6]; + CairoColor shadow; + cairo_pattern_t *pattern; + double radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0)); + + cairo_save (cr); + + cairo_set_line_width (cr, 1.0); + + /* Fill with bg color */ + ge_cairo_set_color (cr, &colors->bg[params->state_type]); + + cairo_rectangle (cr, x, y, width, height); + cairo_fill (cr); + + /* Create trough box */ + ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); + ge_cairo_set_color (cr, &colors->shade[2]); + cairo_fill (cr); + + /* Draw border */ + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners); + clearlooks_set_mixed_color (cr, border, &colors->shade[2], 0.3); + cairo_stroke (cr); + + /* clip the corners of the shadows */ + ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); + cairo_clip (cr); + + ge_shade_color (border, 0.92, &shadow); + + /* Top shadow */ + cairo_rectangle (cr, x+1, y+1, width-2, 4); + pattern = cairo_pattern_create_linear (x, y, x, y+4); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + /* Left shadow */ + cairo_rectangle (cr, x+1, y+1, 4, height-2); + pattern = cairo_pattern_create_linear (x, y, x+4, y); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); +} + +static void +clearlooks_glossy_draw_progressbar_fill (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ProgressBarParameters *progressbar, + int x, int y, int width, int height, + gint offset) +{ + boolean is_horizontal = progressbar->orientation < 2; + double tile_pos = 0; + double stroke_width; + double radius; + int x_step; + + cairo_pattern_t *pattern; + CairoColor a; + CairoColor b; + CairoColor e; + CairoColor border; + CairoColor shadow; + + radius = MAX (0, params->radius - params->xthickness); + + cairo_save (cr); + + if (!is_horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP)) + ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height); + + /* Clamp the radius so that the _height_ fits ... */ + radius = MIN (radius, height / 2.0); + + stroke_width = height*2; + x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */ + + cairo_translate (cr, x, y); + + cairo_save (cr); + /* This is kind of nasty ... Clip twice from each side in case the length + * of the fill is smaller than twice the radius. */ + ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + /* Draw the background gradient */ + ge_shade_color (&colors->spot[1], 1.16, &a); + ge_shade_color (&colors->spot[1], 1.08, &b); + ge_shade_color (&colors->spot[1], 1.08, &e); + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, a.r, a.g, a.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, b.r, b.g, b.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, e.r, e.g, e.b); + cairo_set_source (cr, pattern); + cairo_paint (cr); + cairo_pattern_destroy (pattern); + + /* Draw the Strokes */ + while (tile_pos <= width+x_step) + { + cairo_move_to (cr, stroke_width/2-x_step, 0); + cairo_line_to (cr, stroke_width-x_step, 0); + cairo_line_to (cr, stroke_width/2-x_step, height); + cairo_line_to (cr, -x_step, height); + + cairo_translate (cr, stroke_width, 0); + tile_pos += stroke_width; + } + + cairo_set_source_rgba (cr, colors->spot[2].r, + colors->spot[2].g, + colors->spot[2].b, + 0.15); + + cairo_fill (cr); + cairo_restore (cr); /* rounded clip region */ + + /* inner highlight border + * This is again kinda ugly. Draw once from each side, clipping away the other. */ + cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.3); + + /* left side */ + cairo_save (cr); + cairo_rectangle (cr, 0, 0, width / 2, height); + cairo_clip (cr); + + if (progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + else + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + /* right side */ + cairo_save (cr); + cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height); + cairo_clip (cr); + + if (progressbar->value < 1.0 || progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + else + ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + + /* Draw the dark lines and the shadow */ + cairo_save (cr); + /* Again, this weird clip area. */ + ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + border = colors->spot[2]; + border.a = 0.5; + ge_shade_color (&colors->shade[6], 0.92, &shadow); + shadow.a = 0.2; + + if (progressbar->pulsing) + { + /* At the beginning of the bar. */ + cairo_move_to (cr, 0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, -0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + if (progressbar->value < 1.0 || progressbar->pulsing) + { + /* At the end of the bar. */ + cairo_move_to (cr, width - 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, width + 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + + cairo_restore (cr); + + cairo_restore (cr); /* rotation, mirroring */ +} + +static void +clearlooks_glossy_scale_draw_gradient (cairo_t *cr, + const CairoColor *c1, + const CairoColor *c2, + const CairoColor *c3, + int x, int y, int width, int height, + boolean horizontal) +{ + cairo_pattern_t *pattern; + + pattern = cairo_pattern_create_linear (0, 0, horizontal ? 0 : width, horizontal ? height : 0); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b); + + cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + clearlooks_set_mixed_color (cr, c3, c1, 0.3); + ge_cairo_stroke_rectangle (cr, x, y, width, height); +} + +#define TROUGH_SIZE 6 +static void +clearlooks_glossy_draw_scale_trough (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + int trough_width, trough_height; + double translate_x, translate_y; + + if (slider->horizontal) + { + trough_width = width-3; + trough_height = TROUGH_SIZE-2; + + translate_x = x + 0.5; + translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2); + } + else + { + trough_width = TROUGH_SIZE-2; + trough_height = height-3; + + translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2); + translate_y = y + 0.5; + } + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, translate_x, translate_y); + + if (!slider->fill_level) + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0); + + cairo_translate (cr, 1, 1); + + if (!slider->lower && !slider->fill_level) + clearlooks_glossy_scale_draw_gradient (cr, &colors->shade[3], /* top */ + &colors->shade[2], /* bottom */ + &colors->shade[6], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal); + else + clearlooks_glossy_scale_draw_gradient (cr, &colors->spot[1], /* top */ + &colors->spot[0], /* bottom */ + &colors->spot[2], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal); +} + +static void +clearlooks_glossy_draw_tab (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const TabParameters *tab, + int x, int y, int width, int height) +{ + + const CairoColor *border = &colors->shade[5]; + const CairoColor *stripe_fill = &colors->spot[1]; + const CairoColor *stripe_border = &colors->spot[2]; + const CairoColor *fill; + CairoColor hilight; + + cairo_pattern_t *pattern; + + double radius; + double strip_size; + + radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + /* Set clip */ + cairo_rectangle (cr, x, y, width, height); + cairo_clip (cr); + cairo_new_path (cr); + + /* Translate and set line width */ + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y+0.5); + + + /* Make the tabs slightly bigger than they should be, to create a gap */ + /* And calculate the strip size too, while you're at it */ + if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) + { + height += 3.0; + strip_size = 2.0/height; /* 2 pixel high strip */ + + if (tab->gap_side == CL_GAP_TOP) + cairo_translate (cr, 0.0, -3.0); /* gap at the other side */ + } + else + { + width += 3.0; + strip_size = 2.0/width; + + if (tab->gap_side == CL_GAP_LEFT) + cairo_translate (cr, -3.0, 0.0); /* gap at the other side */ + } + + /* Set the fill color */ + fill = &colors->bg[params->state_type]; + + /* Set tab shape */ + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, + radius, params->corners); + + /* Draw fill */ + ge_cairo_set_color (cr, fill); + cairo_fill (cr); + + ge_shade_color (fill, 1.3, &hilight); + + /* Draw highlight */ + if (!params->active) + { + ShadowParameters shadow; + + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = params->corners; + + clearlooks_glossy_draw_highlight_and_shade (cr, &colors->bg[0], &shadow, + width, + height, radius); + } + + if (params->active) + { + CairoColor shadow, hilight, f1, f2; + + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + ge_shade_color (fill, 1.06, &shadow); + ge_shade_color (fill, 1.18, &hilight); + ge_shade_color (fill, 1.12, &f1); + ge_shade_color (fill, 1.06, &f2); + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, hilight.r, hilight.g, hilight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, hilight.r, hilight.g, hilight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, f1.r, f1.g, f1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.45, f2.r, f2.g, f2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.45, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r, shadow.g, shadow.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + /* Draw shade */ + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.5); + cairo_pattern_add_color_stop_rgba (pattern, 0.8, fill->r, fill->g, fill->b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + if (params->active) + { + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + } + else + { + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2); + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); + cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r, border->g, border->b); + cairo_set_source (cr, pattern); + cairo_stroke (cr); + cairo_pattern_destroy (pattern); + } +} + +static void +clearlooks_glossy_draw_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[7]; + CairoColor fill; + CairoColor hilight; + CairoColor a, b, c, d; + cairo_pattern_t *pattern; + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y); + + cairo_translate (cr, -0.5, -0.5); + + ge_shade_color (&colors->bg[params->state_type], 1.0, &fill); + if (params->prelight) + ge_shade_color (&fill, 1.1, &fill); + + ge_shade_color (&fill, 1.25, &hilight); + ge_shade_color (&fill, 1.16, &a); + ge_shade_color (&fill, 1.08, &b); + ge_shade_color (&fill, 1.0, &c); + ge_shade_color (&fill, 1.08, &d); + + pattern = cairo_pattern_create_linear (1, 1, 1, height-2); + cairo_pattern_add_color_stop_rgb (pattern, 0, a.r, a.g, a.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, b.r, b.g, b.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, c.r, c.g, c.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, d.r, d.g, d.b); + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + clearlooks_set_mixed_color (cr, border, &fill, 0.2); + if (params->prelight) + ge_cairo_set_color (cr, &colors->spot[2]); + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, 2.5, params->corners); + cairo_stroke (cr); + + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, 2.0, params->corners); + cairo_stroke (cr); +} + +static void +clearlooks_glossy_draw_slider_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0)); + + cairo_set_line_width (cr, 1.0); + + if (!slider->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + cairo_translate (cr, x+0.5, y+0.5); + + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); + params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); +} + +static void +clearlooks_glossy_draw_scrollbar_stepper (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + const ScrollBarStepperParameters *stepper, + int x, int y, int width, int height) +{ + CairoCorners corners = CR_CORNER_NONE; + const CairoColor *border = &colors->shade[7]; + CairoColor fill, s1, s2, s4; + cairo_pattern_t *pattern; + ShadowParameters shadow; + double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + if (scrollbar->horizontal) + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + } + else + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; + } + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners); + + if (scrollbar->horizontal) + pattern = cairo_pattern_create_linear (0, 0, 0, height); + else + pattern = cairo_pattern_create_linear (0, 0, width, 0); + + fill = colors->bg[widget->state_type]; + ge_shade_color(&fill, 1.16, &s1); + ge_shade_color(&fill, 1.08, &s2); + ge_shade_color(&fill, 1.08, &s4); + + cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, s2.r, s2.g, s2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_translate (cr, 0.5, 0.5); + cairo_translate (cr, -0.5, -0.5); + + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); + clearlooks_set_mixed_color (cr, border, &fill, 0.2); + if (widget->prelight) + ge_cairo_set_color (cr, &colors->spot[2]); + cairo_stroke (cr); + + cairo_translate (cr, 0.5, 0.5); + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = corners; +} + +static void +clearlooks_glossy_draw_scrollbar_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[7]; + CairoColor fill = scrollbar->color; + CairoColor hilight; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + + if (scrollbar->junction & CL_JUNCTION_BEGIN) + { + if (scrollbar->horizontal) + { + x -= 1; + width += 1; + } + else + { + y -= 1; + height += 1; + } + } + if (scrollbar->junction & CL_JUNCTION_END) + { + if (scrollbar->horizontal) + width += 1; + else + height += 1; + } + + if (!scrollbar->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + cairo_translate (cr, x, y); + + if (widget->prelight) + ge_shade_color (&fill, 1.1, &fill); + + cairo_set_line_width (cr, 1); + + ge_shade_color (&fill, 1.25, &hilight); + ge_shade_color (&fill, 1.16, &shade1); + ge_shade_color (&fill, 1.08, &shade2); + ge_shade_color (&fill, 1.08, &shade3); + + pattern = cairo_pattern_create_linear (1, 1, 1, height-2); + cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + if (scrollbar->has_color) + { + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3); + } + + clearlooks_set_mixed_color (cr, border, &fill, scrollbar->has_color? 0.4 : 0.2); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); +} + +static void +clearlooks_glossy_draw_list_view_header (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ListViewHeaderParameters *header, + int x, int y, int width, int height) +{ +/* + CairoColor *border = !params->prelight? (CairoColor*)&colors->shade[4] : (CairoColor*)&colors->spot[1]; +*/ + const CairoColor *border = &colors->shade[4]; + const CairoColor *fill = &colors->bg[params->state_type]; + CairoColor hilight; + CairoColor shade1, shade2, shade3; + + cairo_pattern_t *pattern; + + ge_shade_color (fill, 1.2, &hilight); + ge_shade_color (fill, 1.08, &shade1); + ge_shade_color (fill, 1.04, &shade2); + ge_shade_color (fill, 1.04, &shade3); + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + /* Draw the fill */ + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, shade3.r, shade3.g, shade3.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, border->r, border->g, border->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, border->r, border->g, border->b); + + cairo_set_source (cr, pattern); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); + + /* Draw highlight */ + if (header->order == CL_ORDER_FIRST) + { + cairo_move_to (cr, 0.5, height-1); + cairo_line_to (cr, 0.5, 0.5); + } + else + cairo_move_to (cr, 0.0, 0.5); + + cairo_line_to (cr, width, 0.5); + + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + cairo_stroke (cr); + + /* Draw resize grip */ + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) + { + SeparatorParameters separator; + separator.horizontal = FALSE; + + if (params->ltr) + params->style_functions->draw_separator (cr, colors, params, &separator, + width-1.5, 4.0, 2, height-8.0); + else + params->style_functions->draw_separator (cr, colors, params, &separator, + 1.5, 4.0, 2, height-8.0); + } +} + +static void +clearlooks_glossy_draw_toolbar (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ToolbarParameters *toolbar, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; + const CairoColor *dark = &colors->shade[3]; + CairoColor light; + ge_shade_color (fill, 1.1, &light); + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y); + + if (toolbar->style == 1) /* Enable Extra features */ + { + cairo_pattern_t *pattern; + CairoColor shade1, shade2, shade3; + + ge_shade_color (fill, 1.08, &shade1); + ge_shade_color (fill, 1.04, &shade2); + ge_shade_color (fill, 1.04, &shade3); + + /* Draw the fill */ + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); + + cairo_set_source (cr, pattern); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); + } + else /* Flat */ + { + ge_cairo_set_color (cr, fill); + cairo_paint (cr); + + if (!toolbar->topmost) + { + /* Draw highlight */ + cairo_move_to (cr, 0, 0.5); + cairo_line_to (cr, width-1, 0.5); + ge_cairo_set_color (cr, &light); + cairo_stroke (cr); + } + } + + /* Draw shadow */ + cairo_move_to (cr, 0, height-0.5); + cairo_line_to (cr, width-1, height-0.5); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); +} + +static void +clearlooks_glossy_draw_menuitem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->spot[1]; + const CairoColor *border = &colors->spot[2]; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + + ge_shade_color (fill, 1.16, &shade1); + ge_shade_color (fill, 1.08, &shade2); + ge_shade_color (fill, 1.08, &shade3); + cairo_set_line_width (cr, 1.0); + + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); +} + +static void +clearlooks_glossy_draw_menubaritem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->spot[1]; + const CairoColor *border = &colors->spot[2]; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + + ge_shade_color (fill, 1.16, &shade1); + ge_shade_color (fill, 1.08, &shade2); + ge_shade_color (fill, 1.08, &shade3); + cairo_set_line_width (cr, 1.0); + + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); +} + +static void +clearlooks_glossy_draw_selected_cell (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + CairoColor color; + + if (params->focus) + color = colors->base[params->state_type]; + else + color = colors->base[GTK_STATE_ACTIVE]; + + clearlooks_draw_glossy_gradient (cr, x, y, width, height, &color, params->disabled, 0.0, CR_CORNER_NONE); +} + + +static void +clearlooks_glossy_draw_radiobutton (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height) +{ + const CairoColor *border; + const CairoColor *dot; + CairoColor shadow; + CairoColor highlight; + cairo_pattern_t *pt; + gboolean inconsistent; + gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); + draw_bullet |= inconsistent; + + if (widget->disabled) + { + border = &colors->shade[5]; + dot = &colors->shade[6]; + } + else + { + if (widget->prelight) + border = &colors->spot[2]; + else + border = &colors->shade[6]; + dot = &colors->text[0]; + } + + ge_shade_color (&widget->parentbg, 0.9, &shadow); + ge_shade_color (&widget->parentbg, 1.1, &highlight); + + pt = cairo_pattern_create_linear (0, 0, 13, 13); + cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g); + cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5); + cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5); + cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b); + + cairo_translate (cr, x, y); + + cairo_set_line_width (cr, 2); + cairo_arc (cr, 7, 7, 6, 0, G_PI*2); + cairo_set_source (cr, pt); + cairo_stroke (cr); + cairo_pattern_destroy (pt); + + cairo_set_line_width (cr, 1); + + cairo_arc (cr, 7, 7, 5.5, 0, G_PI*2); + + if (!widget->disabled) + { + if (widget->prelight) + clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5); + else + ge_cairo_set_color (cr, &colors->base[0]); + cairo_fill_preserve (cr); + } + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + if (draw_bullet) + { + if (inconsistent) + { + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width (cr, 4); + + cairo_move_to(cr, 5, 7); + cairo_line_to(cr, 9, 7); + + ge_cairo_set_color (cr, dot); + cairo_stroke (cr); + } + else + { + cairo_arc (cr, 7, 7, 3, 0, G_PI*2); + ge_cairo_set_color (cr, dot); + cairo_fill (cr); + + cairo_arc (cr, 6, 6, 1, 0, G_PI*2); + cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); + cairo_fill (cr); + } + } +} + +static void +clearlooks_glossy_draw_checkbox (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height) +{ + const CairoColor *border; + const CairoColor *dot; + gboolean inconsistent = FALSE; + gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); + draw_bullet |= inconsistent; + + if (widget->disabled) + { + border = &colors->shade[5]; + dot = &colors->shade[6]; + } + else + { + if (widget->prelight) + border = &colors->spot[2]; + else + border = &colors->shade[6]; + dot = &colors->text[GTK_STATE_NORMAL]; + } + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + if (widget->xthickness > 2 && widget->ythickness > 2) + { + widget->style_functions->draw_inset (cr, &widget->parentbg, 0.5, 0.5, + width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + + /* Draw the rectangle for the checkbox itself */ + ge_cairo_rounded_rectangle (cr, 1.5, 1.5, + width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + } + else + { + /* Draw the rectangle for the checkbox itself */ + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, + width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + } + + if (!widget->disabled) + { + if (widget->prelight) + clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5); + else + ge_cairo_set_color (cr, &colors->base[0]); + cairo_fill_preserve (cr); + } + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + if (draw_bullet) + { + if (inconsistent) /* Inconsistent */ + { + cairo_set_line_width (cr, 2.0); + cairo_move_to (cr, 3, height*0.5); + cairo_line_to (cr, width-3, height*0.5); + } + else + { + cairo_set_line_width (cr, 1.7); + cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5)); + cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7)); + + cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7), + 0.5 + (width*0.5), (height*0.4), + 0.5 + (width*0.70), (height*0.25)); + + } + + ge_cairo_set_color (cr, dot); + cairo_stroke (cr); + } +} + +void +clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions) +{ + functions->draw_inset = clearlooks_glossy_draw_inset; + functions->draw_button = clearlooks_glossy_draw_button; + functions->draw_progressbar_trough = clearlooks_glossy_draw_progressbar_trough; + functions->draw_progressbar_fill = clearlooks_glossy_draw_progressbar_fill; + functions->draw_scale_trough = clearlooks_glossy_draw_scale_trough; + functions->draw_tab = clearlooks_glossy_draw_tab; + functions->draw_slider = clearlooks_glossy_draw_slider; + functions->draw_slider_button = clearlooks_glossy_draw_slider_button; + functions->draw_scrollbar_stepper = clearlooks_glossy_draw_scrollbar_stepper; + functions->draw_scrollbar_slider = clearlooks_glossy_draw_scrollbar_slider; + functions->draw_list_view_header = clearlooks_glossy_draw_list_view_header; + functions->draw_toolbar = clearlooks_glossy_draw_toolbar; + functions->draw_menuitem = clearlooks_glossy_draw_menuitem; + functions->draw_menubaritem = clearlooks_glossy_draw_menubaritem; + functions->draw_selected_cell = clearlooks_glossy_draw_selected_cell; + functions->draw_checkbox = clearlooks_glossy_draw_checkbox; + functions->draw_radiobutton = clearlooks_glossy_draw_radiobutton; +} diff --git a/libs/clearlooks-newer/clearlooks_draw_gummy.c b/libs/clearlooks-newer/clearlooks_draw_gummy.c new file mode 100644 index 0000000000..e2a990230b --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_draw_gummy.c @@ -0,0 +1,1524 @@ +/* Clearlooks Gummy style + * Copyright (C) 2007 Andrea Cimitan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Andrea Cimitan <andrea.cimitan@gmail.com> + */ + +#include "clearlooks_draw.h" +#include "clearlooks_style.h" +#include "clearlooks_types.h" + +#include "support.h" +#include <ge-support.h> + +#include <cairo.h> + +/* Normal shadings */ +#define SHADE_TOP 1.08 +#define SHADE_CENTER_TOP 1.02 +#define SHADE_BOTTOM 0.94 + +/* Topleft highlight */ +#define TOPLEFT_HIGHLIGHT_SHADE 1.3 +#define TOPLEFT_HIGHLIGHT_ALPHA 0.4 + +/* Listview */ +#define LISTVIEW_SHADE_TOP 1.06 +#define LISTVIEW_SHADE_CENTER_TOP 1.02 +#define LISTVIEW_SHADE_BOTTOM 0.96 + +/* Toolbar */ +#define TOOLBAR_SHADE_TOP 1.04 +#define TOOLBAR_SHADE_CENTER_TOP 1.01 +#define TOOLBAR_SHADE_BOTTOM 0.97 + + +static void +clearlooks_draw_gummy_gradient (cairo_t *cr, + double x, double y, int width, int height, + const CairoColor *color, + gboolean disabled, gboolean radius, CairoCorners corners) +{ + CairoColor fill; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pt; + + ge_shade_color (color, disabled? 1.04 : SHADE_TOP, &shade1); + ge_shade_color (color, disabled? 1.01 : SHADE_CENTER_TOP, &shade2); + ge_shade_color (color, disabled? 0.99 : 1.0, &fill); + ge_shade_color (color, disabled? 0.96 : SHADE_BOTTOM, &shade3); + + pt = cairo_pattern_create_linear (x, y, x, y+height); + cairo_pattern_add_color_stop_rgb (pt, 0.0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pt, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pt, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb (pt, 1.0, shade3.r, shade3.g, shade3.b); + + cairo_set_source (cr, pt); + ge_cairo_rounded_rectangle (cr, x, y, width, height, radius, corners); + cairo_fill (cr); + + cairo_pattern_destroy (pt); +} + +static void +clearlooks_set_mixed_color (cairo_t *cr, + const CairoColor *color1, + const CairoColor *color2, + gdouble mix_factor) +{ + CairoColor composite; + + ge_mix_color (color1, color2, mix_factor, &composite); + ge_cairo_set_color (cr, &composite); +} + +static void +clearlooks_gummy_draw_highlight_and_shade (cairo_t *cr, + const CairoColor *bg_color, + const ShadowParameters *params, + int width, int height, gdouble radius) +{ + CairoColor shadow; + CairoColor highlight; + uint8 corners = params->corners; + double x = 1.0; + double y = 1.0; + + /* not really sure of shading ratios... we will think */ + ge_shade_color (bg_color, 0.8, &shadow); + ge_shade_color (bg_color, 1.2, &highlight); + + cairo_save (cr); + + /* Top/Left highlight */ + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_move_to (cr, x, y+height-radius); + else + cairo_move_to (cr, x, y+height); + + ge_cairo_rounded_corner (cr, x, y, radius, corners & CR_CORNER_TOPLEFT); + + if (corners & CR_CORNER_TOPRIGHT) + cairo_line_to (cr, x+width-radius, y); + else + cairo_line_to (cr, x+width, y); + + if (params->shadow & CL_SHADOW_OUT) + cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); + else + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5); + + cairo_stroke (cr); + + /* Bottom/Right highlight -- this includes the corners */ + cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */ + ge_cairo_rounded_corner (cr, x+width, y, radius, corners & CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, x+width, y+height, radius, corners & CR_CORNER_BOTTOMRIGHT); + ge_cairo_rounded_corner (cr, x, y+height, radius, corners & CR_CORNER_BOTTOMLEFT); + + if (params->shadow & CL_SHADOW_OUT) + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5); + else + cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); + + cairo_stroke (cr); + + cairo_restore (cr); +} + +static void +clearlooks_gummy_draw_top_left_highlight (cairo_t *cr, const CairoColor *color, + const WidgetParameters *params, + int width, int height, gdouble radius) +{ + CairoColor hilight; + + double light_top = params->ythickness-1, + light_bottom = height - params->ythickness - 1, + light_left = params->xthickness-1, + light_right = width - params->xthickness - 1; + + ge_shade_color (color, TOPLEFT_HIGHLIGHT_SHADE, &hilight); + cairo_move_to (cr, light_left, light_bottom - (int)radius/2); + + ge_cairo_rounded_corner (cr, light_left, light_top, radius, params->corners & CR_CORNER_TOPLEFT); + + cairo_line_to (cr, light_right - (int)radius/2, light_top); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, TOPLEFT_HIGHLIGHT_ALPHA); + cairo_stroke (cr); +} + +static void +clearlooks_gummy_draw_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + double xoffset = 0, yoffset = 0; + CairoColor fill = colors->bg[params->state_type]; + CairoColor border_normal = colors->shade[6]; + CairoColor border_disabled = colors->shade[4]; + double radius; + + cairo_pattern_t *pattern; + + cairo_save (cr); + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + /* Shadows and Glow */ + if (params->xthickness == 3 || params->ythickness == 3) + { + if (params->xthickness == 3) + xoffset = 1; + if (params->ythickness == 3) + yoffset = 1; + } + + radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0, (height - 2.0 - 2*yoffset) / 2.0)); + + if (params->xthickness == 3 || params->ythickness == 3) + { + cairo_translate (cr, 0.5, 0.5); + + if (params->enable_glow && !params->active && !params->disabled && !params->is_default) + { + CairoColor shadow; + + radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0)); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius+1, params->corners); + ge_shade_color (¶ms->parentbg, 0.97, &shadow); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius+1, params->corners); + ge_shade_color (¶ms->parentbg, 0.93, &shadow); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + + if (params->is_default) + { + CairoColor shadow = colors->spot[1]; + + radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0)); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius+1, params->corners); + clearlooks_set_mixed_color (cr, ¶ms->parentbg, &shadow, 0.5); + cairo_stroke (cr); + } + + if (!(params->enable_glow && !params->active && !params->disabled)) + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, params->radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); + } + + clearlooks_draw_gummy_gradient (cr, xoffset+1, yoffset+1, + width-(xoffset*2)-2, height-(yoffset*2)-2, + &fill, params->disabled, radius, params->corners); + + /* Pressed button shadow */ + if (params->active) + { + CairoColor shadow; + ge_shade_color (&fill, 0.92, &shadow); + + cairo_save (cr); + + ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height, radius, + params->corners & (CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMLEFT)); + cairo_clip (cr); + cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3); + + pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2); + + pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); + } + + /* Border */ + if (params->is_default) /* || (params->prelight && params->enable_glow)) */ + border_normal = colors->spot[2]; + if (params->disabled) + ge_cairo_set_color (cr, &border_disabled); + else + clearlooks_set_mixed_color (cr, &border_normal, &fill, 0.2); + ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5, + width-(xoffset*2)-1, height-(yoffset*2)-1, + radius, params->corners); + cairo_stroke (cr); + + if (!params->active) + { + cairo_translate (cr, 0.5, 0.5); + clearlooks_gummy_draw_top_left_highlight (cr, &fill, params, width, height, radius); + } + cairo_restore (cr); +} + +static void +clearlooks_gummy_draw_entry (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *base = &colors->base[params->state_type]; + CairoColor border = colors->shade[params->disabled ? 4 : 6]; + double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0)); + + if (params->focus) + border = colors->spot[2]; + + cairo_translate (cr, x+0.5, y+0.5); + cairo_set_line_width (cr, 1.0); + + /* Fill the background to get the correct corners. */ + cairo_rectangle (cr, -0.5, -0.5, width, height); + ge_cairo_set_color (cr, ¶ms->parentbg); + cairo_fill (cr); + + /* Fill with the base color, because it was just cleared above */ + cairo_rectangle (cr, 1.5, 1.5, width-4, height-4); + ge_cairo_set_color (cr, base); + cairo_fill (cr); + + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); + + /* Draw the inner shadow */ + if (params->focus) + { + /* ge_cairo_rounded_rectangle (cr, 2, 2, width-5, height-5, RADIUS-1, params->corners); */ + ge_cairo_set_color (cr, &colors->spot[0]); + ge_cairo_stroke_rectangle (cr, 2, 2, width-5, height-5); + } + else + { + CairoColor shadow; + ge_shade_color (&border, 0.92, &shadow); + + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, params->disabled ? 0.09 : 0.18); + /* + cairo_move_to (cr, 2, height-3); + cairo_arc (cr, params->xthickness+RADIUS-1, params->ythickness+RADIUS-1, RADIUS, G_PI, 270*(G_PI/180)); + cairo_line_to (cr, width-3, 2); + */ + cairo_move_to (cr, 2, height-3); + cairo_line_to (cr, 2, 2); + cairo_line_to (cr, width-3, 2); + cairo_stroke (cr); + } + + ge_cairo_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, params->corners); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); +} + +static void +clearlooks_gummy_draw_progressbar_trough (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[7]; + CairoColor shadow; + cairo_pattern_t *pattern; + double radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0)); + + cairo_save (cr); + + cairo_set_line_width (cr, 1.0); + + /* Fill with bg color */ + ge_cairo_set_color (cr, &colors->bg[params->state_type]); + + cairo_rectangle (cr, x, y, width, height); + cairo_fill (cr); + + /* Create trough box */ + ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); + ge_cairo_set_color (cr, &colors->shade[2]); + cairo_fill (cr); + + /* Draw border */ + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners); + clearlooks_set_mixed_color (cr, border, &colors->shade[2], 0.3); + cairo_stroke (cr); + + /* clip the corners of the shadows */ + ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); + cairo_clip (cr); + + ge_shade_color (border, 0.92, &shadow); + + /* Top shadow */ + cairo_rectangle (cr, x+1, y+1, width-2, 4); + pattern = cairo_pattern_create_linear (x, y, x, y+4); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + /* Left shadow */ + cairo_rectangle (cr, x+1, y+1, 4, height-2); + pattern = cairo_pattern_create_linear (x, y, x+4, y); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); +} + +static void +clearlooks_gummy_draw_progressbar_fill (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ProgressBarParameters *progressbar, + int x, int y, int width, int height, gint offset) +{ + boolean is_horizontal = progressbar->orientation < 2; + double tile_pos = 0; + double stroke_width; + double radius; + int x_step; + + cairo_pattern_t *pattern; + CairoColor shade1, shade2, shade3; + CairoColor border; + CairoColor shadow; + + radius = MAX (0, params->radius - params->xthickness); + + cairo_save (cr); + + if (!is_horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP)) + ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height); + + /* Clamp the radius so that the _height_ fits ... */ + radius = MIN (radius, height / 2.0); + + stroke_width = height*2; + x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */ + + cairo_translate (cr, x, y); + + cairo_save (cr); + /* This is kind of nasty ... Clip twice from each side in case the length + * of the fill is smaller than twice the radius. */ + ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + /* Draw the background gradient */ + ge_shade_color (&colors->spot[1], SHADE_TOP, &shade1); + ge_shade_color (&colors->spot[1], SHADE_CENTER_TOP, &shade2); + ge_shade_color (&colors->spot[1], SHADE_BOTTOM, &shade3); + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); + cairo_set_source (cr, pattern); + cairo_paint (cr); + cairo_pattern_destroy (pattern); + + /* Draw the Strokes */ + while (tile_pos <= width+x_step) + { + cairo_move_to (cr, stroke_width/2-x_step, 0); + cairo_line_to (cr, stroke_width-x_step, 0); + cairo_line_to (cr, stroke_width/2-x_step, height); + cairo_line_to (cr, -x_step, height); + + cairo_translate (cr, stroke_width, 0); + tile_pos += stroke_width; + } + + cairo_set_source_rgba (cr, colors->spot[2].r, + colors->spot[2].g, + colors->spot[2].b, + 0.15); + + cairo_fill (cr); + cairo_restore (cr); /* rounded clip region */ + + /* inner highlight border + * This is again kinda ugly. Draw once from each side, clipping away the other. */ + cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.2); + + /* left side */ + cairo_save (cr); + cairo_rectangle (cr, 0, 0, width / 2, height); + cairo_clip (cr); + + if (progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + else + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + /* right side */ + cairo_save (cr); + cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height); + cairo_clip (cr); + + if (progressbar->value < 1.0 || progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + else + ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + + /* Draw the dark lines and the shadow */ + cairo_save (cr); + /* Again, this weird clip area. */ + ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + border = colors->spot[2]; + border.a = 0.6; + ge_shade_color (&colors->shade[7], 0.92, &shadow); + shadow.a = 0.2; + + if (progressbar->pulsing) + { + /* At the beginning of the bar. */ + cairo_move_to (cr, 0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, -0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + if (progressbar->value < 1.0 || progressbar->pulsing) + { + /* At the end of the bar. */ + cairo_move_to (cr, width - 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, width + 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + + cairo_restore (cr); + + cairo_restore (cr); /* rotation, mirroring */ +} + +static void +clearlooks_gummy_scale_draw_gradient (cairo_t *cr, + const CairoColor *fill, + const CairoColor *border, + int x, int y, int width, int height, + gboolean horizontal, gboolean in) +{ + cairo_pattern_t *pattern; + + CairoColor f1, f2; + + ge_shade_color (fill, in? 0.95 : 1.1, &f1); + ge_shade_color (fill, in? 1.05 : 0.9, &f2); + + pattern = cairo_pattern_create_linear (0, 0, horizontal ? 0 : width, horizontal ? height : 0); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, f1.r, f1.g, f1.b, f1.a); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, f2.r, f2.g, f2.b, f2.a); + + cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + clearlooks_set_mixed_color (cr, border, fill, 0.2); + ge_cairo_stroke_rectangle (cr, x, y, width, height); +} + +#define TROUGH_SIZE 6 +static void +clearlooks_gummy_draw_scale_trough (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + int trough_width, trough_height; + double translate_x, translate_y; + + if (slider->horizontal) + { + trough_width = width-3; + trough_height = TROUGH_SIZE-2; + + translate_x = x + 0.5; + translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2); + } + else + { + trough_width = TROUGH_SIZE-2; + trough_height = height-3; + + translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2); + translate_y = y + 0.5; + } + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, translate_x, translate_y); + + if (!slider->fill_level) + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0); + + cairo_translate (cr, 1, 1); + + if (!slider->lower && !slider->fill_level) + clearlooks_gummy_scale_draw_gradient (cr, + &colors->shade[2], /* bottom */ + &colors->shade[6], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal, TRUE); + else if (!slider->fill_level) + clearlooks_gummy_scale_draw_gradient (cr, + &colors->spot[1], /* bottom */ + &colors->spot[2], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal, FALSE); + else { + CairoColor c1 = colors->spot[1]; + CairoColor c2 = colors->spot[2]; + + c1.a = 0.25; + c2.a = 0.25; + + clearlooks_gummy_scale_draw_gradient (cr, + &c1, /* bottom */ + &c2, /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal, FALSE); + } + +} + +static void +clearlooks_gummy_draw_tab (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const TabParameters *tab, + int x, int y, int width, int height) +{ + + const CairoColor *border = &colors->shade[5]; + const CairoColor *stripe_fill = &colors->spot[1]; + const CairoColor *stripe_border = &colors->spot[2]; + const CairoColor *fill; + + cairo_pattern_t *pattern; + + double radius; + double strip_size; + + radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + /* Set clip */ + cairo_rectangle (cr, x, y, width, height); + cairo_clip (cr); + cairo_new_path (cr); + + /* Translate and set line width */ + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y+0.5); + + /* Make the tabs slightly bigger than they should be, to create a gap */ + /* And calculate the strip size too, while you're at it */ + if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) + { + height += 3.0; + strip_size = 2.0/height; /* 2 pixel high strip */ + + if (tab->gap_side == CL_GAP_TOP) + cairo_translate (cr, 0.0, -3.0); /* gap at the other side */ + } + else + { + width += 3.0; + strip_size = 2.0/width; + + if (tab->gap_side == CL_GAP_LEFT) + cairo_translate (cr, -3.0, 0.0); /* gap at the other side */ + } + + /* Set the fill color */ + fill = &colors->bg[params->state_type]; + + /* Set tab shape */ + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, + radius, params->corners); + + /* Draw fill */ + ge_cairo_set_color (cr, fill); + cairo_fill (cr); + + /* Draw highlight */ + if (!params->active) + { + ShadowParameters shadow; + + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = params->corners; + + clearlooks_gummy_draw_highlight_and_shade (cr, &colors->bg[0], &shadow, + width, height, radius); + } + + if (params->active) + { + CairoColor hilight; + CairoColor shade1, shade2, shade3; + + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + ge_shade_color (fill, 1.14, &hilight); + ge_shade_color (fill, SHADE_TOP, &shade1); + ge_shade_color (fill, SHADE_CENTER_TOP, &shade2); + ge_shade_color (fill, SHADE_BOTTOM, &shade3); + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, hilight.r, hilight.g, hilight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, hilight.r, hilight.g, hilight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.45, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.45, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + /* Draw shade */ + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.5); + cairo_pattern_add_color_stop_rgba (pattern, 0.8, fill->r, fill->g, fill->b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + if (params->active) + { + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + } + else + { + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2); + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); + cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r, border->g, border->b); + cairo_set_source (cr, pattern); + cairo_stroke (cr); + cairo_pattern_destroy (pattern); + } +} + +static void +clearlooks_gummy_draw_separator (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SeparatorParameters *separator, + int x, int y, int width, int height) +{ + CairoColor color = colors->shade[3]; + CairoColor hilight; + ge_shade_color (&color, 1.3, &hilight); + + cairo_save (cr); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + + if (separator->horizontal) + { + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y+0.5); + + cairo_move_to (cr, 0.0, 0.0); + cairo_line_to (cr, width, 0.0); + ge_cairo_set_color (cr, &color); + cairo_stroke (cr); + + cairo_move_to (cr, 0.0, 1.0); + cairo_line_to (cr, width, 1.0); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); + } + else + { + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y); + + cairo_move_to (cr, 0.0, 0.0); + cairo_line_to (cr, 0.0, height); + ge_cairo_set_color (cr, &color); + cairo_stroke (cr); + + cairo_move_to (cr, 1.0, 0.0); + cairo_line_to (cr, 1.0, height); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); + } + + cairo_restore (cr); +} + +static void +clearlooks_gummy_draw_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[7]; + CairoColor fill; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + int bar_x, i; + int shift_x; + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y); + + cairo_translate (cr, -0.5, -0.5); + + ge_shade_color (&colors->bg[params->state_type], 1.0, &fill); + if (params->prelight) + ge_shade_color (&fill, 1.04, &fill); + + ge_shade_color (&fill, SHADE_TOP, &shade1); + ge_shade_color (&fill, SHADE_CENTER_TOP, &shade2); + ge_shade_color (&fill, SHADE_BOTTOM, &shade3); + + pattern = cairo_pattern_create_linear (1, 1, 1, height-2); + cairo_pattern_add_color_stop_rgb(pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, shade3.r, shade3.g, shade3.b); + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + clearlooks_set_mixed_color (cr, border, &fill, 0.2); + if (params->prelight) + ge_cairo_set_color (cr, &colors->spot[2]); + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, 2.5, params->corners); + cairo_stroke (cr); + + /* Handle */ + shift_x = (width%2 == 0 ? 1 : 0); + bar_x = width/2-3+shift_x; + cairo_translate (cr, 0.5, 0.5); + ge_cairo_set_color (cr, border); + for (i=0; i<3-shift_x; i++) + { + cairo_move_to (cr, bar_x, 4); + cairo_line_to (cr, bar_x, height-5); + bar_x += 3; + } + cairo_stroke (cr); + + clearlooks_gummy_draw_top_left_highlight (cr, &fill, params, width, height, 2.0); +} + +static void +clearlooks_gummy_draw_slider_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0)); + + cairo_set_line_width (cr, 1.0); + + if (!slider->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + cairo_translate (cr, x+0.5, y+0.5); + + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); + params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); +} + +static void +clearlooks_gummy_draw_scrollbar_stepper (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + const ScrollBarStepperParameters *stepper, + int x, int y, int width, int height) +{ + CairoCorners corners = CR_CORNER_NONE; + const CairoColor *border = &colors->shade[scrollbar->has_color ? 7 : 6]; + CairoColor fill; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + ShadowParameters shadow; + double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + if (scrollbar->horizontal) + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + } + else + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; + } + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners); + + if (scrollbar->horizontal) + pattern = cairo_pattern_create_linear (0, 0, 0, height); + else + pattern = cairo_pattern_create_linear (0, 0, width, 0); + + fill = colors->bg[widget->state_type]; + ge_shade_color(&fill, SHADE_TOP, &shade1); + ge_shade_color(&fill, SHADE_CENTER_TOP, &shade2); + ge_shade_color(&fill, SHADE_BOTTOM, &shade3); + + cairo_pattern_add_color_stop_rgb(pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, shade3.r, shade3.g, shade3.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_translate (cr, 0.5, 0.5); + clearlooks_gummy_draw_top_left_highlight (cr, &fill, widget, width, height, (stepper->stepper == CL_STEPPER_A) ? radius : 0); + cairo_translate (cr, -0.5, -0.5); + + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); + clearlooks_set_mixed_color (cr, border, &fill, 0.2); + cairo_stroke (cr); + + cairo_translate (cr, 0.5, 0.5); + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = corners; +} + +static void +clearlooks_gummy_draw_scrollbar_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height) +{ + CairoColor fill = scrollbar->color; + CairoColor border, handles; + CairoColor hilight; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + int bar_x, i; + + gdouble hue_scroll, brightness_scroll, saturation_scroll; + gdouble hue_bg, brightness_bg, saturation_bg; + + ge_hsb_from_color (&fill, &hue_scroll, &saturation_scroll, &brightness_scroll); + ge_hsb_from_color (&colors->bg[0], &hue_bg, &saturation_bg, &brightness_bg); + + /* Set the right color for border and handles */ + if ((fabs(saturation_scroll - saturation_bg) < 0.30) && + (fabs(brightness_scroll - brightness_bg) < 0.20)) + ge_shade_color (&fill, 0.475, &border); + else + ge_shade_color (&fill, 0.575, &border); + /* The following lines increase contrast when the HUE is between 25 and 195, */ + /* fixing a LOT of colorschemes! */ + if (scrollbar->has_color && (hue_scroll < 195) && (hue_scroll > 25)) + ge_shade_color (&border, 0.85, &border); + + handles = border; + ge_mix_color (&border, &fill, scrollbar->has_color? 0.3 : 0.2, &border); + + if (scrollbar->junction & CL_JUNCTION_BEGIN) + { + if (scrollbar->horizontal) + { + x -= 1; + width += 1; + } + else + { + y -= 1; + height += 1; + } + } + if (scrollbar->junction & CL_JUNCTION_END) + { + if (scrollbar->horizontal) + width += 1; + else + height += 1; + } + + if (!scrollbar->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + cairo_translate (cr, x, y); + + if (widget->prelight) + ge_shade_color (&fill, 1.04, &fill); + + cairo_set_line_width (cr, 1); + + ge_shade_color (&fill, TOPLEFT_HIGHLIGHT_SHADE, &hilight); + ge_shade_color (&fill, SHADE_TOP, &shade1); + ge_shade_color (&fill, SHADE_CENTER_TOP, &shade2); + ge_shade_color (&fill, SHADE_BOTTOM, &shade3); + + pattern = cairo_pattern_create_linear (1, 1, 1, height-2); + cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + if (scrollbar->has_color) + { + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.2); + ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3); + } + else + { + cairo_move_to (cr, 1.5, height-1.5); + cairo_line_to (cr, 1.5, 1.5); + cairo_line_to (cr, width-1.5, 1.5); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, TOPLEFT_HIGHLIGHT_ALPHA); + cairo_stroke(cr); + } + + ge_cairo_set_color (cr, &border); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); + + /* Handle */ + bar_x = width/2 - 4; + cairo_translate(cr, 0.5, 0.5); + ge_cairo_set_color (cr, &handles); + for (i=0; i<3; i++) + { + cairo_move_to (cr, bar_x, 5); + cairo_line_to (cr, bar_x, height-6); + bar_x += 3; + } + cairo_stroke (cr); +} + +static void +clearlooks_gummy_draw_list_view_header (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ListViewHeaderParameters *header, + int x, int y, int width, int height) +{ +/* + CairoColor *border = !params->prelight? (CairoColor*)&colors->shade[4] : (CairoColor*)&colors->spot[1]; +*/ + const CairoColor *border = &colors->shade[4]; + const CairoColor *fill = &colors->bg[params->state_type]; + CairoColor hilight; + CairoColor shade1, shade2, shade3; + + cairo_pattern_t *pattern; + + ge_shade_color (fill, 1.11, &hilight); + ge_shade_color (fill, LISTVIEW_SHADE_TOP, &shade1); + ge_shade_color (fill, LISTVIEW_SHADE_CENTER_TOP, &shade2); + ge_shade_color (fill, LISTVIEW_SHADE_BOTTOM, &shade3); + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + /* Draw the fill */ + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, shade3.r, shade3.g, shade3.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, border->r, border->g, border->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, border->r, border->g, border->b); + + cairo_set_source (cr, pattern); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); + + /* Draw highlight */ + if (header->order == CL_ORDER_FIRST) + { + cairo_move_to (cr, 0.5, height-1.5); + cairo_line_to (cr, 0.5, 0.5); + } + else + cairo_move_to (cr, 0.0, 0.5); + + cairo_line_to (cr, width, 0.5); + + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); + + /* Draw resize grip */ + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) + { + SeparatorParameters separator; + separator.horizontal = FALSE; + + if (params->ltr) + params->style_functions->draw_separator (cr, colors, params, &separator, + width-1.5, 4.0, 2, height-8.0); + else + params->style_functions->draw_separator (cr, colors, params, &separator, + 1.5, 4.0, 2, height-8.0); + } +} + +static void +clearlooks_gummy_draw_toolbar (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ToolbarParameters *toolbar, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; + const CairoColor *dark = &colors->shade[3]; + CairoColor light; + ge_shade_color (fill, toolbar->style == 1 ? 1.1 : 1.05, &light); + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y); + + if (toolbar->style == 1) /* Enable Extra features */ + { + cairo_pattern_t *pattern; + CairoColor shade1, shade2, shade3; + + ge_shade_color (fill, TOOLBAR_SHADE_TOP, &shade1); + ge_shade_color (fill, TOOLBAR_SHADE_CENTER_TOP, &shade2); + ge_shade_color (fill, TOOLBAR_SHADE_BOTTOM, &shade3); + + /* Draw the fill */ + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); + + cairo_set_source (cr, pattern); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); + } + else /* Flat */ + { + ge_cairo_set_color (cr, fill); + cairo_paint (cr); + } + + if (!toolbar->topmost) + { + /* Draw highlight */ + cairo_move_to (cr, 0, 0.5); + cairo_line_to (cr, width-1, 0.5); + ge_cairo_set_color (cr, &light); + cairo_stroke (cr); + } + + /* Draw shadow */ + cairo_move_to (cr, 0, height-0.5); + cairo_line_to (cr, width-1, height-0.5); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); +} + +static void +clearlooks_gummy_draw_menuitem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->spot[1]; + const CairoColor *border = &colors->spot[2]; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + + ge_shade_color (fill, SHADE_TOP, &shade1); + ge_shade_color (fill, SHADE_CENTER_TOP, &shade2); + ge_shade_color (fill, SHADE_BOTTOM, &shade3); + cairo_set_line_width (cr, 1.0); + + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); +} + +static void +clearlooks_gummy_draw_menubaritem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->spot[1]; + const CairoColor *border = &colors->spot[2]; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + + ge_shade_color (fill, SHADE_TOP, &shade1); + ge_shade_color (fill, SHADE_CENTER_TOP, &shade2); + ge_shade_color (fill, SHADE_BOTTOM, &shade3); + cairo_set_line_width (cr, 1.0); + + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); +} + +static void +clearlooks_gummy_draw_selected_cell (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + CairoColor color; + + if (params->focus) + color = colors->base[params->state_type]; + else + color = colors->base[GTK_STATE_ACTIVE]; + + clearlooks_draw_gummy_gradient (cr, x, y, width, height, &color, params->disabled, 0.0, CR_CORNER_NONE); +} + +static void +clearlooks_gummy_draw_statusbar (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + const CairoColor *dark = &colors->shade[3]; + CairoColor hilight; + + ge_shade_color (dark, 1.3, &hilight); + + cairo_set_line_width (cr, 1); + cairo_translate (cr, x, y+0.5); + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, width, 0); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); + + cairo_translate (cr, 0, 1); + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, width, 0); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); +} + +static void +clearlooks_gummy_draw_radiobutton (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height) +{ + const CairoColor *border; + const CairoColor *dot; + CairoColor shadow; + CairoColor highlight; + cairo_pattern_t *pt; + gboolean inconsistent; + gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); + draw_bullet |= inconsistent; + + if (widget->disabled) + { + border = &colors->shade[5]; + dot = &colors->shade[6]; + } + else + { + if (widget->prelight) + border = &colors->spot[2]; + else + border = &colors->shade[6]; + dot = &colors->text[0]; + } + + ge_shade_color (&widget->parentbg, 0.9, &shadow); + ge_shade_color (&widget->parentbg, 1.1, &highlight); + + pt = cairo_pattern_create_linear (0, 0, 13, 13); + cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g); + cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5); + cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5); + cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b); + + cairo_translate (cr, x, y); + + cairo_set_line_width (cr, 2); + cairo_arc (cr, 7, 7, 6, 0, G_PI*2); + cairo_set_source (cr, pt); + cairo_stroke (cr); + cairo_pattern_destroy (pt); + + cairo_set_line_width (cr, 1); + + cairo_arc (cr, 7, 7, 5.5, 0, G_PI*2); + + if (!widget->disabled) + { + if (widget->prelight) + clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5); + else + ge_cairo_set_color (cr, &colors->base[0]); + cairo_fill_preserve (cr); + } + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + if (draw_bullet) + { + if (inconsistent) + { + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_width (cr, 4); + + cairo_move_to(cr, 5, 7); + cairo_line_to(cr, 9, 7); + + ge_cairo_set_color (cr, dot); + cairo_stroke (cr); + } + else + { + cairo_arc (cr, 7, 7, 3, 0, G_PI*2); + ge_cairo_set_color (cr, dot); + cairo_fill (cr); + + cairo_arc (cr, 6, 6, 1, 0, G_PI*2); + cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); + cairo_fill (cr); + } + } +} + +static void +clearlooks_gummy_draw_checkbox (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height) +{ + const CairoColor *border; + const CairoColor *dot; + gboolean inconsistent = FALSE; + gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); + + inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); + draw_bullet |= inconsistent; + + if (widget->disabled) + { + border = &colors->shade[5]; + dot = &colors->shade[6]; + } + else + { + if (widget->prelight) + border = &colors->spot[2]; + else + border = &colors->shade[6]; + dot = &colors->text[GTK_STATE_NORMAL]; + } + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + if (widget->xthickness > 2 && widget->ythickness > 2) + { + widget->style_functions->draw_inset (cr, &widget->parentbg, 0.5, 0.5, + width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + + /* Draw the rectangle for the checkbox itself */ + ge_cairo_rounded_rectangle (cr, 1.5, 1.5, + width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + } + else + { + /* Draw the rectangle for the checkbox itself */ + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, + width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + } + + if (!widget->disabled) + { + if (widget->prelight) + clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5); + else + ge_cairo_set_color (cr, &colors->base[0]); + cairo_fill_preserve (cr); + } + + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + if (draw_bullet) + { + if (inconsistent) /* Inconsistent */ + { + cairo_set_line_width (cr, 2.0); + cairo_move_to (cr, 3, height*0.5); + cairo_line_to (cr, width-3, height*0.5); + } + else + { + cairo_set_line_width (cr, 1.7); + cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5)); + cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7)); + + cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7), + 0.5 + (width*0.5), (height*0.4), + 0.5 + (width*0.70), (height*0.25)); + + } + + ge_cairo_set_color (cr, dot); + cairo_stroke (cr); + } +} + +void +clearlooks_register_style_gummy (ClearlooksStyleFunctions *functions) +{ + functions->draw_button = clearlooks_gummy_draw_button; + functions->draw_entry = clearlooks_gummy_draw_entry; + functions->draw_progressbar_trough = clearlooks_gummy_draw_progressbar_trough; + functions->draw_progressbar_fill = clearlooks_gummy_draw_progressbar_fill; + functions->draw_scale_trough = clearlooks_gummy_draw_scale_trough; + functions->draw_tab = clearlooks_gummy_draw_tab; + functions->draw_separator = clearlooks_gummy_draw_separator; + functions->draw_slider = clearlooks_gummy_draw_slider; + functions->draw_slider_button = clearlooks_gummy_draw_slider_button; + functions->draw_scrollbar_stepper = clearlooks_gummy_draw_scrollbar_stepper; + functions->draw_scrollbar_slider = clearlooks_gummy_draw_scrollbar_slider; + functions->draw_list_view_header = clearlooks_gummy_draw_list_view_header; + functions->draw_toolbar = clearlooks_gummy_draw_toolbar; + functions->draw_menuitem = clearlooks_gummy_draw_menuitem; + functions->draw_menubaritem = clearlooks_gummy_draw_menubaritem; + functions->draw_selected_cell = clearlooks_gummy_draw_selected_cell; + functions->draw_statusbar = clearlooks_gummy_draw_statusbar; + functions->draw_checkbox = clearlooks_gummy_draw_checkbox; + functions->draw_radiobutton = clearlooks_gummy_draw_radiobutton; +} diff --git a/libs/clearlooks-newer/clearlooks_draw_inverted.c b/libs/clearlooks-newer/clearlooks_draw_inverted.c new file mode 100644 index 0000000000..2e8ee3bcd7 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_draw_inverted.c @@ -0,0 +1,1002 @@ +/* Clearlooks Inverted style + * Copyright (C) 2007 Andrea Cimitan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Andrea Cimitan <andrea.cimitan@gmail.com> + */ + +#include "clearlooks_draw.h" +#include "clearlooks_style.h" +#include "clearlooks_types.h" + +#include "support.h" +#include <ge-support.h> + +#include <cairo.h> + + +static void +clearlooks_draw_top_left_highlight (cairo_t *cr, + const CairoColor *color, + const WidgetParameters *params, + int width, int height, gdouble radius) +{ + CairoColor hilight; + + double light_top = params->ythickness-1, + light_bottom = height - params->ythickness - 1, + light_left = params->xthickness-1, + light_right = width - params->xthickness - 1; + + ge_shade_color (color, 1.3, &hilight); + cairo_move_to (cr, light_left, light_bottom - (int)radius/2); + + ge_cairo_rounded_corner (cr, light_left, light_top, radius, params->corners & CR_CORNER_TOPLEFT); + + cairo_line_to (cr, light_right - (int)radius/2, light_top); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.7); + cairo_stroke (cr); +} + +static void +clearlooks_set_border_gradient (cairo_t *cr, const CairoColor *color, double hilight, int width, int height) +{ + cairo_pattern_t *pattern; + + CairoColor bottom_shade; + ge_shade_color (color, hilight, &bottom_shade); + + pattern = cairo_pattern_create_linear (0, 0, width, height); + cairo_pattern_add_color_stop_rgb (pattern, 0, color->r, color->g, color->b); + cairo_pattern_add_color_stop_rgb (pattern, 1, bottom_shade.r, bottom_shade.g, bottom_shade.b); + + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); +} + +static void +clearlooks_inverted_draw_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + double xoffset = 0, yoffset = 0; + double radius = params->radius; + const CairoColor *fill = &colors->bg[params->state_type]; + const CairoColor *border_disabled = &colors->shade[4]; + CairoColor border_normal; + CairoColor shadow; + + ge_shade_color(&colors->shade[6], 1.05, &border_normal); + ge_shade_color (&border_normal, 0.925, &shadow); + + cairo_save (cr); + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + if (params->xthickness == 3 || params->ythickness == 3) + { + if (params->xthickness == 3) + xoffset = 1; + if (params->ythickness == 3) + yoffset = 1; + } + + radius = MIN (radius, MIN ((width - 2.0 - xoffset * 2.0) / 2.0, (height - 2.0 - yoffset * 2) / 2.0)); + + if (params->xthickness == 3 || params->ythickness == 3) + { + cairo_translate (cr, 0.5, 0.5); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); + } + + ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, + width-(xoffset*2)-2, + height-(yoffset*2)-2, + radius, params->corners); + + if (!params->active) + { + cairo_pattern_t *pattern; + + CairoColor top_shade, bottom_shade; + ge_shade_color (fill, 0.95, &top_shade); + ge_shade_color (fill, 1.05, &bottom_shade); + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, top_shade.r, top_shade.g, top_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bottom_shade.r, bottom_shade.g, bottom_shade.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + cairo_pattern_t *pattern; + + ge_cairo_set_color (cr, fill); + cairo_fill_preserve (cr); + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 0.4, shadow.r, shadow.g, shadow.b, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.2); + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + pattern = cairo_pattern_create_linear (0, yoffset+1, 0, 3+yoffset); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + pattern = cairo_pattern_create_linear (xoffset+1, 0, 3+xoffset, 0); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + + /* Drawing the border */ + + if (!params->active && params->is_default) + { + const CairoColor *l = &colors->shade[4]; + const CairoColor *d = &colors->shade[4]; + ge_cairo_set_color (cr, l); + ge_cairo_stroke_rectangle (cr, 2.5, 2.5, width-5, height-5); + + ge_cairo_set_color (cr, d); + ge_cairo_stroke_rectangle (cr, 3.5, 3.5, width-7, height-7); + } + + if (params->disabled) + ge_cairo_set_color (cr, border_disabled); + else + if (!params->active) + clearlooks_set_border_gradient (cr, &border_normal, 1.32, 0, height); + else + ge_cairo_set_color (cr, &border_normal); + + ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5, + width-(xoffset*2)-1, height-(yoffset*2)-1, + radius, params->corners); + cairo_stroke (cr); + + /* Draw the "shadow" */ + if (!params->active) + { + cairo_translate (cr, 0.5, 0.5); + /* Draw right shadow */ + cairo_move_to (cr, width-params->xthickness, params->ythickness - 1); + cairo_line_to (cr, width-params->xthickness, height - params->ythickness - 1); + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1); + cairo_stroke (cr); + + /* Draw topleft shadow */ + clearlooks_draw_top_left_highlight (cr, fill, params, width, height, radius); + } + cairo_restore (cr); +} + +static void +clearlooks_inverted_draw_progressbar_fill (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ProgressBarParameters *progressbar, + int x, int y, int width, int height, + gint offset) +{ + boolean is_horizontal = progressbar->orientation < 2; + double tile_pos = 0; + double stroke_width; + double radius; + int x_step; + + cairo_pattern_t *pattern; + CairoColor bg_shade; + CairoColor border; + CairoColor shadow; + CairoColor top_shade; + + radius = MAX (0, params->radius - params->xthickness); + + cairo_save (cr); + + if (!is_horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP)) + ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height); + + /* Clamp the radius so that the _height_ fits ... */ + radius = MIN (radius, height / 2.0); + + stroke_width = height*2; + x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */ + + cairo_translate (cr, x, y); + + cairo_save (cr); + /* This is kind of nasty ... Clip twice from each side in case the length + * of the fill is smaller than twice the radius. */ + ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + + ge_shade_color (&colors->spot[1], 1.05, &top_shade); + + /* Draw the background gradient */ + ge_shade_color (&colors->spot[1], 0.925, &bg_shade); + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, bg_shade.r, bg_shade.g, bg_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, top_shade.r, top_shade.g, top_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg_shade.r, bg_shade.g, bg_shade.b); + cairo_set_source (cr, pattern); + cairo_paint (cr); + cairo_pattern_destroy (pattern); + + /* Draw the Strokes */ + while (tile_pos <= width+x_step) + { + cairo_move_to (cr, stroke_width/2-x_step, 0); + cairo_line_to (cr, stroke_width-x_step, 0); + cairo_line_to (cr, stroke_width/2-x_step, height); + cairo_line_to (cr, -x_step, height); + + cairo_translate (cr, stroke_width, 0); + tile_pos += stroke_width; + } + + cairo_set_source_rgba (cr, colors->spot[2].r, + colors->spot[2].g, + colors->spot[2].b, + 0.15); + + cairo_fill (cr); + cairo_restore (cr); /* rounded clip region */ + + /* inner highlight border + * This is again kinda ugly. Draw once from each side, clipping away the other. */ + cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.5); + + /* left side */ + cairo_save (cr); + cairo_rectangle (cr, 0, 0, width / 2, height); + cairo_clip (cr); + + if (progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + else + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + /* right side */ + cairo_save (cr); + cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height); + cairo_clip (cr); + + if (progressbar->value < 1.0 || progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + else + ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + + /* Draw the dark lines and the shadow */ + cairo_save (cr); + /* Again, this weird clip area. */ + ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + cairo_clip (cr); + ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + cairo_clip (cr); + + border = colors->spot[2]; + border.a = 0.5; + shadow.r = 0.0; + shadow.g = 0.0; + shadow.b = 0.0; + shadow.a = 0.1; + + if (progressbar->pulsing) + { + /* At the beginning of the bar. */ + cairo_move_to (cr, 0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, -0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + if (progressbar->value < 1.0 || progressbar->pulsing) + { + /* At the end of the bar. */ + cairo_move_to (cr, width - 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_move_to (cr, width + 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); + } + + cairo_restore (cr); + + cairo_restore (cr); /* rotation, mirroring */ +} + +static void +clearlooks_inverted_draw_menuitem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->spot[1]; + CairoColor fill_shade; + CairoColor border = colors->spot[2]; + cairo_pattern_t *pattern; + + ge_shade_color (&border, 1.05, &border); + ge_shade_color (fill, 0.85, &fill_shade); + cairo_set_line_width (cr, 1.0); + + ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, widget->radius, widget->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, fill_shade.r, fill_shade.g, fill_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill->r, fill->g, fill->b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); +} + +static void +clearlooks_inverted_draw_menubaritem (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height) +{ + CairoColor *fill = (CairoColor*)&colors->spot[1]; + CairoColor fill_shade; + CairoColor border = colors->spot[2]; + cairo_pattern_t *pattern; + + ge_shade_color (&border, 1.05, &border); + ge_shade_color (fill, 0.85, &fill_shade); + + cairo_set_line_width (cr, 1.0); + ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1, height, widget->radius, widget->corners); + + pattern = cairo_pattern_create_linear (x, y, x, y + height); + cairo_pattern_add_color_stop_rgb (pattern, 0, fill_shade.r, fill_shade.g, fill_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, fill->r, fill->g, fill->b); + + cairo_set_source (cr, pattern); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pattern); + + ge_cairo_set_color (cr, &border); + cairo_stroke_preserve (cr); +} + +static void +clearlooks_inverted_draw_tab (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const TabParameters *tab, + int x, int y, int width, int height) +{ + const CairoColor *border1 = &colors->shade[6]; + const CairoColor *border2 = &colors->shade[5]; + const CairoColor *stripe_fill = &colors->spot[1]; + const CairoColor *stripe_border = &colors->spot[2]; + const CairoColor *fill; + CairoColor hilight; + CairoColor shadow; + + cairo_pattern_t *pattern; + + double radius; + double strip_size; + + radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + /* Set clip */ + cairo_rectangle (cr, x, y, width, height); + cairo_clip (cr); + cairo_new_path (cr); + + /* Translate and set line width */ + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y+0.5); + + + /* Make the tabs slightly bigger than they should be, to create a gap */ + /* And calculate the strip size too, while you're at it */ + if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) + { + height += 3.0; + strip_size = 2.0/height; /* 2 pixel high strip */ + + if (tab->gap_side == CL_GAP_TOP) + cairo_translate (cr, 0.0, -3.0); /* gap at the other side */ + } + else + { + width += 3.0; + strip_size = 2.0/width; + + if (tab->gap_side == CL_GAP_LEFT) + cairo_translate (cr, -3.0, 0.0); /* gap at the other side */ + } + + /* Set the fill color */ + fill = &colors->bg[params->state_type]; + + /* Set tab shape */ + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, + radius, params->corners); + + /* Draw fill */ + ge_cairo_set_color (cr, fill); + cairo_fill (cr); + + ge_shade_color (fill, 1.3, &hilight); + + /* Draw highlight */ + if (!params->active) + { + ShadowParameters shadow; + + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = params->corners; + /* + clearlooks_draw_highlight_and_shade (cr, colors, &shadow, + width, + height, radius);*/ + } + + if (params->active) + { + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + ge_shade_color (fill, 0.92, &shadow); + + cairo_pattern_add_color_stop_rgba (pattern, 0.0, hilight.r, hilight.g, hilight.b, 0.4); + cairo_pattern_add_color_stop_rgba (pattern, 1.0/height, hilight.r, hilight.g, hilight.b, 0.4); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, fill->r,fill->g,fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r,shadow.g,shadow.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + /* Draw shade */ + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b); + cairo_pattern_add_color_stop_rgba (pattern, strip_size, hilight.r, hilight.g, hilight.b, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 0.8, hilight.r, hilight.g, hilight.b, 0.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + if (params->active) + { + ge_cairo_set_color (cr, border2); + cairo_stroke (cr); + } + else + { + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2 ); + + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, border1->r, border1->g, border1->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, border2->r, border2->g, border2->b); + cairo_set_source (cr, pattern); + cairo_stroke (cr); + cairo_pattern_destroy (pattern); + } +} + +static void +clearlooks_inverted_draw_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + const CairoColor *border = &colors->shade[params->disabled ? 4 : 6]; + const CairoColor *spot = &colors->spot[1]; + const CairoColor *fill = &colors->shade[2]; + double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0)); + + cairo_pattern_t *pattern; + + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y); + + if (params->disabled) + border = &colors->shade[4]; + else if (params->prelight) + border = &colors->spot[2]; + else + border = &colors->shade[6]; + + /* fill the widget */ + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); + + /* Fake light */ + if (!params->disabled) + { + const CairoColor *top = &colors->shade[2]; + const CairoColor *bot = &colors->shade[0]; + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, top->r, top->g, top->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bot->r, bot->g, bot->b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + } + else + { + ge_cairo_set_color (cr, fill); + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); + cairo_fill (cr); + } + + /* Set the clip */ + cairo_save (cr); + cairo_rectangle (cr, 0.5, 0.5, 6, height-2); + cairo_rectangle (cr, width-7.5, 0.5, 6 , height-2); + cairo_clip_preserve (cr); + + cairo_new_path (cr); + + /* Draw the handles */ + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners); + pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, 0.5+height); + + if (params->prelight) + { + CairoColor highlight; + ge_shade_color (spot, 1.5, &highlight); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, spot->r, spot->g, spot->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, highlight.r, highlight.g, highlight.b); + cairo_set_source (cr, pattern); + } + else { + CairoColor hilight; + ge_shade_color (fill, 1.5, &hilight); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + } + + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); + + /* Draw the border */ + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + if (params->prelight || params->disabled) + ge_cairo_set_color (cr, border); + else + clearlooks_set_border_gradient (cr, border, 1.2, 0, height); + cairo_stroke (cr); + + /* Draw handle lines */ + if (width > 14) + { + cairo_move_to (cr, 6, 0.5); + cairo_line_to (cr, 6, height-1); + + cairo_move_to (cr, width-7, 0.5); + cairo_line_to (cr, width-7, height-1); + + cairo_set_line_width (cr, 1.0); + cairo_set_source_rgba (cr, border->r, + border->g, + border->b, + 0.3); + cairo_stroke (cr); + } +} + +static void +clearlooks_inverted_draw_slider_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + cairo_set_line_width (cr, 1.0); + + if (!slider->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + cairo_translate (cr, x+0.5, y+0.5); + + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); + params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); + + if (width > 24) + params->style_functions->draw_gripdots (cr, colors, 0, 0, width-2, height-2, 3, 3, 0); +} + +static void +clearlooks_inverted_draw_list_view_header (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const ListViewHeaderParameters *header, + int x, int y, int width, int height) +{ + const CairoColor *fill = &colors->bg[params->state_type]; + const CairoColor *border = &colors->shade[4]; + cairo_pattern_t *pattern; + CairoColor hilight_header; + CairoColor hilight; + CairoColor shadow; + + ge_shade_color (border, 1.5, &hilight); + ge_shade_color (fill, 1.05, &hilight_header); + ge_shade_color (fill, 0.95, &shadow); + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1.0); + + /* Draw highlight */ + if (header->order == CL_ORDER_FIRST) + { + cairo_move_to (cr, 0.5, height-1); + cairo_line_to (cr, 0.5, 0.5); + } + else + cairo_move_to (cr, 0.0, 0.5); + + cairo_line_to (cr, width, 0.5); + + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); + + /* Draw bottom border */ + cairo_move_to (cr, 0.0, height-0.5); + cairo_line_to (cr, width, height-0.5); + ge_cairo_set_color (cr, border); + cairo_stroke (cr); + + /* Draw bottom shade */ + pattern = cairo_pattern_create_linear (0.0, 0, 0.0, height-1.0); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, shadow.r, shadow.g, shadow.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, hilight_header.r, hilight_header.g, hilight_header.b); + + cairo_rectangle (cr, 0, 1, width, height-2); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + /* Draw resize grip */ + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) + { + SeparatorParameters separator; + separator.horizontal = FALSE; + + if (params->ltr) + params->style_functions->draw_separator (cr, colors, params, &separator, + width-1.5, 4.0, 2, height-8.0); + else + params->style_functions->draw_separator (cr, colors, params, &separator, + 1.5, 4.0, 2, height-8.0); + } +} + + +static void +clearlooks_inverted_draw_scrollbar_stepper (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + const ScrollBarStepperParameters *stepper, + int x, int y, int width, int height) +{ + CairoCorners corners = CR_CORNER_NONE; + CairoColor border; + CairoColor s1, s2, s3; + cairo_pattern_t *pattern; + ShadowParameters shadow; + double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + + ge_shade_color(&colors->shade[6], 1.05, &border); + + if (scrollbar->horizontal) + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + } + else + { + if (stepper->stepper == CL_STEPPER_A) + corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; + else if (stepper->stepper == CL_STEPPER_D) + corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; + } + + cairo_translate (cr, x, y); + cairo_set_line_width (cr, 1); + + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners); + + if (scrollbar->horizontal) + pattern = cairo_pattern_create_linear (0, 0, 0, height); + else + pattern = cairo_pattern_create_linear (0, 0, width, 0); + + s1 = colors->bg[widget->state_type]; + ge_shade_color(&s1, 0.95, &s2); + ge_shade_color(&s1, 1.05, &s3); + + cairo_pattern_add_color_stop_rgb(pattern, 0, s2.r, s2.g, s2.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, s3.r, s3.g, s3.b); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + clearlooks_draw_top_left_highlight (cr, &s1, widget, width, height, radius); + + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); + clearlooks_set_border_gradient (cr, &border, 1.2, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0)); + cairo_stroke (cr); + + cairo_translate (cr, 0.5, 0.5); + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = corners; + /* + clearlooks_draw_highlight_and_shade (cr, &shadow, + width, + height, params->radius);*/ +} + +static void +clearlooks_inverted_draw_scrollbar_slider (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height) +{ + if (scrollbar->junction & CL_JUNCTION_BEGIN) + { + if (scrollbar->horizontal) + { + x -= 1; + width += 1; + } + else + { + y -= 1; + height += 1; + } + } + if (scrollbar->junction & CL_JUNCTION_END) + { + if (scrollbar->horizontal) + width += 1; + else + height += 1; + } + + if (!scrollbar->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + + cairo_translate (cr, x, y); + + if (scrollbar->has_color) + { + const CairoColor *border = &colors->shade[8]; + CairoColor fill = scrollbar->color; + CairoColor hilight; + CairoColor shade1, shade2, shade3; + cairo_pattern_t *pattern; + + if (widget->prelight) + ge_shade_color (&fill, 1.1, &fill); + + cairo_set_line_width (cr, 1); + + ge_shade_color (&fill, 1.3, &hilight); + ge_shade_color (&fill, 1.1, &shade1); + ge_shade_color (&fill, 1.05, &shade2); + ge_shade_color (&fill, 0.98, &shade3); + + pattern = cairo_pattern_create_linear (1, 1, 1, height-2); + cairo_pattern_add_color_stop_rgb (pattern, 0, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade3.r, shade3.g, shade3.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade1.r, shade1.g, shade1.b); + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); + ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3); + + ge_cairo_set_color (cr, border); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); + } + else + { + CairoColor border; + CairoColor s1, s2, s3; + cairo_pattern_t *pattern; + int bar_x, i; + + const CairoColor *dark = &colors->shade[4]; + const CairoColor *light = &colors->shade[0]; + + ge_shade_color(&colors->shade[6], 1.05, &border); + + pattern = cairo_pattern_create_linear(1, 1, 1, height-1); + + s1 = colors->bg[widget->state_type]; + ge_shade_color(&s1, 0.95, &s2); + ge_shade_color(&s1, 1.05, &s3); + + cairo_pattern_add_color_stop_rgb(pattern, 0, s2.r, s2.g, s2.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, s3.r, s3.g, s3.b); + + cairo_rectangle (cr, 1, 1, width-2, height-2); + cairo_set_source(cr, pattern); + cairo_fill(cr); + cairo_pattern_destroy(pattern); + + clearlooks_draw_top_left_highlight (cr, &s2, widget, width, height, 0); + + clearlooks_set_border_gradient (cr, &border, 1.2, 0, height); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); + + /* draw handles */ + cairo_set_line_width (cr, 1); + + bar_x = width/2 - 4; + cairo_translate(cr, 0.5, 0.5); + for (i=0; i<3; i++) + { + cairo_move_to (cr, bar_x, 4); + cairo_line_to (cr, bar_x, height-5); + ge_cairo_set_color (cr, dark); + cairo_stroke (cr); + + cairo_move_to (cr, bar_x+1, 4); + cairo_line_to (cr, bar_x+1, height-5); + ge_cairo_set_color (cr, light); + cairo_stroke (cr); + + bar_x += 3; + } + } +} + +static void +clearlooks_inverted_draw_selected_cell (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) +{ + CairoColor upper_color; + CairoColor lower_color; + CairoColor border; + cairo_pattern_t *pattern; + cairo_save (cr); + + cairo_translate (cr, x, y); + + if (params->focus) + upper_color = colors->base[params->state_type]; + else + upper_color = colors->base[GTK_STATE_ACTIVE]; + + ge_shade_color(&upper_color, 0.9, &lower_color); + + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, lower_color.r, + lower_color.g, + lower_color.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, upper_color.r, + upper_color.g, + upper_color.b); + + + cairo_set_source (cr, pattern); + cairo_rectangle (cr, 0, 0, width, height); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + ge_shade_color(&upper_color, 0.8, &border); + + cairo_move_to (cr, 0, 0.5); + cairo_rel_line_to (cr, width, 0); + cairo_move_to (cr, 0, height-0.5); + cairo_rel_line_to (cr, width, 0); + + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + + cairo_restore (cr); +} + +void +clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions) +{ + functions->draw_button = clearlooks_inverted_draw_button; + functions->draw_slider = clearlooks_inverted_draw_slider; + functions->draw_slider_button = clearlooks_inverted_draw_slider_button; + functions->draw_progressbar_fill = clearlooks_inverted_draw_progressbar_fill; + functions->draw_menuitem = clearlooks_inverted_draw_menuitem; + functions->draw_menubaritem = clearlooks_inverted_draw_menubaritem; + functions->draw_tab = clearlooks_inverted_draw_tab; + functions->draw_list_view_header = clearlooks_inverted_draw_list_view_header; + functions->draw_scrollbar_stepper = clearlooks_inverted_draw_scrollbar_stepper; + functions->draw_scrollbar_slider = clearlooks_inverted_draw_scrollbar_slider; + functions->draw_selected_cell = clearlooks_inverted_draw_selected_cell; +} + diff --git a/libs/clearlooks-newer/clearlooks_rc_style.c b/libs/clearlooks-newer/clearlooks_rc_style.c new file mode 100644 index 0000000000..f486453339 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_rc_style.c @@ -0,0 +1,473 @@ +/* Clearlooks theme engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor <otaylor@redhat.com> + * and by Alexander Larsson <alexl@redhat.com> + * Modified by Richard Stellingwerff <remenic@gmail.com> + * Modified by Kulyk Nazar <schamane@myeburg.net> + */ + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" + +#include "animation.h" + +static void clearlooks_rc_style_init (ClearlooksRcStyle *style); +#ifdef HAVE_ANIMATION +static void clearlooks_rc_style_finalize (GObject *object); +#endif +static void clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass); +static GtkStyle *clearlooks_rc_style_create_style (GtkRcStyle *rc_style); +static guint clearlooks_rc_style_parse (GtkRcStyle *rc_style, + GtkSettings *settings, + GScanner *scanner); +static void clearlooks_rc_style_merge (GtkRcStyle *dest, + GtkRcStyle *src); + + +static GtkRcStyleClass *clearlooks_parent_rc_class; + +GType clearlooks_type_rc_style = 0; + +enum +{ + TOKEN_SCROLLBARCOLOR = G_TOKEN_LAST + 1, + TOKEN_COLORIZESCROLLBAR, + TOKEN_CONTRAST, + TOKEN_SUNKENMENU, + TOKEN_PROGRESSBARSTYLE, + TOKEN_MENUBARSTYLE, + TOKEN_TOOLBARSTYLE, + TOKEN_MENUITEMSTYLE, + TOKEN_LISTVIEWITEMSTYLE, + TOKEN_ANIMATION, + TOKEN_STYLE, + TOKEN_RADIUS, + + TOKEN_CLASSIC, + TOKEN_GLOSSY, + TOKEN_INVERTED, + TOKEN_GUMMY, + + TOKEN_TRUE, + TOKEN_FALSE +}; + +static struct +{ + const gchar *name; + guint token; +} +clearlooks_gtk2_rc_symbols[] = +{ + { "scrollbar_color", TOKEN_SCROLLBARCOLOR }, + { "colorize_scrollbar", TOKEN_COLORIZESCROLLBAR }, + { "contrast", TOKEN_CONTRAST }, + { "sunkenmenubar", TOKEN_SUNKENMENU }, + { "progressbarstyle", TOKEN_PROGRESSBARSTYLE }, + { "menubarstyle", TOKEN_MENUBARSTYLE }, + { "toolbarstyle", TOKEN_TOOLBARSTYLE }, + { "menuitemstyle", TOKEN_MENUITEMSTYLE }, + { "listviewitemstyle", TOKEN_LISTVIEWITEMSTYLE }, + { "animation", TOKEN_ANIMATION }, + { "style", TOKEN_STYLE }, + { "radius", TOKEN_RADIUS }, + + { "CLASSIC", TOKEN_CLASSIC }, + { "GLOSSY", TOKEN_GLOSSY }, + { "INVERTED", TOKEN_INVERTED }, + { "GUMMY", TOKEN_GUMMY }, + + { "TRUE", TOKEN_TRUE }, + { "FALSE", TOKEN_FALSE } +}; + + +void +clearlooks_rc_style_register_type (GTypeModule *module) +{ + static const GTypeInfo object_info = + { + sizeof (ClearlooksRcStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_rc_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksRcStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_rc_style_init, + NULL + }; + + clearlooks_type_rc_style = g_type_module_register_type (module, + GTK_TYPE_RC_STYLE, + "ClearlooksRcStyle", + &object_info, 0); +} + +static void +clearlooks_rc_style_init (ClearlooksRcStyle *clearlooks_rc) +{ + clearlooks_rc->style = CL_STYLE_CLASSIC; + + clearlooks_rc->flags = 0; + + clearlooks_rc->contrast = 1.0; + clearlooks_rc->menubarstyle = 0; + clearlooks_rc->toolbarstyle = 0; + clearlooks_rc->animation = FALSE; + clearlooks_rc->colorize_scrollbar = FALSE; + clearlooks_rc->radius = 3.0; +} + +#ifdef HAVE_ANIMATION +static void +clearlooks_rc_style_finalize (GObject *object) +{ + /* cleanup all the animation stuff */ + clearlooks_animation_cleanup (); + + if (G_OBJECT_CLASS (clearlooks_parent_rc_class)->finalize != NULL) + G_OBJECT_CLASS (clearlooks_parent_rc_class)->finalize(object); +} +#endif + + +static void +clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass) +{ + GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass); +#ifdef HAVE_ANIMATION + GObjectClass *g_object_class = G_OBJECT_CLASS (klass); +#endif + + clearlooks_parent_rc_class = g_type_class_peek_parent (klass); + + rc_style_class->parse = clearlooks_rc_style_parse; + rc_style_class->create_style = clearlooks_rc_style_create_style; + rc_style_class->merge = clearlooks_rc_style_merge; + +#ifdef HAVE_ANIMATION + g_object_class->finalize = clearlooks_rc_style_finalize; +#endif +} + +static guint +clearlooks_gtk2_rc_parse_boolean (GtkSettings *settings, + GScanner *scanner, + gboolean *retval) +{ + guint token; + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token == TOKEN_TRUE) + *retval = TRUE; + else if (token == TOKEN_FALSE) + *retval = FALSE; + else + return TOKEN_TRUE; + + return G_TOKEN_NONE; +} + +static guint +clearlooks_gtk2_rc_parse_color(GtkSettings *settings, + GScanner *scanner, + GdkColor *color) +{ + guint token; + + /* Skip 'blah_color' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + return gtk_rc_parse_color (scanner, color); +} + +static guint +clearlooks_gtk2_rc_parse_double (GtkSettings *settings, + GScanner *scanner, + gdouble *val) +{ + guint token; + + /* Skip 'blah' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_FLOAT) + return G_TOKEN_FLOAT; + + *val = scanner->value.v_float; + + return G_TOKEN_NONE; +} + +static guint +clearlooks_gtk2_rc_parse_int (GtkSettings *settings, + GScanner *scanner, + guint8 *progressbarstyle) +{ + guint token; + + /* Skip 'sunkenmenubar' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *progressbarstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +clearlooks_gtk2_rc_parse_style (GtkSettings *settings, + GScanner *scanner, + ClearlooksStyles *style) +{ + guint token; + + g_assert (CL_NUM_STYLES == CL_STYLE_GUMMY + 1); /* so that people don't forget ;-) */ + + /* Skip 'style' */ + token = g_scanner_get_next_token (scanner); + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token (scanner); + + switch (token) + { + case TOKEN_CLASSIC: + *style = CL_STYLE_CLASSIC; + break; + case TOKEN_GLOSSY: + *style = CL_STYLE_GLOSSY; + break; + case TOKEN_INVERTED: + *style = CL_STYLE_INVERTED; + break; + case TOKEN_GUMMY: + *style = CL_STYLE_GUMMY; + break; + default: + return TOKEN_CLASSIC; + } + + return G_TOKEN_NONE; +} + +static guint +clearlooks_gtk2_rc_parse_dummy (GtkSettings *settings, + GScanner *scanner, + gchar *name) +{ + guint token; + + /* Skip option */ + token = g_scanner_get_next_token (scanner); + + /* print a warning. Isn't there a way to get the string from the scanner? */ + g_scanner_warn (scanner, "Clearlooks configuration option \"%s\" is not supported and will be ignored.", name); + + /* equal sign */ + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + /* eat whatever comes next */ + token = g_scanner_get_next_token (scanner); + + return G_TOKEN_NONE; +} + +static guint +clearlooks_rc_style_parse (GtkRcStyle *rc_style, + GtkSettings *settings, + GScanner *scanner) + +{ + static GQuark scope_id = 0; + ClearlooksRcStyle *clearlooks_style = CLEARLOOKS_RC_STYLE (rc_style); + + guint old_scope; + guint token; + guint i; + + /* Set up a new scope in this scanner. */ + + if (!scope_id) + scope_id = g_quark_from_string("clearlooks_theme_engine"); + + /* If we bail out due to errors, we *don't* reset the scope, so the + * error messaging code can make sense of our tokens. + */ + old_scope = g_scanner_set_scope(scanner, scope_id); + + /* Now check if we already added our symbols to this scope + * (in some previous call to clearlooks_rc_style_parse for the + * same scanner. + */ + + if (!g_scanner_lookup_symbol(scanner, clearlooks_gtk2_rc_symbols[0].name)) + { + for (i = 0; i < G_N_ELEMENTS (clearlooks_gtk2_rc_symbols); i++) + g_scanner_scope_add_symbol(scanner, scope_id, + clearlooks_gtk2_rc_symbols[i].name, + GINT_TO_POINTER(clearlooks_gtk2_rc_symbols[i].token)); + } + + /* We're ready to go, now parse the top level */ + + token = g_scanner_peek_next_token(scanner); + while (token != G_TOKEN_RIGHT_CURLY) + { + switch (token) + { + case TOKEN_SCROLLBARCOLOR: + token = clearlooks_gtk2_rc_parse_color (settings, scanner, &clearlooks_style->scrollbar_color); + clearlooks_style->flags |= CL_FLAG_SCROLLBAR_COLOR; + break; + case TOKEN_COLORIZESCROLLBAR: + token = clearlooks_gtk2_rc_parse_boolean (settings, scanner, &clearlooks_style->colorize_scrollbar); + clearlooks_style->flags |= CL_FLAG_COLORIZE_SCROLLBAR; + break; + case TOKEN_CONTRAST: + token = clearlooks_gtk2_rc_parse_double (settings, scanner, &clearlooks_style->contrast); + clearlooks_style->flags |= CL_FLAG_CONTRAST; + break; + case TOKEN_MENUBARSTYLE: + token = clearlooks_gtk2_rc_parse_int (settings, scanner, &clearlooks_style->menubarstyle); + clearlooks_style->flags |= CL_FLAG_MENUBARSTYLE; + break; + case TOKEN_TOOLBARSTYLE: + token = clearlooks_gtk2_rc_parse_int (settings, scanner, &clearlooks_style->toolbarstyle); + clearlooks_style->flags |= CL_FLAG_TOOLBARSTYLE; + break; + case TOKEN_ANIMATION: + token = clearlooks_gtk2_rc_parse_boolean (settings, scanner, &clearlooks_style->animation); + clearlooks_style->flags |= CL_FLAG_ANIMATION; + break; + case TOKEN_STYLE: + token = clearlooks_gtk2_rc_parse_style (settings, scanner, &clearlooks_style->style); + clearlooks_style->flags |= CL_FLAG_STYLE; + break; + case TOKEN_RADIUS: + token = clearlooks_gtk2_rc_parse_double (settings, scanner, &clearlooks_style->radius); + clearlooks_style->flags |= CL_FLAG_RADIUS; + break; + + /* stuff to ignore */ + case TOKEN_SUNKENMENU: + token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "sunkenmenu"); + break; + case TOKEN_PROGRESSBARSTYLE: + token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "progressbarstyle"); + break; + case TOKEN_MENUITEMSTYLE: + token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "menuitemstyle"); + break; + case TOKEN_LISTVIEWITEMSTYLE: + token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "listviewitemstyle"); + break; + + default: + g_scanner_get_next_token(scanner); + token = G_TOKEN_RIGHT_CURLY; + break; + } + + if (token != G_TOKEN_NONE) + return token; + + token = g_scanner_peek_next_token(scanner); + } + + g_scanner_get_next_token(scanner); + + g_scanner_set_scope(scanner, old_scope); + + return G_TOKEN_NONE; +} + +static void +clearlooks_rc_style_merge (GtkRcStyle *dest, + GtkRcStyle *src) +{ + ClearlooksRcStyle *dest_w, *src_w; + ClearlooksRcFlags flags; + + clearlooks_parent_rc_class->merge (dest, src); + + if (!CLEARLOOKS_IS_RC_STYLE (src)) + return; + + src_w = CLEARLOOKS_RC_STYLE (src); + dest_w = CLEARLOOKS_RC_STYLE (dest); + + flags = (~dest_w->flags) & src_w->flags; + + if (flags & CL_FLAG_STYLE) + dest_w->style = src_w->style; + if (flags & CL_FLAG_CONTRAST) + dest_w->contrast = src_w->contrast; + if (flags & CL_FLAG_MENUBARSTYLE) + dest_w->menubarstyle = src_w->menubarstyle; + if (flags & CL_FLAG_TOOLBARSTYLE) + dest_w->toolbarstyle = src_w->toolbarstyle; + if (flags & CL_FLAG_SCROLLBAR_COLOR) + dest_w->scrollbar_color = src_w->scrollbar_color; + if (flags & CL_FLAG_COLORIZE_SCROLLBAR) + dest_w->colorize_scrollbar = src_w->colorize_scrollbar; + if (flags & CL_FLAG_ANIMATION) + dest_w->animation = src_w->animation; + if (flags & CL_FLAG_RADIUS) + dest_w->radius = src_w->radius; + + dest_w->flags |= src_w->flags; +} + + +/* Create an empty style suitable to this RC style + */ +static GtkStyle * +clearlooks_rc_style_create_style (GtkRcStyle *rc_style) +{ + return GTK_STYLE (g_object_new (CLEARLOOKS_TYPE_STYLE, NULL)); +} diff --git a/libs/clearlooks-newer/clearlooks_rc_style.h b/libs/clearlooks-newer/clearlooks_rc_style.h new file mode 100644 index 0000000000..a80a846000 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_rc_style.h @@ -0,0 +1,74 @@ +/* Clearlooks Theme Engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor <otaylor@redhat.com> + * and by Alexander Larsson <alexl@redhat.com> + * Modified by Richard Stellingwerff <remenic@gmail.com> + * Modified by Kulyk Nazar <schamane@myeburg.net> + */ + +#include <gtk/gtkrc.h> +#include "clearlooks_types.h" + +typedef struct _ClearlooksRcStyle ClearlooksRcStyle; +typedef struct _ClearlooksRcStyleClass ClearlooksRcStyleClass; + +GE_INTERNAL extern GType clearlooks_type_rc_style; + +#define CLEARLOOKS_TYPE_RC_STYLE clearlooks_type_rc_style +#define CLEARLOOKS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyle)) +#define CLEARLOOKS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyleClass)) +#define CLEARLOOKS_IS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_RC_STYLE)) +#define CLEARLOOKS_IS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLEARLOOKS_TYPE_RC_STYLE)) +#define CLEARLOOKS_RC_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyleClass)) + +/* XXX: needs fixing! */ +typedef enum { + CL_FLAG_STYLE = 1 << 0, + CL_FLAG_SCROLLBAR_COLOR = 1 << 1, + CL_FLAG_COLORIZE_SCROLLBAR = 1 << 2, + CL_FLAG_CONTRAST = 1 << 3, + CL_FLAG_MENUBARSTYLE = 1 << 4, + CL_FLAG_TOOLBARSTYLE = 1 << 5, + CL_FLAG_ANIMATION = 1 << 6, + CL_FLAG_RADIUS = 1 << 7 +} ClearlooksRcFlags; + +struct _ClearlooksRcStyle +{ + GtkRcStyle parent_instance; + + ClearlooksRcFlags flags; + + ClearlooksStyles style; + + GdkColor scrollbar_color; + gboolean colorize_scrollbar; + double contrast; + guint8 menubarstyle; + guint8 toolbarstyle; + gboolean animation; + double radius; +}; + +struct _ClearlooksRcStyleClass +{ + GtkRcStyleClass parent_class; +}; + +GE_INTERNAL void clearlooks_rc_style_register_type (GTypeModule *module); diff --git a/libs/clearlooks-newer/clearlooks_style.c b/libs/clearlooks-newer/clearlooks_style.c new file mode 100644 index 0000000000..48b6647df3 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_style.c @@ -0,0 +1,1647 @@ +/* Clearlooks theme engine + * Copyright (C) 2005 Richard Stellingwerff. + * Copyright (C) 2007 Benjamin Berg <benjamin@sipsolutions.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include <gtk/gtk.h> +#include <cairo.h> +#include <math.h> +#include <string.h> + +#include <ge-support.h> +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" +#include "clearlooks_draw.h" +#include "support.h" + +/* #define DEBUG 1 */ + +#define DETAIL(xx) ((detail) && (!strcmp(xx, detail))) + +#define DRAW_ARGS GtkStyle *style, \ + GdkWindow *window, \ + GtkStateType state_type, \ + GtkShadowType shadow_type, \ + GdkRectangle *area, \ + GtkWidget *widget, \ + const gchar *detail, \ + gint x, \ + gint y, \ + gint width, \ + gint height + +#ifdef HAVE_ANIMATION +#include "animation.h" +#endif + +#define STYLE_FUNCTION(function) (clearlooks_style_class->style_functions[CLEARLOOKS_STYLE (style)->style].function) + +static ClearlooksStyleClass *clearlooks_style_class; +static GtkStyleClass *clearlooks_parent_class; + +static void +clearlooks_set_widget_parameters (const GtkWidget *widget, + const GtkStyle *style, + GtkStateType state_type, + WidgetParameters *params) +{ + params->style_functions = &(clearlooks_style_class->style_functions[CLEARLOOKS_STYLE (style)->style]); + + params->active = (state_type == GTK_STATE_ACTIVE); + params->prelight = (state_type == GTK_STATE_PRELIGHT); + params->disabled = (state_type == GTK_STATE_INSENSITIVE); + params->state_type = (ClearlooksStateType)state_type; + params->corners = CR_CORNER_ALL; + params->ltr = ge_widget_is_ltr ((GtkWidget*)widget); + params->focus = widget && GTK_WIDGET_HAS_FOCUS (widget); + params->is_default = widget && GE_WIDGET_HAS_DEFAULT (widget); + params->enable_glow = FALSE; + params->radius = CLEARLOOKS_STYLE (style)->radius; + + if (!params->active && widget && GE_IS_TOGGLE_BUTTON (widget)) + params->active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + params->xthickness = style->xthickness; + params->ythickness = style->ythickness; + + /* This is used in GtkEntry to fake transparency. The reason to do this + * is that the entry has it's entire background filled with base[STATE]. + * This is not a very good solution as it will eg. fail if one changes + * the background color of a notebook. */ + params->parentbg = CLEARLOOKS_STYLE (style)->colors.bg[state_type]; + clearlooks_get_parent_bg (widget, ¶ms->parentbg); +} + +static void +clearlooks_style_draw_flat_box (DRAW_ARGS) +{ + if (detail && + state_type == GTK_STATE_SELECTED && ( + !strncmp ("cell_even", detail, 9) || + !strncmp ("cell_odd", detail, 8))) + { + WidgetParameters params; + ClearlooksStyle *clearlooks_style; + ClearlooksColors *colors; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + clearlooks_style = CLEARLOOKS_STYLE (style); + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + colors = &clearlooks_style->colors; + cr = ge_gdk_drawable_to_cairo (window, area); + + /* XXX: We could expose the side details by setting params->corners accordingly + * or adding another option. */ + STYLE_FUNCTION (draw_selected_cell) (cr, colors, ¶ms, x, y, width, height); + + cairo_destroy (cr); + } + else if (DETAIL ("tooltip")) + { + WidgetParameters params; + ClearlooksStyle *clearlooks_style; + ClearlooksColors *colors; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + clearlooks_style = CLEARLOOKS_STYLE (style); + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + colors = &clearlooks_style->colors; + cr = ge_gdk_drawable_to_cairo (window, area); + + STYLE_FUNCTION (draw_tooltip) (cr, colors, ¶ms, x, y, width, height); + + cairo_destroy (cr); + } + else if ((CLEARLOOKS_STYLE (style)->style == CL_STYLE_GLOSSY || CLEARLOOKS_STYLE (style)->style == CL_STYLE_GUMMY) && + ((DETAIL("checkbutton") || DETAIL("radiobutton")) && state_type == GTK_STATE_PRELIGHT)) + { + /* XXX: Don't draw any check/radiobutton bg in GLOSSY or GUMMY mode. */ + } + else + { + clearlooks_parent_class->draw_flat_box (style, window, state_type, + shadow_type, + area, widget, detail, + x, y, width, height); + } +} + +static void +clearlooks_style_draw_shadow (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + cairo_t *cr = ge_gdk_drawable_to_cairo (window, area); + + CHECK_ARGS + SANITIZE_SIZE + + if ((DETAIL ("entry") && !(widget && widget->parent && GE_IS_TREE_VIEW (widget->parent))) || + (DETAIL ("frame") && ge_is_in_combo_box (widget))) + { + WidgetParameters params; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + /* Override the entries state type, because we are too lame to handle this via + * the focus ring, and GtkEntry doesn't even set the INSENSITIVE state ... */ + if (state_type == GTK_STATE_NORMAL && widget && GE_IS_ENTRY (widget)) + params.state_type = GTK_WIDGET_STATE (widget); + + if (widget && (ge_is_in_combo_box (widget) || GE_IS_SPIN_BUTTON (widget))) + { + width += style->xthickness; + if (!params.ltr) + x -= style->xthickness; + + if (params.ltr) + params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + else + params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + } + + STYLE_FUNCTION (draw_entry) (cr, &clearlooks_style->colors, ¶ms, + x, y, width, height); + } + else if (DETAIL ("frame") && widget && GE_IS_STATUSBAR (widget->parent)) + { + WidgetParameters params; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + gtk_style_apply_default_background (style, window, TRUE, state_type, + area, x, y, width, height); + + STYLE_FUNCTION (draw_statusbar) (cr, colors, ¶ms, + x, y, width, height); + } + else if (DETAIL ("frame")) + { + WidgetParameters params; + FrameParameters frame; + frame.shadow = shadow_type; + frame.gap_x = -1; /* No gap will be drawn */ + frame.border = &colors->shade[4]; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + params.corners = CR_CORNER_NONE; + + if (widget && !g_str_equal ("XfcePanelWindow", gtk_widget_get_name (gtk_widget_get_toplevel (widget)))) + STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, + x, y, width, height); + } + else if (DETAIL ("scrolled_window") || DETAIL ("viewport") || detail == NULL) + { + CairoColor *border = (CairoColor*)&colors->shade[5]; + cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); + ge_cairo_set_color (cr, border); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); + } + else + { + WidgetParameters params; + FrameParameters frame; + + frame.shadow = shadow_type; + frame.gap_x = -1; + frame.border = &colors->shade[5]; + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + params.corners = CR_CORNER_ALL; + + STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, x, y, width, height); + } + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_box_gap (DRAW_ARGS, + GtkPositionType gap_side, + gint gap_x, + gint gap_width) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + cr = ge_gdk_drawable_to_cairo (window, area); + + if (DETAIL ("notebook")) + { + WidgetParameters params; + FrameParameters frame; + gboolean start, end; + + frame.shadow = shadow_type; + frame.gap_side = gap_side; + frame.gap_x = gap_x; + frame.gap_width = gap_width; + frame.border = &colors->shade[5]; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + clearlooks_get_notebook_tab_position (widget, &start, &end); + + params.corners = CR_CORNER_ALL; + switch (gap_side) { + case GTK_POS_LEFT: + if (start) + params.corners ^= CR_CORNER_TOPLEFT; + if (end) + params.corners ^= CR_CORNER_BOTTOMLEFT; + break; + case GTK_POS_RIGHT: + if (start) + params.corners ^= CR_CORNER_TOPRIGHT; + if (end) + params.corners ^= CR_CORNER_BOTTOMRIGHT; + break; + case GTK_POS_TOP: + if (ge_widget_is_ltr (widget)) { + if (start) + params.corners ^= CR_CORNER_TOPLEFT; + if (end) + params.corners ^= CR_CORNER_TOPRIGHT; + } else { + if (start) + params.corners ^= CR_CORNER_TOPRIGHT; + if (end) + params.corners ^= CR_CORNER_TOPLEFT; + } + break; + case GTK_POS_BOTTOM: + if (ge_widget_is_ltr (widget)) { + if (start) + params.corners ^= CR_CORNER_BOTTOMLEFT; + if (end) + params.corners ^= CR_CORNER_BOTTOMRIGHT; + } else { + if (start) + params.corners ^= CR_CORNER_BOTTOMRIGHT; + if (end) + params.corners ^= CR_CORNER_BOTTOMLEFT; + } + break; + } + + /* Fill the background with bg[NORMAL] */ + ge_cairo_rounded_rectangle (cr, x, y, width, height, params.radius, params.corners); + ge_cairo_set_color (cr, &colors->bg[GTK_STATE_NORMAL]); + cairo_fill (cr); + + STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, + x, y, width, height); + } + else + { + clearlooks_parent_class->draw_box_gap (style, window, state_type, shadow_type, + area, widget, detail, + x, y, width, height, + gap_side, gap_x, gap_width); + } + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_extension (DRAW_ARGS, GtkPositionType gap_side) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + cr = ge_gdk_drawable_to_cairo (window, area); + + if (DETAIL ("tab")) + { + WidgetParameters params; + TabParameters tab; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + tab.gap_side = (ClearlooksGapSide)gap_side; + + switch (gap_side) + { + case CL_GAP_BOTTOM: + params.corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; + break; + case CL_GAP_TOP: + params.corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; + break; + case CL_GAP_RIGHT: + params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + break; + case CL_GAP_LEFT: + params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + } + + STYLE_FUNCTION(draw_tab) (cr, colors, ¶ms, &tab, + x, y, width, height); + } + else + { + clearlooks_parent_class->draw_extension (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, + gap_side); + + } + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_handle (DRAW_ARGS, GtkOrientation orientation) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + cairo_t *cr; + gboolean is_horizontal; + + CHECK_ARGS + SANITIZE_SIZE + + cr = ge_gdk_drawable_to_cairo (window, area); + + /* Evil hack to work around broken orientation for toolbars */ + is_horizontal = (width > height); + + if (DETAIL ("handlebox")) + { + WidgetParameters params; + HandleParameters handle; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + handle.type = CL_HANDLE_TOOLBAR; + handle.horizontal = is_horizontal; + + /* Is this ever true? -Daniel */ + if (GE_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE) + { + ToolbarParameters toolbar; + + clearlooks_set_toolbar_parameters (&toolbar, widget, window, x, y); + + toolbar.style = clearlooks_style->toolbarstyle; + + cairo_save (cr); + STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height); + cairo_restore (cr); + } + + STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, + x, y, width, height); + } + else if (DETAIL ("paned")) + { + WidgetParameters params; + HandleParameters handle; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + handle.type = CL_HANDLE_SPLITTER; + handle.horizontal = orientation == GTK_ORIENTATION_HORIZONTAL; + + STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, + x, y, width, height); + } + else + { + WidgetParameters params; + HandleParameters handle; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + handle.type = CL_HANDLE_TOOLBAR; + handle.horizontal = is_horizontal; + + /* Is this ever true? -Daniel */ + if (GE_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE) + { + ToolbarParameters toolbar; + + clearlooks_set_toolbar_parameters (&toolbar, widget, window, x, y); + + toolbar.style = clearlooks_style->toolbarstyle; + + cairo_save (cr); + STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height); + cairo_restore (cr); + } + + STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, + x, y, width, height); + } + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_box (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + const ClearlooksColors *colors; + cairo_t *cr; + + cr = ge_gdk_drawable_to_cairo (window, area); + colors = &clearlooks_style->colors; + + CHECK_ARGS + SANITIZE_SIZE + + if (DETAIL ("menubar") && !ge_is_panel_widget_item(widget)) + { + WidgetParameters params; + MenuBarParameters menubar; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + menubar.style = clearlooks_style->menubarstyle; + + STYLE_FUNCTION(draw_menubar) (cr, colors, ¶ms, &menubar, + x, y, width, height); + } + else if (DETAIL ("button") && widget && widget->parent && + (GE_IS_TREE_VIEW(widget->parent) || + GE_IS_CLIST (widget->parent) || + ge_object_is_a (G_OBJECT(widget->parent), "ETree"))) /* ECanvas inside ETree */ + { + WidgetParameters params; + ListViewHeaderParameters header; + + gint columns, column_index; + gboolean resizable = TRUE; + + /* XXX: This makes unknown treeview header CL_ORDER_MIDDLE, in need for something nicer */ + columns = 3; + column_index = 1; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + params.corners = CR_CORNER_NONE; + + if (GE_IS_TREE_VIEW (widget->parent)) + { + clearlooks_treeview_get_header_index (GTK_TREE_VIEW(widget->parent), + widget, &column_index, &columns, + &resizable); + } + else if (GE_IS_CLIST (widget->parent)) + { + clearlooks_clist_get_header_index (GTK_CLIST(widget->parent), + widget, &column_index, &columns); + } + + header.resizable = resizable; + + if (column_index == 0) + header.order = params.ltr ? CL_ORDER_FIRST : CL_ORDER_LAST; + else if (column_index == columns-1) + header.order = params.ltr ? CL_ORDER_LAST : CL_ORDER_FIRST; + else + header.order = CL_ORDER_MIDDLE; + + gtk_style_apply_default_background (style, window, FALSE, state_type, area, x, y, width, height); + + STYLE_FUNCTION(draw_list_view_header) (cr, colors, ¶ms, &header, + x, y, width, height); + } + else if (DETAIL ("button") || DETAIL ("buttondefault")) + { + WidgetParameters params; + ShadowParameters shadow = { CR_CORNER_ALL, CL_SHADOW_NONE } ; + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + if (ge_is_in_combo_box(widget)) + { + if (params.ltr) + params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + else + params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + + shadow.shadow = CL_SHADOW_IN; + + if (params.xthickness > 2) + { + if (params.ltr) + x--; + width++; + } + } + else + { + params.corners = CR_CORNER_ALL; + /* if (!(ge_is_combo_box (widget, FALSE))) */ + params.enable_glow = TRUE; + } + + if (GE_IS_TOGGLE_BUTTON (widget) && + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) + params.active = TRUE; + + STYLE_FUNCTION(draw_button) (cr, &clearlooks_style->colors, ¶ms, + x, y, width, height); + } + else if (DETAIL ("spinbutton_up") || DETAIL ("spinbutton_down")) + { + if (state_type == GTK_STATE_ACTIVE) + { + WidgetParameters params; + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + if (style->xthickness == 3) + { + width++; + if (params.ltr) + x--; + } + + if (DETAIL ("spinbutton_up")) + { + height+=2; + if (params.ltr) + params.corners = CR_CORNER_TOPRIGHT; + else + params.corners = CR_CORNER_TOPLEFT; + } + else + { + if (params.ltr) + params.corners = CR_CORNER_BOTTOMRIGHT; + else + params.corners = CR_CORNER_BOTTOMLEFT; + } + + STYLE_FUNCTION(draw_spinbutton_down) (cr, &clearlooks_style->colors, ¶ms, x, y, width, height); + } + } + else if (DETAIL ("spinbutton")) + { + WidgetParameters params; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + if (params.ltr) + params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + else + params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + + if (style->xthickness == 3) + { + if (params.ltr) + x--; + width++; + } + + STYLE_FUNCTION(draw_spinbutton) (cr, &clearlooks_style->colors, ¶ms, + x, y, width, height); + } + else if (detail && g_str_has_prefix (detail, "trough") && GE_IS_SCALE (widget)) + { + WidgetParameters params; + SliderParameters slider; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + params.corners = CR_CORNER_NONE; + + slider.lower = DETAIL ("trough-lower"); + slider.fill_level = DETAIL ("trough-fill-level") || DETAIL ("trough-fill-level-full"); + + slider.horizontal = (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL); + + STYLE_FUNCTION(draw_scale_trough) (cr, &clearlooks_style->colors, + ¶ms, &slider, + x, y, width, height); + } + else if (DETAIL ("trough") && widget && GE_IS_PROGRESS_BAR (widget)) + { + WidgetParameters params; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + STYLE_FUNCTION(draw_progressbar_trough) (cr, colors, ¶ms, + x, y, width, height); + } + else if (DETAIL ("trough") && widget && (GE_IS_VSCROLLBAR (widget) || GE_IS_HSCROLLBAR (widget))) + { + WidgetParameters params; + ScrollBarParameters scrollbar; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + params.corners = CR_CORNER_NONE; + + scrollbar.horizontal = TRUE; + scrollbar.junction = clearlooks_scrollbar_get_junction (widget); + + if (GE_IS_RANGE (widget)) + scrollbar.horizontal = GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL; + + if (scrollbar.horizontal) + { + x += 2; + width -= 4; + } + else + { + y += 2; + height -= 4; + } + + STYLE_FUNCTION(draw_scrollbar_trough) (cr, colors, ¶ms, &scrollbar, + x, y, width, height); + } + else if (DETAIL ("bar")) + { + WidgetParameters params; + ProgressBarParameters progressbar; + gdouble elapsed = 0.0; + +#ifdef HAVE_ANIMATION + if(clearlooks_style->animation && CL_IS_PROGRESS_BAR (widget)) + { + gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode; + + if (!activity_mode) + clearlooks_animation_progressbar_add ((gpointer)widget); + } + + elapsed = clearlooks_animation_elapsed (widget); +#endif + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + if (widget && GE_IS_PROGRESS_BAR (widget)) + { + progressbar.orientation = gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (widget)); + progressbar.value = gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(widget)); + progressbar.pulsing = GTK_PROGRESS (widget)->activity_mode; + } + else + { + progressbar.orientation = CL_ORIENTATION_LEFT_TO_RIGHT; + progressbar.value = 0; + progressbar.pulsing = FALSE; + } + + if (!params.ltr) + { + if (progressbar.orientation == GTK_PROGRESS_LEFT_TO_RIGHT) + progressbar.orientation = GTK_PROGRESS_RIGHT_TO_LEFT; + else if (progressbar.orientation == GTK_PROGRESS_RIGHT_TO_LEFT) + progressbar.orientation = GTK_PROGRESS_LEFT_TO_RIGHT; + } + + /* Following is a hack to have a larger clip area, the one passed in + * does not allow for the shadow. */ + if (area) + { + GdkRectangle tmp = *area; + if (!progressbar.pulsing) + { + switch (progressbar.orientation) + { + case GTK_PROGRESS_RIGHT_TO_LEFT: + tmp.x -= 1; + case GTK_PROGRESS_LEFT_TO_RIGHT: + tmp.width += 1; + break; + case GTK_PROGRESS_BOTTOM_TO_TOP: + tmp.y -= 1; + case GTK_PROGRESS_TOP_TO_BOTTOM: + tmp.height += 1; + break; + } + } + else + { + if (progressbar.orientation == GTK_PROGRESS_RIGHT_TO_LEFT || + progressbar.orientation == GTK_PROGRESS_LEFT_TO_RIGHT) + { + tmp.x -= 1; + tmp.width += 2; + } + else + { + tmp.y -= 1; + tmp.height += 2; + } + } + + cairo_reset_clip (cr); + gdk_cairo_rectangle (cr, &tmp); + cairo_clip (cr); + } + + STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, ¶ms, &progressbar, + x, y, width, height, + 10 - (int)(elapsed * 10.0) % 10); + } + else if (DETAIL ("optionmenu")) + { + WidgetParameters params; + OptionMenuParameters optionmenu; + + GtkRequisition indicator_size; + GtkBorder indicator_spacing; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + params.enable_glow = TRUE; + + ge_option_menu_get_props (widget, &indicator_size, &indicator_spacing); + + if (ge_widget_is_ltr (widget)) + optionmenu.linepos = width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - 1; + else + optionmenu.linepos = (indicator_size.width + indicator_spacing.left + indicator_spacing.right) + 1; + + STYLE_FUNCTION(draw_optionmenu) (cr, colors, ¶ms, &optionmenu, + x, y, width, height); + } + else if (DETAIL ("menuitem")) + { + WidgetParameters params; + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + if (widget && GE_IS_MENU_BAR (widget->parent)) + { + params.corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; + height += 1; + STYLE_FUNCTION(draw_menubaritem) (cr, colors, ¶ms, x, y, width, height); + } + else + { + params.corners = CR_CORNER_ALL; + STYLE_FUNCTION(draw_menuitem) (cr, colors, ¶ms, x, y, width, height); + } + } + else if (DETAIL ("hscrollbar") || DETAIL ("vscrollbar")) /* This can't be "stepper" for scrollbars ... */ + { + WidgetParameters params; + ScrollBarParameters scrollbar; + ScrollBarStepperParameters stepper; + GdkRectangle this_rectangle; + + this_rectangle.x = x; + this_rectangle.y = y; + this_rectangle.width = width; + this_rectangle.height = height; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + params.corners = CR_CORNER_NONE; + + scrollbar.has_color = FALSE; + scrollbar.horizontal = TRUE; + scrollbar.junction = clearlooks_scrollbar_get_junction (widget); + + if (clearlooks_style->colorize_scrollbar || clearlooks_style->has_scrollbar_color) { + scrollbar.has_color = TRUE; + } + + scrollbar.horizontal = DETAIL ("hscrollbar"); + + stepper.stepper = clearlooks_scrollbar_get_stepper (widget, &this_rectangle); + + STYLE_FUNCTION(draw_scrollbar_stepper) (cr, colors, ¶ms, &scrollbar, &stepper, + x, y, width, height); + } + else if (DETAIL ("toolbar") || DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin")) + { + WidgetParameters params; + ToolbarParameters toolbar; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + clearlooks_set_toolbar_parameters (&toolbar, widget, window, x, y); + + toolbar.style = clearlooks_style->toolbarstyle; + + /* Only draw the shadows on horizontal toolbars */ + if (shadow_type != GTK_SHADOW_NONE && height < 2*width ) + STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height); + } + else if (DETAIL ("trough")) + { + + } + else if (DETAIL ("menu")) + { + WidgetParameters params; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + STYLE_FUNCTION(draw_menu_frame) (cr, colors, ¶ms, x, y, width, height); + } + else if (DETAIL ("hseparator") || DETAIL ("vseparator")) + { + const gchar *new_detail = detail; + /* Draw a normal separator, we just use this because it gives more control + * over sizing (currently). */ + + /* This isn't nice ... but it seems like the best cleanest way to me right now. + * It will get slightly nicer in the future hopefully. */ + if (GE_IS_MENU_ITEM (widget)) + new_detail = "menuitem"; + + if (DETAIL ("hseparator")) { + gtk_paint_hline (style, window, state_type, area, widget, new_detail, + x, x + width - 1, y + height/2); + } else + gtk_paint_vline (style, window, state_type, area, widget, new_detail, + y, y + height - 1, x + width/2); + } + else + { + clearlooks_parent_class->draw_box (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); + } + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_slider (DRAW_ARGS, GtkOrientation orientation) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + const ClearlooksColors *colors; + cairo_t *cr; + + cr = ge_gdk_drawable_to_cairo (window, area); + colors = &clearlooks_style->colors; + + CHECK_ARGS + SANITIZE_SIZE + + if (DETAIL ("hscale") || DETAIL ("vscale")) + { + WidgetParameters params; + SliderParameters slider; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + slider.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL); + slider.lower = FALSE; + slider.fill_level = FALSE; + + if (clearlooks_style->style == CL_STYLE_GLOSSY) /* XXX! */ + params.corners = CR_CORNER_ALL; + + STYLE_FUNCTION(draw_slider_button) (cr, &clearlooks_style->colors, + ¶ms, &slider, + x, y, width, height); + } + else if (DETAIL ("slider")) + { + WidgetParameters params; + ScrollBarParameters scrollbar; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + params.corners = CR_CORNER_NONE; + + scrollbar.has_color = FALSE; + scrollbar.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL); + scrollbar.junction = clearlooks_scrollbar_get_junction (widget); + + if (clearlooks_style->colorize_scrollbar) { + scrollbar.color = colors->spot[1]; + scrollbar.has_color = TRUE; + } + + /* Set scrollbar color */ + if (clearlooks_style->has_scrollbar_color) + { + ge_gdk_color_to_cairo (&clearlooks_style->scrollbar_color, &scrollbar.color); + scrollbar.has_color = TRUE; + } + + if ((clearlooks_style->style == CL_STYLE_GLOSSY || clearlooks_style->style == CL_STYLE_GUMMY) + && !scrollbar.has_color) + scrollbar.color = colors->bg[0]; + + STYLE_FUNCTION(draw_scrollbar_slider) (cr, colors, ¶ms, &scrollbar, + x, y, width, height); + } + else + { + clearlooks_parent_class->draw_slider (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, orientation); + } + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_option (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + const ClearlooksColors *colors; + WidgetParameters params; + CheckboxParameters checkbox; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + cr = ge_gdk_drawable_to_cairo (window, area); + colors = &clearlooks_style->colors; + + checkbox.shadow_type = shadow_type; + checkbox.in_menu = (widget && GTK_IS_MENU(widget->parent)); + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + STYLE_FUNCTION(draw_radiobutton) (cr, colors, ¶ms, &checkbox, x, y, width, height); + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_check (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + WidgetParameters params; + CheckboxParameters checkbox; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + cr = ge_gdk_drawable_to_cairo (window, area); + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + params.corners = CR_CORNER_ALL; + + checkbox.shadow_type = shadow_type; + checkbox.in_cell = DETAIL("cellcheck"); + + checkbox.in_menu = (widget && widget->parent && GTK_IS_MENU(widget->parent)); + + STYLE_FUNCTION(draw_checkbox) (cr, &clearlooks_style->colors, ¶ms, &checkbox, + x, y, width, height); + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_vline (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint y1, + gint y2, + gint x) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + const ClearlooksColors *colors; + SeparatorParameters separator = { FALSE }; + cairo_t *cr; + + CHECK_ARGS + + colors = &clearlooks_style->colors; + + cr = ge_gdk_drawable_to_cairo (window, area); + + /* There is no such thing as a vertical menu separator + * (and even if, a normal one should be better on menu bars) */ + STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, + x, y1, 2, y2-y1+1); + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_hline (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint x1, + gint x2, + gint y) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + const ClearlooksColors *colors; + cairo_t *cr; + SeparatorParameters separator; + + CHECK_ARGS + + colors = &clearlooks_style->colors; + + cr = ge_gdk_drawable_to_cairo (window, area); + + separator.horizontal = TRUE; + + if (!DETAIL ("menuitem")) + STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, + x1, y, x2-x1+1, 2); + else + STYLE_FUNCTION(draw_menu_item_separator) (cr, colors, NULL, &separator, + x1, y, x2-x1+1, 2); + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_shadow_gap (DRAW_ARGS, + GtkPositionType gap_side, + gint gap_x, + gint gap_width) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + const ClearlooksColors *colors; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + cr = ge_gdk_drawable_to_cairo (window, area); + colors = &clearlooks_style->colors; + + if (DETAIL ("frame")) + { + WidgetParameters params; + FrameParameters frame; + + frame.shadow = shadow_type; + frame.gap_side = gap_side; + frame.gap_x = gap_x; + frame.gap_width = gap_width; + frame.border = &colors->shade[5]; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + params.corners = CR_CORNER_ALL; + + STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, + x, y, width, height); + } + else + { + clearlooks_parent_class->draw_shadow_gap (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, + gap_side, gap_x, gap_width); + } + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_resize_grip (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GdkWindowEdge edge, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + cairo_t *cr; + WidgetParameters params; + ResizeGripParameters grip; + + CHECK_ARGS + SANITIZE_SIZE + + grip.edge = (ClearlooksWindowEdge)edge; + + g_return_if_fail (window != NULL); + + cr = ge_gdk_drawable_to_cairo (window, area); + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + STYLE_FUNCTION(draw_resize_grip) (cr, colors, ¶ms, &grip, + x, y, width, height); + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_tab (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + WidgetParameters params; + ArrowParameters arrow; + cairo_t *cr; + + CHECK_ARGS + SANITIZE_SIZE + + cr = ge_gdk_drawable_to_cairo (window, area); + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + arrow.type = CL_ARROW_COMBO; + arrow.direction = CL_DIRECTION_DOWN; + + STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height); + + cairo_destroy (cr); +} + +static void +clearlooks_style_draw_arrow (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GtkShadowType shadow, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GtkArrowType arrow_type, + gboolean fill, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + WidgetParameters params; + ArrowParameters arrow; + cairo_t *cr = ge_gdk_drawable_to_cairo (window, area); + + CHECK_ARGS + SANITIZE_SIZE + + if (arrow_type == GTK_ARROW_NONE) { + cairo_destroy (cr); + return; + } + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + arrow.type = CL_ARROW_NORMAL; + arrow.direction = (ClearlooksDirection)arrow_type; + + if (ge_is_combo_box (widget, FALSE) && !ge_is_combo_box_entry (widget)) + { + arrow.type = CL_ARROW_COMBO; + } + + /* I have no idea why, but the arrow of GtkCombo is larger than in other places. + * Subtracting 3 seems to fix this. */ + if (widget && widget->parent && GE_IS_COMBO (widget->parent->parent)) + { + if (params.ltr) + x += 1; + else + x += 2; + width -= 3; + } + + STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height); + + cairo_destroy (cr); +} + +static void +clearlooks_style_init_from_rc (GtkStyle * style, + GtkRcStyle * rc_style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + clearlooks_parent_class->init_from_rc (style, rc_style); + + g_assert ((CLEARLOOKS_RC_STYLE (rc_style)->style >= 0) && (CLEARLOOKS_RC_STYLE (rc_style)->style < CL_NUM_STYLES)); + clearlooks_style->style = CLEARLOOKS_RC_STYLE (rc_style)->style; + + clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle; + clearlooks_style->toolbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->toolbarstyle; + clearlooks_style->has_scrollbar_color = CLEARLOOKS_RC_STYLE (rc_style)->flags & CL_FLAG_SCROLLBAR_COLOR; + clearlooks_style->colorize_scrollbar = CLEARLOOKS_RC_STYLE (rc_style)->colorize_scrollbar; + clearlooks_style->animation = CLEARLOOKS_RC_STYLE (rc_style)->animation; + clearlooks_style->radius = CLAMP (CLEARLOOKS_RC_STYLE (rc_style)->radius, 0.0, 10.0); + + if (clearlooks_style->has_scrollbar_color) + clearlooks_style->scrollbar_color = CLEARLOOKS_RC_STYLE (rc_style)->scrollbar_color; +} + +static void +clearlooks_style_realize (GtkStyle * style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + double shades[] = {1.15, 0.95, 0.896, 0.82, 0.7, 0.665, 0.475, 0.45, 0.4}; + CairoColor spot_color; + CairoColor bg_normal; + double contrast; + int i; + + clearlooks_parent_class->realize (style); + + contrast = CLEARLOOKS_RC_STYLE (style->rc_style)->contrast; + + /* Lighter to darker */ + ge_gdk_color_to_cairo (&style->bg[GTK_STATE_NORMAL], &bg_normal); + + for (i = 0; i < 9; i++) + { + ge_shade_color(&bg_normal, (shades[i]-0.7) * contrast + 0.7, &clearlooks_style->colors.shade[i]); + } + + ge_gdk_color_to_cairo (&style->bg[GTK_STATE_SELECTED], &spot_color); + + ge_shade_color(&spot_color, 1.42, &clearlooks_style->colors.spot[0]); + ge_shade_color(&spot_color, 1.05, &clearlooks_style->colors.spot[1]); + ge_shade_color(&spot_color, 0.65, &clearlooks_style->colors.spot[2]); + + for (i=0; i<5; i++) + { + ge_gdk_color_to_cairo (&style->fg[i], &clearlooks_style->colors.fg[i]); + ge_gdk_color_to_cairo (&style->bg[i], &clearlooks_style->colors.bg[i]); + ge_gdk_color_to_cairo (&style->base[i], &clearlooks_style->colors.base[i]); + ge_gdk_color_to_cairo (&style->text[i], &clearlooks_style->colors.text[i]); + } +} + +static void +clearlooks_style_draw_focus (GtkStyle *style, GdkWindow *window, GtkStateType state_type, + GdkRectangle *area, GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + cairo_t *cr; + gboolean free_dash_list = FALSE; + gint line_width = 1; + gint8 *dash_list = (gint8 *)"\1\1"; + + if (widget) + { + gtk_widget_style_get (widget, + "focus-line-width", &line_width, + "focus-line-pattern", + (gchar *) & dash_list, NULL); + + free_dash_list = TRUE; + } + + if (detail && !strcmp (detail, "add-mode")) + { + if (free_dash_list) + g_free (dash_list); + + dash_list = (gint8 *)"\4\4"; + free_dash_list = FALSE; + } + + CHECK_ARGS + SANITIZE_SIZE + + cr = gdk_cairo_create (window); + + if (detail && !strcmp (detail, "colorwheel_light")) + cairo_set_source_rgb (cr, 0., 0., 0.); + else if (detail && !strcmp (detail, "colorwheel_dark")) + cairo_set_source_rgb (cr, 1., 1., 1.); + else + ge_cairo_set_gdk_color_with_alpha (cr, &style->fg[state_type], + 0.7); + + cairo_set_line_width (cr, line_width); + + if (dash_list[0]) + { + gint n_dashes = strlen ((gchar *)dash_list); + gdouble *dashes = g_new (gdouble, n_dashes); + gdouble total_length = 0; + gdouble dash_offset; + gint i; + + for (i = 0; i < n_dashes; i++) + { + dashes[i] = dash_list[i]; + total_length += dash_list[i]; + } + + /* The dash offset here aligns the pattern to integer pixels + * by starting the dash at the right side of the left border + * Negative dash offsets in cairo don't work + * (https://bugs.freedesktop.org/show_bug.cgi?id=2729) + */ + dash_offset = -line_width / 2.; + while (dash_offset < 0) + dash_offset += total_length; + + cairo_set_dash (cr, dashes, n_dashes, dash_offset); + g_free (dashes); + } + + if (area) + { + gdk_cairo_rectangle (cr, area); + cairo_clip (cr); + } + + cairo_rectangle (cr, + x + line_width / 2., + y + line_width / 2., + width - line_width, height - line_width); + cairo_stroke (cr); + cairo_destroy (cr); + + if (free_dash_list) + g_free (dash_list); +} + +static void +clearlooks_style_copy (GtkStyle * style, GtkStyle * src) +{ + ClearlooksStyle * cl_style = CLEARLOOKS_STYLE (style); + ClearlooksStyle * cl_src = CLEARLOOKS_STYLE (src); + + cl_style->colors = cl_src->colors; + cl_style->menubarstyle = cl_src->menubarstyle; + cl_style->toolbarstyle = cl_src->toolbarstyle; + cl_style->scrollbar_color = cl_src->scrollbar_color; + cl_style->has_scrollbar_color = cl_src->has_scrollbar_color; + cl_style->colorize_scrollbar = cl_src->colorize_scrollbar; + cl_style->animation = cl_src->animation; + cl_style->radius = cl_src->radius; + cl_style->style = cl_src->style; + + clearlooks_parent_class->copy (style, src); +} + +static void +clearlooks_style_unrealize (GtkStyle * style) +{ + clearlooks_parent_class->unrealize (style); +} + +static GdkPixbuf * +set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent) +{ + GdkPixbuf *target; + guchar *data, *current; + guint x, y, rowstride, height, width; + + g_return_val_if_fail (pixbuf != NULL, NULL); + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + /* Returns a copy of pixbuf with it's non-completely-transparent pixels to + have an alpha level "alpha_percent" of their original value. */ + + target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); + + if (alpha_percent == 1.0) + return target; + width = gdk_pixbuf_get_width (target); + height = gdk_pixbuf_get_height (target); + rowstride = gdk_pixbuf_get_rowstride (target); + data = gdk_pixbuf_get_pixels (target); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + /* The "4" is the number of chars per pixel, in this case, RGBA, + the 3 means "skip to the alpha" */ + current = data + (y * rowstride) + (x * 4) + 3; + *(current) = (guchar) (*(current) * alpha_percent); + } + } + + return target; +} + +static GdkPixbuf* +scale_or_ref (GdkPixbuf *src, + int width, + int height) +{ + if (width == gdk_pixbuf_get_width (src) && + height == gdk_pixbuf_get_height (src)) { + return g_object_ref (src); + } else { + return gdk_pixbuf_scale_simple (src, + width, height, + GDK_INTERP_BILINEAR); + } +} + +static void +clearlooks_style_draw_layout (GtkStyle * style, + GdkWindow * window, + GtkStateType state_type, + gboolean use_text, + GdkRectangle * area, + GtkWidget * widget, + const gchar * detail, gint x, gint y, PangoLayout * layout) +{ + GdkGC *gc; + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type]; + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + if (state_type == GTK_STATE_INSENSITIVE) { + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksColors *colors = &clearlooks_style->colors; + + WidgetParameters params; + GdkColor etched; + CairoColor temp; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + if (GTK_WIDGET_NO_WINDOW (widget)) + ge_shade_color (¶ms.parentbg, 1.2, &temp); + else + ge_shade_color (&colors->bg[widget->state], 1.2, &temp); + + etched.red = (int) (temp.r * 65535); + etched.green = (int) (temp.g * 65535); + etched.blue = (int) (temp.b * 65535); + + gdk_draw_layout_with_colors (window, gc, x + 1, y + 1, layout, &etched, NULL); + gdk_draw_layout (window, gc, x, y, layout); + } + else + gdk_draw_layout (window, gc, x, y, layout); + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); +} + +static GdkPixbuf * +clearlooks_style_draw_render_icon (GtkStyle *style, + const GtkIconSource *source, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const char *detail) +{ + int width = 1; + int height = 1; + GdkPixbuf *scaled; + GdkPixbuf *stated; + GdkPixbuf *base_pixbuf; + GdkScreen *screen; + GtkSettings *settings; + + /* Oddly, style can be NULL in this function, because + * GtkIconSet can be used without a style and if so + * it uses this function. + */ + + base_pixbuf = gtk_icon_source_get_pixbuf (source); + + g_return_val_if_fail (base_pixbuf != NULL, NULL); + + if (widget && gtk_widget_has_screen (widget)) { + screen = gtk_widget_get_screen (widget); + settings = gtk_settings_get_for_screen (screen); + } else if (style->colormap) { + screen = gdk_colormap_get_screen (style->colormap); + settings = gtk_settings_get_for_screen (screen); + } else { + settings = gtk_settings_get_default (); + GTK_NOTE (MULTIHEAD, + g_warning ("Using the default screen for gtk_default_render_icon()")); + } + + + if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) { + g_warning (G_STRLOC ": invalid icon size '%d'", size); + return NULL; + } + + /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise, + * leave it alone. + */ + if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source)) + scaled = scale_or_ref (base_pixbuf, width, height); + else + scaled = g_object_ref (base_pixbuf); + + /* If the state was wildcarded, then generate a state. */ + if (gtk_icon_source_get_state_wildcarded (source)) { + if (state == GTK_STATE_INSENSITIVE) { + stated = set_transparency (scaled, 0.3); + gdk_pixbuf_saturate_and_pixelate (stated, stated, + 0.1, FALSE); + + g_object_unref (scaled); + } else if (state == GTK_STATE_PRELIGHT) { + stated = gdk_pixbuf_copy (scaled); + + gdk_pixbuf_saturate_and_pixelate (scaled, stated, + 1.2, FALSE); + + g_object_unref (scaled); + } else { + stated = scaled; + } + } + else + stated = scaled; + + return stated; +} + +static void +clearlooks_style_init (ClearlooksStyle * style) +{ +} + +static void +clearlooks_style_class_init (ClearlooksStyleClass * klass) +{ + GtkStyleClass *style_class = GTK_STYLE_CLASS (klass); + + clearlooks_style_class = CLEARLOOKS_STYLE_CLASS (klass); + clearlooks_parent_class = g_type_class_peek_parent (klass); + + style_class->copy = clearlooks_style_copy; + style_class->realize = clearlooks_style_realize; + style_class->unrealize = clearlooks_style_unrealize; + style_class->init_from_rc = clearlooks_style_init_from_rc; + style_class->draw_handle = clearlooks_style_draw_handle; + style_class->draw_slider = clearlooks_style_draw_slider; + style_class->draw_shadow_gap = clearlooks_style_draw_shadow_gap; + style_class->draw_focus = clearlooks_style_draw_focus; + style_class->draw_box = clearlooks_style_draw_box; + style_class->draw_shadow = clearlooks_style_draw_shadow; + style_class->draw_box_gap = clearlooks_style_draw_box_gap; + style_class->draw_extension = clearlooks_style_draw_extension; + style_class->draw_option = clearlooks_style_draw_option; + style_class->draw_check = clearlooks_style_draw_check; + style_class->draw_flat_box = clearlooks_style_draw_flat_box; + style_class->draw_vline = clearlooks_style_draw_vline; + style_class->draw_hline = clearlooks_style_draw_hline; + style_class->draw_resize_grip = clearlooks_style_draw_resize_grip; + style_class->draw_tab = clearlooks_style_draw_tab; + style_class->draw_arrow = clearlooks_style_draw_arrow; + style_class->draw_layout = clearlooks_style_draw_layout; + style_class->render_icon = clearlooks_style_draw_render_icon; + + clearlooks_register_style_classic (&clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]); + clearlooks_style_class->style_functions[CL_STYLE_GLOSSY] = clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]; + clearlooks_register_style_glossy (&clearlooks_style_class->style_functions[CL_STYLE_GLOSSY]); + clearlooks_style_class->style_functions[CL_STYLE_INVERTED] = clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]; + clearlooks_register_style_inverted (&clearlooks_style_class->style_functions[CL_STYLE_INVERTED]); + clearlooks_style_class->style_functions[CL_STYLE_GUMMY] = clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]; + clearlooks_register_style_gummy (&clearlooks_style_class->style_functions[CL_STYLE_GUMMY]); +} + +GType clearlooks_type_style = 0; + +void +clearlooks_style_register_type (GTypeModule * module) +{ + static const GTypeInfo object_info = + { + sizeof (ClearlooksStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_style_init, + NULL + }; + + clearlooks_type_style = g_type_module_register_type (module, + GTK_TYPE_STYLE, + "ClearlooksStyle", + &object_info, 0); +} diff --git a/libs/clearlooks-newer/clearlooks_style.h b/libs/clearlooks-newer/clearlooks_style.h new file mode 100644 index 0000000000..78f3ca1675 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_style.h @@ -0,0 +1,70 @@ +/* Clearlooks Engine + * Copyright (C) 2005 Richard Stellingwerff. + * Copyright (C) 2006 Benjamin Berg + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor <otaylor@redhat.com> + * and by Alexander Larsson <alexl@redhat.com> + * Modified by Richard Stellingwerff <remenic@gmail.com> + */ +#include <gtk/gtkstyle.h> + +#ifndef CLEARLOOKS_STYLE_H +#define CLEARLOOKS_STYLE_H + +#include "animation.h" +#include "clearlooks_types.h" + +typedef struct _ClearlooksStyle ClearlooksStyle; +typedef struct _ClearlooksStyleClass ClearlooksStyleClass; + +GE_INTERNAL extern GType clearlooks_type_style; + +#define CLEARLOOKS_TYPE_STYLE clearlooks_type_style +#define CLEARLOOKS_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_STYLE, ClearlooksStyle)) +#define CLEARLOOKS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_STYLE, ClearlooksStyleClass)) +#define CLEARLOOKS_IS_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_STYLE)) +#define CLEARLOOKS_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLEARLOOKS_TYPE_STYLE)) +#define CLEARLOOKS_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLEARLOOKS_TYPE_STYLE, ClearlooksStyleClass)) + +struct _ClearlooksStyle +{ + GtkStyle parent_instance; + + ClearlooksColors colors; + + ClearlooksStyles style; + + guint8 menubarstyle; + guint8 toolbarstyle; + GdkColor scrollbar_color; + gboolean colorize_scrollbar; + gboolean has_scrollbar_color; + gboolean animation; + gfloat radius; +}; + +struct _ClearlooksStyleClass +{ + GtkStyleClass parent_class; + + ClearlooksStyleFunctions style_functions[CL_NUM_STYLES]; +}; + +GE_INTERNAL void clearlooks_style_register_type (GTypeModule *module); + +#endif /* CLEARLOOKS_STYLE_H */ diff --git a/libs/clearlooks-newer/clearlooks_theme_main.c b/libs/clearlooks-newer/clearlooks_theme_main.c new file mode 100644 index 0000000000..c042fdbac0 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_theme_main.c @@ -0,0 +1,23 @@ +#include <gmodule.h> +#include <gtk/gtk.h> + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" + +GE_EXPORT void +theme_init (GTypeModule *module) +{ + clearlooks_rc_style_register_type (module); + clearlooks_style_register_type (module); +} + +GE_EXPORT void +theme_exit (void) +{ +} + +GE_EXPORT GtkRcStyle * +theme_create_rc_style (void) +{ + return GTK_RC_STYLE (g_object_new (CLEARLOOKS_TYPE_RC_STYLE, NULL)); +} diff --git a/libs/clearlooks-newer/clearlooks_types.h b/libs/clearlooks-newer/clearlooks_types.h new file mode 100644 index 0000000000..7caf8a3208 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_types.h @@ -0,0 +1,455 @@ +#ifndef CLEARLOOKS_TYPES_H +#define CLEARLOOKS_TYPES_H + +#include <ge-support.h> + +typedef unsigned char boolean; +typedef unsigned char uint8; +typedef struct _ClearlooksStyleFunctions ClearlooksStyleFunctions; + +typedef enum +{ + CL_STYLE_CLASSIC = 0, + CL_STYLE_GLOSSY = 1, + CL_STYLE_INVERTED = 2, + CL_STYLE_GUMMY = 3, + CL_NUM_STYLES = 4 +} ClearlooksStyles; + + +typedef enum +{ + CL_STATE_NORMAL, + CL_STATE_ACTIVE, + CL_STATE_SELECTED, + CL_STATE_INSENSITIVE +} ClearlooksStateType; + +typedef enum +{ + CL_JUNCTION_NONE = 0, + CL_JUNCTION_BEGIN = 1, + CL_JUNCTION_END = 2 +} ClearlooksJunction; + +typedef enum +{ + CL_STEPPER_UNKNOWN = 0, + CL_STEPPER_A = 1, + CL_STEPPER_B = 2, + CL_STEPPER_C = 4, + CL_STEPPER_D = 8 +} ClearlooksStepper; + +typedef enum +{ + CL_ORDER_FIRST, + CL_ORDER_MIDDLE, + CL_ORDER_LAST +} ClearlooksOrder; + +typedef enum +{ + CL_ORIENTATION_LEFT_TO_RIGHT, + CL_ORIENTATION_RIGHT_TO_LEFT, + CL_ORIENTATION_BOTTOM_TO_TOP, + CL_ORIENTATION_TOP_TO_BOTTOM +} ClearlooksOrientation; + +typedef enum +{ + CL_GAP_LEFT, + CL_GAP_RIGHT, + CL_GAP_TOP, + CL_GAP_BOTTOM +} ClearlooksGapSide; + +typedef enum +{ + CL_SHADOW_NONE, + CL_SHADOW_IN, + CL_SHADOW_OUT, + CL_SHADOW_ETCHED_IN, + CL_SHADOW_ETCHED_OUT +} ClearlooksShadowType; + +typedef enum +{ + CL_HANDLE_TOOLBAR, + CL_HANDLE_SPLITTER +} ClearlooksHandleType; + +typedef enum +{ + CL_ARROW_NORMAL, + CL_ARROW_COMBO +} ClearlooksArrowType; + +typedef enum +{ + CL_DIRECTION_UP, + CL_DIRECTION_DOWN, + CL_DIRECTION_LEFT, + CL_DIRECTION_RIGHT +} ClearlooksDirection; + +typedef enum +{ + CL_PROGRESSBAR_CONTINUOUS, + CL_PROGRESSBAR_DISCRETE +} ClearlooksProgressBarStyle; + +typedef enum +{ + CL_WINDOW_EDGE_NORTH_WEST, + CL_WINDOW_EDGE_NORTH, + CL_WINDOW_EDGE_NORTH_EAST, + CL_WINDOW_EDGE_WEST, + CL_WINDOW_EDGE_EAST, + CL_WINDOW_EDGE_SOUTH_WEST, + CL_WINDOW_EDGE_SOUTH, + CL_WINDOW_EDGE_SOUTH_EAST +} ClearlooksWindowEdge; + +typedef struct +{ + double x; + double y; + double width; + double height; +} ClearlooksRectangle; + +typedef struct +{ + CairoColor fg[5]; + CairoColor bg[5]; + CairoColor base[5]; + CairoColor text[5]; + + CairoColor shade[9]; + CairoColor spot[3]; +} ClearlooksColors; + +typedef struct +{ + boolean active; + boolean prelight; + boolean disabled; + boolean focus; + boolean is_default; + boolean ltr; + boolean enable_glow; + + gfloat radius; + + ClearlooksStateType state_type; + + uint8 corners; + uint8 xthickness; + uint8 ythickness; + + CairoColor parentbg; + + ClearlooksStyleFunctions *style_functions; +} WidgetParameters; + +typedef struct +{ + boolean lower; + boolean horizontal; + boolean fill_level; +} SliderParameters; + +typedef struct +{ + ClearlooksOrientation orientation; + boolean pulsing; + float value; +} ProgressBarParameters; + +typedef struct +{ + int linepos; +} OptionMenuParameters; + +typedef struct +{ + ClearlooksShadowType shadow; + ClearlooksGapSide gap_side; + int gap_x; + int gap_width; + const CairoColor *border; /* maybe changes this to some other hint ... */ +} FrameParameters; + +typedef struct +{ + ClearlooksGapSide gap_side; +} TabParameters; + +typedef struct +{ + CairoCorners corners; + ClearlooksShadowType shadow; +} ShadowParameters; + +typedef struct +{ + boolean horizontal; +} SeparatorParameters; + +typedef struct +{ + ClearlooksOrder order; /* XXX: rename to position */ + boolean resizable; +} ListViewHeaderParameters; + +typedef struct +{ + CairoColor color; + ClearlooksJunction junction; /* On which sides the slider junctions */ + boolean horizontal; + boolean has_color; +} ScrollBarParameters; + +typedef struct +{ + ClearlooksHandleType type; + boolean horizontal; +} HandleParameters; + +typedef struct +{ + ClearlooksStepper stepper; /* Which stepper to draw */ +} ScrollBarStepperParameters; + +typedef struct +{ + ClearlooksWindowEdge edge; +} ResizeGripParameters; + +typedef struct +{ + int style; +} MenuBarParameters; + +typedef struct +{ + ClearlooksShadowType shadow_type; + boolean in_cell; + boolean in_menu; +} CheckboxParameters; + +typedef struct +{ + ClearlooksArrowType type; + ClearlooksDirection direction; +} ArrowParameters; + +typedef struct +{ + int style; + boolean topmost; +} ToolbarParameters; + +struct _ClearlooksStyleFunctions +{ + void (*draw_button) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_scale_trough) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SliderParameters *slider, + int x, int y, int width, int height); + + void (*draw_progressbar_trough) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_progressbar_fill) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ProgressBarParameters *progressbar, + int x, int y, int width, int height, gint offset); + + void (*draw_slider_button) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SliderParameters *slider, + int x, int y, int width, int height); + + void (*draw_entry) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_spinbutton) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_spinbutton_down) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_optionmenu) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const OptionMenuParameters *optionmenu, + int x, int y, int width, int height); + + void (*draw_inset) (cairo_t *cr, + const CairoColor *bg_color, + double x, double y, double w, double h, + double radius, uint8 corners); + + void (*draw_menubar) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const MenuBarParameters *menubar, + int x, int y, int width, int height); + + void (*draw_tab) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const TabParameters *tab, + int x, int y, int width, int height); + + void (*draw_frame) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const FrameParameters *frame, + int x, int y, int width, int height); + + void (*draw_separator) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SeparatorParameters *separator, + int x, int y, int width, int height); + + void (*draw_menu_item_separator) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SeparatorParameters *separator, + int x, int y, int width, int height); + + void (*draw_list_view_header) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ListViewHeaderParameters *header, + int x, int y, int width, int height); + + void (*draw_toolbar) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ToolbarParameters *toolbar, + int x, int y, int width, int height); + + void (*draw_menuitem) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_menubaritem) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_selected_cell) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_scrollbar_stepper) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + const ScrollBarStepperParameters *stepper, + int x, int y, int width, int height); + + void (*draw_scrollbar_slider) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height); + + void (*draw_scrollbar_trough) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height); + + void (*draw_statusbar) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_menu_frame) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_tooltip) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_handle) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const HandleParameters *handle, + int x, int y, int width, int height); + + void (*draw_resize_grip) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ResizeGripParameters *grip, + int x, int y, int width, int height); + + void (*draw_arrow) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ArrowParameters *arrow, + int x, int y, int width, int height); + + void (*draw_checkbox) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height); + + void (*draw_radiobutton) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height); + + /* Style internal functions */ + /* XXX: Only used by slider_button, inline it? */ + void (*draw_shadow) (cairo_t *cr, + const ClearlooksColors *colors, + gfloat radius, + int width, int height); + + void (*draw_slider) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_gripdots) (cairo_t *cr, + const ClearlooksColors *colors, int x, int y, + int width, int height, int xr, int yr, + float contrast); +}; + + +#define CLEARLOOKS_RECTANGLE_SET(rect, _x, _y, _w, _h) rect.x = _x; \ + rect.y = _y; \ + rect.width = _w; \ + rect.height = _h; + +#endif /* CLEARLOOKS_TYPES_H */ diff --git a/libs/clearlooks-newer/config.h b/libs/clearlooks-newer/config.h new file mode 100644 index 0000000000..4326e37ec1 --- /dev/null +++ b/libs/clearlooks-newer/config.h @@ -0,0 +1,80 @@ +/* engines/clearlooks/src/config.h. Generated from config.h.in by configure. */ +/* engines/clearlooks/src/config.h.in. Generated from configure.ac by autoheader. */ + +/* always defined to indicate that i18n is enabled */ +#define ENABLE_NLS 1 + +/* Gettext package */ +#define GETTEXT_PACKAGE "gtk-engines" + +/* Defines whether to compile with animation support */ +#define HAVE_ANIMATION 1 + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +#define HAVE_BIND_TEXTDOMAIN_CODESET 1 + +/* Define to 1 if you have the `dcgettext' function. */ +#define HAVE_DCGETTEXT 1 + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#define HAVE_GETTEXT 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if your <locale.h> file defines LC_MESSAGES. */ +#define HAVE_LC_MESSAGES 1 + +/* Define to 1 if you have the <locale.h> header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "gtk-engines" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "gtk-engines" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "gtk-engines 2.12.2" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "gtk-engines" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.12.2" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "2.12.2" diff --git a/libs/clearlooks-newer/cpdll.sh b/libs/clearlooks-newer/cpdll.sh new file mode 100755 index 0000000000..fb101d52a0 --- /dev/null +++ b/libs/clearlooks-newer/cpdll.sh @@ -0,0 +1,2 @@ +mkdir engines +cp libclearlooks.so engines diff --git a/libs/clearlooks-newer/ge-support.h b/libs/clearlooks-newer/ge-support.h new file mode 100644 index 0000000000..e0a42b6c3d --- /dev/null +++ b/libs/clearlooks-newer/ge-support.h @@ -0,0 +1,9 @@ +#ifndef GE_SUPPORT_H +#define GE_SUPPORT_H + +#include "general-support.h" +#include "cairo-support.h" +#include "widget-information.h" + + +#endif /* GE_SUPPORT_H */ diff --git a/libs/clearlooks-newer/general-support.h b/libs/clearlooks-newer/general-support.h new file mode 100644 index 0000000000..25999e2d31 --- /dev/null +++ b/libs/clearlooks-newer/general-support.h @@ -0,0 +1,39 @@ + +#include <gmodule.h> +#include <glib.h> + +/* macros to make sure that things are sane ... */ + +#define CHECK_DETAIL(detail, value) ((detail) && (!strcmp(value, detail))) + +#define CHECK_ARGS \ + g_return_if_fail (window != NULL); \ + g_return_if_fail (style != NULL); + +#define SANITIZE_SIZE \ + g_return_if_fail (width >= -1); \ + g_return_if_fail (height >= -1); \ + \ + if ((width == -1) && (height == -1)) \ + gdk_drawable_get_size (window, &width, &height); \ + else if (width == -1) \ + gdk_drawable_get_size (window, &width, NULL); \ + else if (height == -1) \ + gdk_drawable_get_size (window, NULL, &height); + +#define GE_EXPORT G_MODULE_EXPORT +#define GE_INTERNAL G_GNUC_INTERNAL + +/* explicitly export with ggc, G_MODULE_EXPORT does not do this, this should + * make it possible to compile with -fvisibility=hidden */ +#ifdef G_HAVE_GNUC_VISIBILITY +# undef GE_EXPORT +# define GE_EXPORT __attribute__((__visibility__("default"))) +#endif + +#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) +# undef GE_EXPORT +# undef GE_INTERNAL +# define GE_EXPORT __global +# define GE_INTERNAL __hidden +#endif diff --git a/libs/clearlooks-newer/support.c b/libs/clearlooks-newer/support.c new file mode 100644 index 0000000000..6d4d8a286d --- /dev/null +++ b/libs/clearlooks-newer/support.c @@ -0,0 +1,287 @@ +/* Clearlooks theme engine + * Copyright (C) 2005 Richard Stellingwerff. + * Copyright (C) 2007 Benjamin Berg <benjamin@sipsolutions.net>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "support.h" + +void clearlooks_treeview_get_header_index (GtkTreeView *tv, GtkWidget *header, + gint *column_index, gint *columns, + gboolean *resizable) +{ + GList *list, *list_start; + *column_index = *columns = 0; + list_start = list = gtk_tree_view_get_columns (tv); + + do + { + GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(list->data); + if ( column->button == header ) + { + *column_index = *columns; + *resizable = column->resizable; + } + if ( column->visible ) + (*columns)++; + } while ((list = g_list_next(list))); + + g_list_free (list_start); +} + +void clearlooks_clist_get_header_index (GtkCList *clist, GtkWidget *button, + gint *column_index, gint *columns) +{ + int i; + *columns = clist->columns; + + for (i=0; i<*columns; i++) + { + if (clist->column[i].button == button) + { + *column_index = i; + break; + } + } +} + +void +clearlooks_get_parent_bg (const GtkWidget *widget, CairoColor *color) +{ + GtkStateType state_type; + const GtkWidget *parent; + GdkColor *gcolor; + + if (widget == NULL) + return; + + parent = widget->parent; + + while (parent && GTK_WIDGET_NO_WINDOW (parent) && !((GTK_IS_NOTEBOOK (parent)) || (GTK_IS_TOOLBAR (parent)))) + parent = parent->parent; + + if (parent == NULL) + return; + + state_type = GTK_WIDGET_STATE (parent); + + gcolor = &parent->style->bg[state_type]; + + ge_gdk_color_to_cairo (gcolor, color); +} + +ClearlooksStepper +clearlooks_scrollbar_get_stepper (GtkWidget *widget, + GdkRectangle *stepper) +{ + ClearlooksStepper value = CL_STEPPER_UNKNOWN; + GdkRectangle tmp; + GdkRectangle check_rectangle; + GtkOrientation orientation; + + if (!GE_IS_RANGE (widget)) + return CL_STEPPER_UNKNOWN; + + check_rectangle.x = widget->allocation.x; + check_rectangle.y = widget->allocation.y; + check_rectangle.width = stepper->width; + check_rectangle.height = stepper->height; + + orientation = GTK_RANGE (widget)->orientation; + + if (widget->allocation.x == -1 && widget->allocation.y == -1) + return CL_STEPPER_UNKNOWN; + + if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp)) + value = CL_STEPPER_A; + + if (value == CL_STEPPER_UNKNOWN) /* Haven't found a match */ + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + check_rectangle.x = widget->allocation.x + stepper->width; + else + check_rectangle.y = widget->allocation.y + stepper->height; + + if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp)) + value = CL_STEPPER_B; + } + + if (value == CL_STEPPER_UNKNOWN) /* Still haven't found a match */ + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + check_rectangle.x = widget->allocation.x + widget->allocation.width - (stepper->width * 2); + else + check_rectangle.y = widget->allocation.y + widget->allocation.height - (stepper->height * 2); + + if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp)) + value = CL_STEPPER_C; + } + + if (value == CL_STEPPER_UNKNOWN) /* STILL haven't found a match */ + { + if (orientation == GTK_ORIENTATION_HORIZONTAL) + check_rectangle.x = widget->allocation.x + widget->allocation.width - stepper->width; + else + check_rectangle.y = widget->allocation.y + widget->allocation.height - stepper->height; + + if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp)) + value = CL_STEPPER_D; + } + + return value; +} + +ClearlooksStepper +clearlooks_scrollbar_visible_steppers (GtkWidget *widget) +{ + ClearlooksStepper steppers = 0; + + if (!GE_IS_RANGE (widget)) + return 0; + + if (GTK_RANGE (widget)->has_stepper_a) + steppers |= CL_STEPPER_A; + + if (GTK_RANGE (widget)->has_stepper_b) + steppers |= CL_STEPPER_B; + + if (GTK_RANGE (widget)->has_stepper_c) + steppers |= CL_STEPPER_C; + + if (GTK_RANGE (widget)->has_stepper_d) + steppers |= CL_STEPPER_D; + + return steppers; +} + +ClearlooksJunction +clearlooks_scrollbar_get_junction (GtkWidget *widget) +{ + GtkAdjustment *adj; + ClearlooksJunction junction = CL_JUNCTION_NONE; + + if (!GE_IS_RANGE (widget)) + return CL_JUNCTION_NONE; + + adj = GTK_RANGE (widget)->adjustment; + + if (adj->value <= adj->lower && + (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b)) + { + junction |= CL_JUNCTION_BEGIN; + } + + if (adj->value >= adj->upper - adj->page_size && + (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d)) + { + junction |= CL_JUNCTION_END; + } + + return junction; +} + +void +clearlooks_set_toolbar_parameters (ToolbarParameters *toolbar, GtkWidget *widget, GdkWindow *window, gint x, gint y) +{ + toolbar->topmost = FALSE; + + if (x == 0 && y == 0) { + if (widget && widget->allocation.x == 0 && widget->allocation.y == 0) + { + if (widget->window == window && GE_IS_TOOLBAR (widget)) + { + toolbar->topmost = TRUE; + } + } + } +} + +void +clearlooks_get_notebook_tab_position (GtkWidget *widget, + gboolean *start, + gboolean *end) +{ + /* default value */ + *start = TRUE; + *end = FALSE; + + if (GE_IS_NOTEBOOK (widget)) { + gboolean found_tabs = FALSE; + gint i, n_pages; + GtkNotebook *notebook = GTK_NOTEBOOK (widget); + + /* got a notebook, so walk over all the tabs and decide based + * on that ... + * It works like this: + * - If there is any visible tab that is expanded, set both. + * - Set start/end if there is any visible tab that is at + * the start/end. + * - If one has the child_visibility set to false, arrows + * are present; so none + * The heuristic falls over if there is a notebook that just + * happens to fill up all the available space. ie. All tabs + * are left aligned, but it does not require scrolling. + * (a more complex heuristic could calculate the tabs width + * and add them all up) */ + + n_pages = gtk_notebook_get_n_pages (notebook); + for (i = 0; i < n_pages; i++) { + GtkWidget *tab_child; + GtkWidget *tab_label; + gboolean expand; + GtkPackType pack_type; + + tab_child = gtk_notebook_get_nth_page (notebook, i); + + /* Skip invisible tabs */ + tab_label = gtk_notebook_get_tab_label (notebook, tab_child); + if (!tab_label || !GTK_WIDGET_VISIBLE (tab_label)) + continue; + /* This is the same what the notebook does internally. */ + if (tab_label && !gtk_widget_get_child_visible (tab_label)) { + /* One child is hidden because scroll arrows are present. + * So both corners are rounded. */ + *start = FALSE; + *end = FALSE; + return; + } + + gtk_notebook_query_tab_label_packing (notebook, tab_child, + &expand, + NULL, /* don't need fill */ + &pack_type); + + if (!found_tabs) { + found_tabs = TRUE; + *start = FALSE; + *end = FALSE; + } + + if (expand) { + *start = TRUE; + *end = TRUE; + } else if (pack_type == GTK_PACK_START) { + *start = TRUE; + } else { + *end = TRUE; + } + } + } +} + + diff --git a/libs/clearlooks-newer/support.h b/libs/clearlooks-newer/support.h new file mode 100644 index 0000000000..23e33c58e7 --- /dev/null +++ b/libs/clearlooks-newer/support.h @@ -0,0 +1,38 @@ +#ifndef SUPPORT_H +#define SUPPORT_H + +#include <gtk/gtk.h> +#include <math.h> +#include <string.h> + +#include "clearlooks_types.h" + +#define RADIO_SIZE 13 +#define CHECK_SIZE 13 + +GE_INTERNAL void clearlooks_treeview_get_header_index (GtkTreeView *tv, + GtkWidget *header, + gint *column_index, + gint *columns, + gboolean *resizable); + +GE_INTERNAL void clearlooks_clist_get_header_index (GtkCList *clist, + GtkWidget *button, + gint *column_index, + gint *columns); +#ifdef DEVELOPMENT +#warning clearlooks_get_parent_bg is a bad hack - find out why its needed, and figure out a better way. +#endif + +GE_INTERNAL void clearlooks_get_parent_bg (const GtkWidget *widget, + CairoColor *color); + +GE_INTERNAL ClearlooksStepper clearlooks_scrollbar_get_stepper (GtkWidget *widget, + GdkRectangle *stepper); +GE_INTERNAL ClearlooksStepper clearlooks_scrollbar_visible_steppers (GtkWidget *widget); +GE_INTERNAL ClearlooksJunction clearlooks_scrollbar_get_junction (GtkWidget *widget); + +GE_INTERNAL void clearlooks_set_toolbar_parameters (ToolbarParameters *toolbar, GtkWidget *widget, GdkWindow *window, gint x, gint y); +GE_INTERNAL void clearlooks_get_notebook_tab_position (GtkWidget *widget, gboolean *start, gboolean *end); + +#endif /* SUPPORT_H */ diff --git a/libs/clearlooks-newer/support.h.orig b/libs/clearlooks-newer/support.h.orig new file mode 100644 index 0000000000..a1430b40d0 --- /dev/null +++ b/libs/clearlooks-newer/support.h.orig @@ -0,0 +1,110 @@ +#include <gtk/gtk.h> +#include <math.h> +#include <string.h> + +/* GTK 2.2 compatibility */ +#ifndef GTK_IS_COMBO_BOX_ENTRY + #define GTK_IS_COMBO_BOX_ENTRY(x) 0 +#endif +#ifndef GTK_IS_COMBO_BOX + #define GTK_IS_COMBO_BOX(x) 0 +#endif + +#define RADIO_SIZE 13 +#define CHECK_SIZE 13 + +GtkTextDirection +get_direction (GtkWidget *widget); + +GdkPixbuf * +generate_bit (unsigned char alpha[], + GdkColor *color, + double mult); + +GdkPixbuf * +colorize_bit (unsigned char *bit, + unsigned char *alpha, + GdkColor *new_color); + +GdkPixmap * +pixbuf_to_pixmap (GtkStyle *style, + GdkPixbuf *pixbuf, + GdkScreen *screen); + +gboolean +sanitize_size (GdkWindow *window, + gint *width, + gint *height); + +void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b); + +void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s); + +void +shade (GdkColor * a, GdkColor * b, float k); + +void +draw_hgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *top_color, GdkColor *bottom_color); + +void +draw_vgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *left_color, GdkColor *right_color); + +void +arrow_draw_hline (GdkWindow *window, + GdkGC *gc, + int x1, + int x2, + int y, + gboolean last); + +void +arrow_draw_vline (GdkWindow *window, + GdkGC *gc, + int y1, + int y2, + int x, + gboolean last); + +void +draw_arrow (GdkWindow *window, + GdkGC *gc, + GdkRectangle *area, + GtkArrowType arrow_type, + gint x, + gint y, + gint width, + gint height); + +void +calculate_arrow_geometry (GtkArrowType arrow_type, + gint *x, + gint *y, + gint *width, + gint *height); + +GtkWidget *special_get_ancestor(GtkWidget * widget, + GType widget_type); + +void blend (GdkColormap *colormap, + GdkColor *a, GdkColor *b, GdkColor *c, int alpha); + +GtkWidget *get_parent_window (GtkWidget *widget); + +GdkColor *get_parent_bgcolor (GtkWidget *widget); + +gboolean is_combo_box (GtkWidget * widget); + +GtkWidget *find_combo_box_widget (GtkWidget * widget); + +void gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button, + gint *column_index, gint *columns); diff --git a/libs/clearlooks-newer/widget-information.c b/libs/clearlooks-newer/widget-information.c new file mode 100644 index 0000000000..cbeb00e291 --- /dev/null +++ b/libs/clearlooks-newer/widget-information.c @@ -0,0 +1,312 @@ +#include <gtk/gtk.h> + +#include "general-support.h" +#include "widget-information.h" +#include <math.h> +#include <string.h> + +/* Widget Type Lookups/Macros + + Based on/modified from functions in + Smooth-Engine. +*/ +gboolean +ge_object_is_a (const GObject * object, const gchar * type_name) +{ + gboolean result = FALSE; + + if ((object)) + { + GType tmp = g_type_from_name (type_name); + + if (tmp) + result = g_type_check_instance_is_a ((GTypeInstance *) object, tmp); + } + + return result; +} + +gboolean +ge_is_combo_box_entry (GtkWidget * widget) +{ + gboolean result = FALSE; + + if ((widget) && (widget->parent)) + { + if (GE_IS_COMBO_BOX_ENTRY (widget->parent)) + result = TRUE; + else + result = ge_is_combo_box_entry (widget->parent); + } + return result; +} + +static gboolean +ge_combo_box_is_using_list (GtkWidget * widget) +{ + gboolean result = FALSE; + + if (GE_IS_COMBO_BOX (widget)) + { + gboolean *tmp = NULL; + + gtk_widget_style_get (widget, "appears-as-list", &result, NULL); + + if (tmp) + result = *tmp; + } + + return result; +} + +gboolean +ge_is_combo_box (GtkWidget * widget, gboolean as_list) +{ + gboolean result = FALSE; + + if ((widget) && (widget->parent)) + { + if (GE_IS_COMBO_BOX (widget->parent)) + { + if (as_list) + result = (ge_combo_box_is_using_list(widget->parent)); + else + result = (!ge_combo_box_is_using_list(widget->parent)); + } + else + result = ge_is_combo_box (widget->parent, as_list); + } + return result; +} + +gboolean +ge_is_combo (GtkWidget * widget) +{ + gboolean result = FALSE; + + if ((widget) && (widget->parent)) + { + if (GE_IS_COMBO (widget->parent)) + result = TRUE; + else + result = ge_is_combo (widget->parent); + } + return result; +} + +gboolean +ge_is_in_combo_box (GtkWidget * widget) +{ + return ((ge_is_combo (widget) || ge_is_combo_box (widget, TRUE) || ge_is_combo_box_entry (widget))); +} + +gboolean +ge_is_toolbar_item (GtkWidget * widget) +{ + gboolean result = FALSE; + + if ((widget) && (widget->parent)) { + if ((GE_IS_BONOBO_TOOLBAR (widget->parent)) + || (GE_IS_BONOBO_DOCK_ITEM (widget->parent)) + || (GE_IS_EGG_TOOLBAR (widget->parent)) + || (GE_IS_TOOLBAR (widget->parent)) + || (GE_IS_HANDLE_BOX (widget->parent))) + result = TRUE; + else + result = ge_is_toolbar_item (widget->parent); + } + return result; +} + +gboolean +ge_is_panel_widget_item (GtkWidget * widget) +{ + gboolean result = FALSE; + + if ((widget) && (widget->parent)) + { + if (GE_IS_PANEL_WIDGET (widget->parent)) + result = TRUE; + else + result = ge_is_panel_widget_item (widget->parent); + } + return result; +} + +gboolean +ge_is_bonobo_dock_item (GtkWidget * widget) +{ + gboolean result = FALSE; + + if ((widget)) + { + if (GE_IS_BONOBO_DOCK_ITEM(widget) || GE_IS_BONOBO_DOCK_ITEM (widget->parent)) + result = TRUE; + else if (GE_IS_BOX(widget) || GE_IS_BOX(widget->parent)) + { + GtkContainer *box = GE_IS_BOX(widget)?GTK_CONTAINER(widget):GTK_CONTAINER(widget->parent); + GList *children = NULL, *child = NULL; + + children = gtk_container_get_children(box); + + for (child = g_list_first(children); child; child = g_list_next(child)) + { + if (GE_IS_BONOBO_DOCK_ITEM_GRIP(child->data)) + { + result = TRUE; + child = NULL; + } + } + + if (children) + g_list_free(children); + } + } + return result; +} + +static GtkWidget * +ge_find_combo_box_entry_widget (GtkWidget * widget) +{ + GtkWidget *result = NULL; + + if (widget) + { + if (GE_IS_COMBO_BOX_ENTRY (widget)) + result = widget; + else + result = ge_find_combo_box_entry_widget (widget->parent); + } + + return result; +} + +static GtkWidget * +ge_find_combo_box_widget (GtkWidget * widget, gboolean as_list) +{ + GtkWidget *result = NULL; + + if (widget) + { + if (GE_IS_COMBO_BOX (widget)) + { + if (as_list) + result = (ge_combo_box_is_using_list(widget))?widget:NULL; + else + result = (!ge_combo_box_is_using_list(widget))?widget:NULL; + } + else + result = ge_find_combo_box_widget (widget->parent, as_list); + } + return result; +} + +static GtkWidget * +ge_find_combo_widget (GtkWidget * widget) +{ + GtkWidget *result = NULL; + + if (widget) + { + if (GE_IS_COMBO (widget)) + result = widget; + else + result = ge_find_combo_widget(widget->parent); + } + return result; +} + +GtkWidget* +ge_find_combo_box_widget_parent (GtkWidget * widget) +{ + GtkWidget *result = NULL; + + if (!result) + result = ge_find_combo_widget(widget); + + if (!result) + result = ge_find_combo_box_widget(widget, TRUE); + + if (!result) + result = ge_find_combo_box_entry_widget(widget); + + return result; +} + +/*********************************************** + * option_menu_get_props - + * + * Find Option Menu Size and Spacing + * + * Taken from Smooth + ***********************************************/ +void +ge_option_menu_get_props (GtkWidget * widget, + GtkRequisition * indicator_size, + GtkBorder * indicator_spacing) +{ + GtkRequisition default_size = { 9, 5 }; + GtkBorder default_spacing = { 7, 5, 2, 2 }; + GtkRequisition *tmp_size = NULL; + GtkBorder *tmp_spacing = NULL; + + if ((widget) && GE_IS_OPTION_MENU(widget)) + gtk_widget_style_get (widget, + "indicator_size", &tmp_size, + "indicator_spacing", &tmp_spacing, NULL); + + if (tmp_size) + { + *indicator_size = *tmp_size; + gtk_requisition_free (tmp_size); + } + else + *indicator_size = default_size; + + if (tmp_spacing) + { + *indicator_spacing = *tmp_spacing; + gtk_border_free (tmp_spacing); + } + else + *indicator_spacing = default_spacing; +} + +void +ge_button_get_default_border (GtkWidget *widget, + GtkBorder *border) +{ + GtkBorder default_border = {1, 1, 1, 1}; + GtkBorder *tmp_border = NULL; + + if (widget && GE_IS_BUTTON (widget)) + gtk_widget_style_get (widget, "default-border", &tmp_border, NULL); + + if (tmp_border) + { + *border = *tmp_border; + gtk_border_free (tmp_border); + } + else + { + *border = default_border; + } +} + + +gboolean +ge_widget_is_ltr (GtkWidget *widget) +{ + GtkTextDirection dir = GTK_TEXT_DIR_NONE; + + if (GE_IS_WIDGET (widget)) + dir = gtk_widget_get_direction (widget); + + if (dir == GTK_TEXT_DIR_NONE) + dir = gtk_widget_get_default_direction (); + + if (dir == GTK_TEXT_DIR_RTL) + return FALSE; + else + return TRUE; +} diff --git a/libs/clearlooks-newer/widget-information.h b/libs/clearlooks-newer/widget-information.h new file mode 100644 index 0000000000..55da859d78 --- /dev/null +++ b/libs/clearlooks-newer/widget-information.h @@ -0,0 +1,99 @@ + +/* Object Type Lookups/Macros + + Based on/modified from functions in + Smooth-Engine. +*/ +#define GE_IS_WIDGET(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkWidget")) +#define GE_IS_CONTAINER(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkContainer")) +#define GE_IS_BIN(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkBin")) + +#define GE_IS_ARROW(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkArrow")) + +#define GE_IS_SEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkSeparator")) +#define GE_IS_VSEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkVSeparator")) +#define GE_IS_HSEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHSeparator")) + +#define GE_IS_HANDLE_BOX(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHandleBox")) +#define GE_IS_HANDLE_BOX_ITEM(object) ((object) && GE_IS_HANDLE_BOX(object->parent)) +#define GE_IS_BONOBO_DOCK_ITEM(object) ((object) && ge_object_is_a ((GObject*)(object), "BonoboDockItem")) +#define GE_IS_BONOBO_DOCK_ITEM_GRIP(object) ((object) && ge_object_is_a ((GObject*)(object), "BonoboDockItemGrip")) +#define GE_IS_BONOBO_TOOLBAR(object) ((object) && ge_object_is_a ((GObject*)(object), "BonoboUIToolbar")) +#define GE_IS_EGG_TOOLBAR(object) ((object) && ge_object_is_a ((GObject*)(object), "Toolbar")) +#define GE_IS_TOOLBAR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkToolbar")) +#define GE_IS_PANEL_WIDGET(object) ((object) && (ge_object_is_a ((GObject*)(object), "PanelWidget") || ge_object_is_a ((GObject*)(object), "PanelApplet"))) + +#define GE_IS_COMBO_BOX_ENTRY(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkComboBoxEntry")) +#define GE_IS_COMBO_BOX(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkComboBox")) +#define GE_IS_COMBO(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkCombo")) +#define GE_IS_OPTION_MENU(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkOptionMenu")) + +#define GE_IS_TOGGLE_BUTTON(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkToggleButton")) +#define GE_IS_CHECK_BUTTON(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkCheckButton")) +#define GE_IS_SPIN_BUTTON(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkSpinButton")) + +#define GE_IS_STATUSBAR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkStatusbar")) +#define GE_IS_PROGRESS_BAR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkProgressBar")) + +#define GE_IS_MENU_SHELL(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkMenuShell")) +#define GE_IS_MENU(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkMenu")) +#define GE_IS_MENU_BAR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkMenuBar")) +#define GE_IS_MENU_ITEM(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkMenuItem")) + +#define GE_IS_CHECK_MENU_ITEM(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkCheckMenuItem")) + +#define GE_IS_RANGE(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkRange")) + +#define GE_IS_SCROLLBAR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkScrollbar")) +#define GE_IS_VSCROLLBAR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkVScrollbar")) +#define GE_IS_HSCROLLBAR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHScrollbar")) + +#define GE_IS_SCALE(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkScale")) +#define GE_IS_VSCALE(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkVScale")) +#define GE_IS_HSCALE(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHScale")) + +#define GE_IS_PANED(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkPaned")) +#define GE_IS_VPANED(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkVPaned")) +#define GE_IS_HPANED(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHPaned")) + +#define GE_IS_BOX(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkBox")) +#define GE_IS_VBOX(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkVBox")) +#define GE_IS_HBOX(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHBox")) + +#define GE_IS_CLIST(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkCList")) +#define GE_IS_TREE_VIEW(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkTreeView")) +#define GE_IS_ENTRY(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkEntry")) +#define GE_IS_BUTTON(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkButton")) +#define GE_IS_FIXED(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkFixed")) + +#define TOGGLE_BUTTON(object) (GE_IS_TOGGLE_BUTTON(object)?(GtkToggleButton *)object:NULL) + +#define GE_IS_NOTEBOOK(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkNotebook")) +#define GE_IS_CELL_RENDERER_TOGGLE(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkCellRendererToggle")) + +#define GE_WIDGET_HAS_DEFAULT(object) ((object) && GE_IS_WIDGET(object) && GTK_WIDGET_HAS_DEFAULT(object)) + +GE_INTERNAL gboolean ge_object_is_a (const GObject * object, const gchar * type_name); + +GE_INTERNAL gboolean ge_is_combo_box_entry (GtkWidget * widget); +GE_INTERNAL gboolean ge_is_combo_box (GtkWidget * widget, gboolean as_list); +GE_INTERNAL gboolean ge_is_combo (GtkWidget * widget); +GE_INTERNAL gboolean ge_is_in_combo_box (GtkWidget * widget); + +GE_INTERNAL gboolean ge_is_toolbar_item (GtkWidget * widget); + +GE_INTERNAL gboolean ge_is_panel_widget_item (GtkWidget * widget); + +GE_INTERNAL gboolean ge_is_bonobo_dock_item (GtkWidget * widget); + +GE_INTERNAL GtkWidget *ge_find_combo_box_widget_parent (GtkWidget * widget); + +GE_INTERNAL void ge_option_menu_get_props (GtkWidget * widget, + GtkRequisition * indicator_size, + GtkBorder * indicator_spacing); + +GE_INTERNAL void ge_button_get_default_border (GtkWidget *widget, + GtkBorder *border); + +GE_INTERNAL gboolean ge_widget_is_ltr (GtkWidget *widget); + |