1 /* Clearlooks theme engine
2 * Copyright (C) 2005 Richard Stellingwerff
3 * Copyright (C) 2007 Benjamin Berg
4 * Copyright (C) 2007 Andrea Cimitan
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
28 #include <ge-support.h>
29 #include "clearlooks_style.h"
30 #include "clearlooks_rc_style.h"
31 #include "clearlooks_draw.h"
36 #define DETAIL(xx) ((detail) && (!strcmp(xx, detail)))
37 #define CHECK_HINT(xx) (ge_check_hint ((xx), CLEARLOOKS_RC_STYLE ((style)->rc_style)->hint, widget))
39 #define DRAW_ARGS GtkStyle *style, \
41 GtkStateType state_type, \
42 GtkShadowType shadow_type, \
45 const gchar *detail, \
52 #include "animation.h"
55 #define STYLE_FUNCTION(function) (CLEARLOOKS_STYLE_GET_CLASS (style)->style_functions[CLEARLOOKS_STYLE (style)->style].function)
57 G_DEFINE_DYNAMIC_TYPE (ClearlooksStyle, clearlooks_style, GTK_TYPE_STYLE)
60 clearlooks_set_widget_parameters (const GtkWidget *widget,
61 const GtkStyle *style,
62 GtkStateType state_type,
63 WidgetParameters *params)
65 params->style_functions = &(CLEARLOOKS_STYLE_GET_CLASS (style)->style_functions[CLEARLOOKS_STYLE (style)->style]);
66 params->style_constants = &(CLEARLOOKS_STYLE_GET_CLASS (style)->style_constants[CLEARLOOKS_STYLE (style)->style]);
68 params->active = (state_type == GTK_STATE_ACTIVE);
69 params->prelight = (state_type == GTK_STATE_PRELIGHT);
70 params->disabled = (state_type == GTK_STATE_INSENSITIVE);
71 params->state_type = (ClearlooksStateType)state_type;
72 params->corners = CR_CORNER_ALL;
73 params->ltr = ge_widget_is_ltr ((GtkWidget*)widget);
74 params->focus = widget && GTK_WIDGET_HAS_FOCUS (widget);
75 params->is_default = widget && GE_WIDGET_HAS_DEFAULT (widget);
76 params->enable_shadow = FALSE;
77 params->radius = CLEARLOOKS_STYLE (style)->radius;
79 params->xthickness = style->xthickness;
80 params->ythickness = style->ythickness;
82 /* This is used in GtkEntry to fake transparency. The reason to do this
83 * is that the entry has it's entire background filled with base[STATE].
84 * This is not a very good solution as it will eg. fail if one changes
85 * the background color of a notebook. */
86 params->parentbg = CLEARLOOKS_STYLE (style)->colors.bg[state_type];
87 clearlooks_get_parent_bg (widget, ¶ms->parentbg);
91 clearlooks_style_draw_flat_box (DRAW_ARGS)
94 state_type == GTK_STATE_SELECTED && (
95 !strncmp ("cell_even", detail, 9) ||
96 !strncmp ("cell_odd", detail, 8)))
98 WidgetParameters params;
99 ClearlooksStyle *clearlooks_style;
100 ClearlooksColors *colors;
106 clearlooks_style = CLEARLOOKS_STYLE (style);
107 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
108 colors = &clearlooks_style->colors;
109 cr = ge_gdk_drawable_to_cairo (window, area);
111 /* XXX: We could expose the side details by setting params->corners accordingly
112 * or adding another option. */
113 STYLE_FUNCTION (draw_selected_cell) (cr, colors, ¶ms, x, y, width, height);
117 else if (DETAIL ("tooltip"))
119 WidgetParameters params;
120 ClearlooksStyle *clearlooks_style;
121 ClearlooksColors *colors;
127 clearlooks_style = CLEARLOOKS_STYLE (style);
128 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
129 colors = &clearlooks_style->colors;
130 cr = ge_gdk_drawable_to_cairo (window, area);
132 STYLE_FUNCTION (draw_tooltip) (cr, colors, ¶ms, x, y, width, height);
136 else if ((CLEARLOOKS_STYLE (style)->style == CL_STYLE_GLOSSY || CLEARLOOKS_STYLE (style)->style == CL_STYLE_GUMMY) &&
137 ((DETAIL("checkbutton") || DETAIL("radiobutton")) && state_type == GTK_STATE_PRELIGHT))
139 /* XXX: Don't draw any check/radiobutton bg in GLOSSY or GUMMY mode. */
143 GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_flat_box (style, window, state_type,
145 area, widget, detail,
146 x, y, width, height);
151 clearlooks_style_draw_shadow (DRAW_ARGS)
153 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
154 ClearlooksColors *colors = &clearlooks_style->colors;
155 cairo_t *cr = ge_gdk_drawable_to_cairo (window, area);
160 /* The "frame" thing is a hack because of GtkCombo. */
161 if ((DETAIL ("entry") && !CHECK_HINT (GE_HINT_TREEVIEW)) ||
162 (DETAIL ("frame") && CHECK_HINT (GE_HINT_COMBOBOX_ENTRY)))
164 WidgetParameters params;
166 /* Override the entries state type, because we are too lame to handle this via
167 * the focus ring, and GtkEntry doesn't even set the INSENSITIVE state ... */
168 if (state_type == GTK_STATE_NORMAL && widget && GE_IS_ENTRY (widget))
169 state_type = GTK_WIDGET_STATE (widget);
171 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
173 if (CHECK_HINT (GE_HINT_COMBOBOX_ENTRY) || CHECK_HINT (GE_HINT_SPINBUTTON))
175 width += style->xthickness;
177 x -= style->xthickness;
180 params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
182 params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
185 /* Fill the background as it is initilized to base[NORMAL].
186 * Relevant GTK+ bug: http://bugzilla.gnome.org/show_bug.cgi?id=513471
187 * The fill only happens if no hint has been added by some application
188 * that is faking GTK+ widgets. */
189 if (!widget || !g_object_get_data(G_OBJECT (widget), "transparent-bg-hint"))
191 cairo_rectangle (cr, 0, 0, width, height);
192 ge_cairo_set_color (cr, ¶ms.parentbg);
196 STYLE_FUNCTION (draw_entry) (cr, &clearlooks_style->colors, ¶ms,
197 x, y, width, height);
199 else if (DETAIL ("frame") && CHECK_HINT (GE_HINT_STATUSBAR))
201 WidgetParameters params;
203 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
205 gtk_style_apply_default_background (style, window, TRUE, state_type,
206 area, x, y, width, height);
207 if (shadow_type != GTK_SHADOW_NONE)
208 STYLE_FUNCTION (draw_statusbar) (cr, colors, ¶ms,
209 x, y, width, height);
211 else if (DETAIL ("frame") || DETAIL ("calendar"))
213 WidgetParameters params;
214 FrameParameters frame;
215 frame.shadow = shadow_type;
216 frame.gap_x = -1; /* No gap will be drawn */
217 frame.border = &colors->shade[4];
219 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
220 params.corners = CR_CORNER_NONE;
222 if (widget && !g_str_equal ("XfcePanelWindow", gtk_widget_get_name (gtk_widget_get_toplevel (widget))))
223 STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame,
224 x, y, width, height);
226 else if (DETAIL ("scrolled_window") || DETAIL ("viewport") || detail == NULL)
230 if (CLEARLOOKS_STYLE (style)->style == CL_STYLE_CLASSIC)
231 ge_shade_color ((CairoColor*)&colors->bg[0], 0.78, &border);
233 border = colors->shade[5];
235 cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
236 ge_cairo_set_color (cr, &border);
237 cairo_set_line_width (cr, 1);
242 WidgetParameters params;
243 FrameParameters frame;
245 frame.shadow = shadow_type;
247 frame.border = &colors->shade[5];
248 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
249 params.corners = CR_CORNER_ALL;
251 STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, x, y, width, height);
258 clearlooks_style_draw_box_gap (DRAW_ARGS,
259 GtkPositionType gap_side,
263 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
264 ClearlooksColors *colors = &clearlooks_style->colors;
270 cr = ge_gdk_drawable_to_cairo (window, area);
272 if (DETAIL ("notebook"))
274 WidgetParameters params;
275 FrameParameters frame;
278 frame.shadow = shadow_type;
279 frame.gap_side = gap_side;
281 frame.gap_width = gap_width;
282 frame.border = &colors->shade[5];
284 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
286 clearlooks_get_notebook_tab_position (widget, &start, &end);
288 params.corners = CR_CORNER_ALL;
292 if (ge_widget_is_ltr (widget))
295 params.corners ^= CR_CORNER_TOPLEFT;
297 params.corners ^= CR_CORNER_TOPRIGHT;
302 params.corners ^= CR_CORNER_TOPRIGHT;
304 params.corners ^= CR_CORNER_TOPLEFT;
308 if (ge_widget_is_ltr (widget))
311 params.corners ^= CR_CORNER_BOTTOMLEFT;
313 params.corners ^= CR_CORNER_BOTTOMRIGHT;
318 params.corners ^= CR_CORNER_BOTTOMRIGHT;
320 params.corners ^= CR_CORNER_BOTTOMLEFT;
325 params.corners ^= CR_CORNER_TOPLEFT;
327 params.corners ^= CR_CORNER_BOTTOMLEFT;
331 params.corners ^= CR_CORNER_TOPRIGHT;
333 params.corners ^= CR_CORNER_BOTTOMRIGHT;
337 /* Fill the background with bg[NORMAL] */
338 ge_cairo_rounded_rectangle (cr, x, y, width, height, params.radius, params.corners);
339 ge_cairo_set_color (cr, &colors->bg[GTK_STATE_NORMAL]);
342 STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame,
343 x, y, width, height);
347 GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_box_gap (style, window, state_type, shadow_type,
348 area, widget, detail,
350 gap_side, gap_x, gap_width);
357 clearlooks_style_draw_extension (DRAW_ARGS, GtkPositionType gap_side)
359 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
360 ClearlooksColors *colors = &clearlooks_style->colors;
366 cr = ge_gdk_drawable_to_cairo (window, area);
370 WidgetParameters params;
372 FocusParameters focus;
374 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
376 tab.gap_side = (ClearlooksGapSide)gap_side;
381 params.corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT;
384 params.corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
387 params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
390 params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
395 if (clearlooks_style->has_focus_color)
397 ge_gdk_color_to_cairo (&clearlooks_style->focus_color, &focus.color);
398 focus.has_color = TRUE;
401 focus.color = colors->bg[GTK_STATE_SELECTED];
405 STYLE_FUNCTION(draw_tab) (cr, colors, ¶ms, &tab,
406 x, y, width, height);
410 GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_extension (style, window, state_type, shadow_type, area,
411 widget, detail, x, y, width, height,
419 clearlooks_style_draw_handle (DRAW_ARGS, GtkOrientation orientation)
421 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
422 ClearlooksColors *colors = &clearlooks_style->colors;
428 cr = ge_gdk_drawable_to_cairo (window, area);
430 if (DETAIL ("handlebox"))
432 WidgetParameters params;
433 HandleParameters handle;
435 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
436 handle.type = CL_HANDLE_TOOLBAR;
437 handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
439 STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle,
440 x, y, width, height);
442 else if (DETAIL ("paned"))
444 WidgetParameters params;
445 HandleParameters handle;
447 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
448 handle.type = CL_HANDLE_SPLITTER;
449 handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
451 STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle,
452 x, y, width, height);
456 WidgetParameters params;
457 HandleParameters handle;
459 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
460 handle.type = CL_HANDLE_TOOLBAR;
461 handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
463 STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle,
464 x, y, width, height);
471 clearlooks_style_draw_box (DRAW_ARGS)
473 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
474 const ClearlooksColors *colors;
477 cr = ge_gdk_drawable_to_cairo (window, area);
478 colors = &clearlooks_style->colors;
483 if (DETAIL ("menubar"))
485 WidgetParameters params;
486 MenuBarParameters menubar;
489 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
491 menubar.style = clearlooks_style->menubarstyle;
493 horizontal = height < 2*width;
494 /* This is not that great. Ideally we would have a nice vertical menubar. */
495 if ((shadow_type != GTK_SHADOW_NONE) && horizontal)
496 STYLE_FUNCTION(draw_menubar) (cr, colors, ¶ms, &menubar,
497 x, y, width, height);
499 else if (DETAIL ("button") && CHECK_HINT (GE_HINT_TREEVIEW_HEADER))
501 WidgetParameters params;
502 ListViewHeaderParameters header;
504 gint columns, column_index;
505 gboolean resizable = TRUE;
507 /* XXX: This makes unknown treeview header "middle", in need for something nicer */
511 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
513 params.corners = CR_CORNER_NONE;
515 if (GE_IS_TREE_VIEW (widget->parent))
517 clearlooks_treeview_get_header_index (GTK_TREE_VIEW(widget->parent),
518 widget, &column_index, &columns,
521 else if (GE_IS_CLIST (widget->parent))
523 clearlooks_clist_get_header_index (GTK_CLIST(widget->parent),
524 widget, &column_index, &columns);
527 header.resizable = resizable;
530 if (column_index == 0)
531 header.order |= params.ltr ? CL_ORDER_FIRST : CL_ORDER_LAST;
532 if (column_index == columns-1)
533 header.order |= params.ltr ? CL_ORDER_LAST : CL_ORDER_FIRST;
535 gtk_style_apply_default_background (style, window, FALSE, state_type, area, x, y, width, height);
537 STYLE_FUNCTION(draw_list_view_header) (cr, colors, ¶ms, &header,
538 x, y, width, height);
540 else if (DETAIL ("button") || DETAIL ("buttondefault"))
542 WidgetParameters params;
543 ShadowParameters shadow = { CR_CORNER_ALL, CL_SHADOW_NONE } ;
544 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
545 params.active = shadow_type == GTK_SHADOW_IN;
547 if (CHECK_HINT (GE_HINT_COMBOBOX_ENTRY))
550 params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
552 params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
554 shadow.shadow = CL_SHADOW_IN;
556 if (params.xthickness > 2)
565 params.corners = CR_CORNER_ALL;
566 if (clearlooks_style->reliefstyle != 0)
567 params.enable_shadow = TRUE;
570 STYLE_FUNCTION(draw_button) (cr, &clearlooks_style->colors, ¶ms,
571 x, y, width, height);
573 else if (DETAIL ("spinbutton_up") || DETAIL ("spinbutton_down"))
575 if (state_type == GTK_STATE_ACTIVE)
577 WidgetParameters params;
578 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
580 if (style->xthickness == 3)
587 if (DETAIL ("spinbutton_up"))
591 params.corners = CR_CORNER_TOPRIGHT;
593 params.corners = CR_CORNER_TOPLEFT;
598 params.corners = CR_CORNER_BOTTOMRIGHT;
600 params.corners = CR_CORNER_BOTTOMLEFT;
603 STYLE_FUNCTION(draw_spinbutton_down) (cr, &clearlooks_style->colors, ¶ms, x, y, width, height);
606 else if (DETAIL ("spinbutton"))
608 WidgetParameters params;
610 /* The "spinbutton" box is always drawn with state NORMAL, even if it is insensitive.
611 * So work around this here. */
612 if (state_type == GTK_STATE_NORMAL && widget && GE_IS_ENTRY (widget))
613 state_type = GTK_WIDGET_STATE (widget);
615 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
618 params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
620 params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
622 if (style->xthickness == 3)
629 STYLE_FUNCTION(draw_spinbutton) (cr, &clearlooks_style->colors, ¶ms,
630 x, y, width, height);
632 else if (detail && g_str_has_prefix (detail, "trough") && CHECK_HINT (GE_HINT_SCALE))
634 WidgetParameters params;
635 SliderParameters slider;
637 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
638 params.corners = CR_CORNER_NONE;
640 slider.lower = DETAIL ("trough-lower");
641 slider.fill_level = DETAIL ("trough-fill-level") || DETAIL ("trough-fill-level-full");
643 if (CHECK_HINT (GE_HINT_HSCALE))
644 slider.horizontal = TRUE;
645 else if (CHECK_HINT (GE_HINT_VSCALE))
646 slider.horizontal = FALSE;
647 else /* Fallback based on the size... */
648 slider.horizontal = width >= height;
650 STYLE_FUNCTION(draw_scale_trough) (cr, &clearlooks_style->colors,
652 x, y, width, height);
654 else if (DETAIL ("trough") && CHECK_HINT (GE_HINT_PROGRESSBAR))
656 WidgetParameters params;
658 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
660 /* Fill the background as it is initilized to base[NORMAL].
661 * Relevant GTK+ bug: http://bugzilla.gnome.org/show_bug.cgi?id=513476
662 * The fill only happens if no hint has been added by some application
663 * that is faking GTK+ widgets. */
664 if (!widget || !g_object_get_data(G_OBJECT (widget), "transparent-bg-hint"))
666 cairo_rectangle (cr, 0, 0, width, height);
667 ge_cairo_set_color (cr, ¶ms.parentbg);
670 STYLE_FUNCTION(draw_progressbar_trough) (cr, colors, ¶ms,
671 x, y, width, height);
673 else if (DETAIL ("trough") && CHECK_HINT (GE_HINT_SCROLLBAR))
675 WidgetParameters params;
676 ScrollBarParameters scrollbar;
677 gboolean trough_under_steppers = TRUE;
678 ClearlooksStepper steppers;
680 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
681 params.corners = CR_CORNER_ALL;
683 scrollbar.horizontal = TRUE;
684 scrollbar.junction = clearlooks_scrollbar_get_junction (widget);
686 steppers = clearlooks_scrollbar_visible_steppers (widget);
688 if (CHECK_HINT (GE_HINT_HSCROLLBAR))
689 scrollbar.horizontal = TRUE;
690 else if (CHECK_HINT (GE_HINT_VSCROLLBAR))
691 scrollbar.horizontal = FALSE;
692 else /* Fallback based on the size ... */
693 scrollbar.horizontal = width >= height;
696 gtk_widget_style_get (widget,
697 "trough-under-steppers", &trough_under_steppers,
700 if (trough_under_steppers)
702 /* If trough under steppers is set, then we decrease the size
703 * slightly. The size is decreased so that the trough is not
704 * visible underneath the steppers. This is not really needed
705 * as one can use the trough-under-steppers style property,
706 * but it needs to exist for backward compatibility. */
707 if (scrollbar.horizontal)
709 if (steppers & (CL_STEPPER_A | CL_STEPPER_B))
714 if (steppers & (CL_STEPPER_C | CL_STEPPER_D))
721 if (steppers & (CL_STEPPER_A | CL_STEPPER_B))
726 if (steppers & (CL_STEPPER_C | CL_STEPPER_D))
733 STYLE_FUNCTION(draw_scrollbar_trough) (cr, colors, ¶ms, &scrollbar,
734 x, y, width, height);
736 else if (DETAIL ("bar"))
738 WidgetParameters params;
739 ProgressBarParameters progressbar;
740 gdouble elapsed = 0.0;
742 #ifdef HAVE_ANIMATION
743 if(clearlooks_style->animation && CL_IS_PROGRESS_BAR (widget))
745 gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode;
748 clearlooks_animation_progressbar_add ((gpointer)widget);
751 elapsed = clearlooks_animation_elapsed (widget);
754 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
756 if (widget && GE_IS_PROGRESS_BAR (widget))
758 progressbar.orientation = gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (widget));
759 progressbar.value = gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(widget));
760 progressbar.pulsing = GTK_PROGRESS (widget)->activity_mode;
764 progressbar.orientation = CL_ORIENTATION_LEFT_TO_RIGHT;
765 progressbar.value = 0;
766 progressbar.pulsing = FALSE;
771 if (progressbar.orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
772 progressbar.orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
773 else if (progressbar.orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
774 progressbar.orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
777 /* Following is a hack to have a larger clip area, the one passed in
778 * does not allow for the shadow. */
781 GdkRectangle tmp = *area;
782 if (!progressbar.pulsing)
784 switch (progressbar.orientation)
786 case GTK_PROGRESS_RIGHT_TO_LEFT:
788 case GTK_PROGRESS_LEFT_TO_RIGHT:
791 case GTK_PROGRESS_BOTTOM_TO_TOP:
793 case GTK_PROGRESS_TOP_TO_BOTTOM:
800 if (progressbar.orientation == GTK_PROGRESS_RIGHT_TO_LEFT ||
801 progressbar.orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
813 cairo_reset_clip (cr);
814 gdk_cairo_rectangle (cr, &tmp);
818 STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, ¶ms, &progressbar,
820 10 - (int)(elapsed * 10.0) % 10);
822 else if (DETAIL ("optionmenu"))
824 WidgetParameters params;
825 OptionMenuParameters optionmenu;
827 GtkRequisition indicator_size;
828 GtkBorder indicator_spacing;
830 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
832 if (clearlooks_style->reliefstyle != 0)
833 params.enable_shadow = TRUE;
835 ge_option_menu_get_props (widget, &indicator_size, &indicator_spacing);
837 if (ge_widget_is_ltr (widget))
838 optionmenu.linepos = width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - 1;
840 optionmenu.linepos = (indicator_size.width + indicator_spacing.left + indicator_spacing.right) + 1;
842 STYLE_FUNCTION(draw_optionmenu) (cr, colors, ¶ms, &optionmenu,
843 x, y, width, height);
845 else if (DETAIL ("menuitem"))
847 WidgetParameters params;
848 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
850 if (CHECK_HINT (GE_HINT_MENUBAR))
852 params.corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
854 STYLE_FUNCTION(draw_menubaritem) (cr, colors, ¶ms, x, y, width, height);
858 params.corners = CR_CORNER_ALL;
859 STYLE_FUNCTION(draw_menuitem) (cr, colors, ¶ms, x, y, width, height);
862 else if (DETAIL ("hscrollbar") || DETAIL ("vscrollbar")) /* This can't be "stepper" for scrollbars ... */
864 WidgetParameters params;
865 ScrollBarParameters scrollbar;
866 ScrollBarStepperParameters stepper;
867 GdkRectangle this_rectangle;
869 this_rectangle.x = x;
870 this_rectangle.y = y;
871 this_rectangle.width = width;
872 this_rectangle.height = height;
874 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
875 params.corners = CR_CORNER_NONE;
877 scrollbar.has_color = FALSE;
878 scrollbar.horizontal = TRUE;
879 scrollbar.junction = clearlooks_scrollbar_get_junction (widget);
881 if (clearlooks_style->colorize_scrollbar || clearlooks_style->has_scrollbar_color)
882 scrollbar.has_color = TRUE;
884 scrollbar.horizontal = DETAIL ("hscrollbar");
886 stepper.stepper = clearlooks_scrollbar_get_stepper (widget, &this_rectangle);
888 STYLE_FUNCTION(draw_scrollbar_stepper) (cr, colors, ¶ms, &scrollbar, &stepper,
889 x, y, width, height);
891 else if (DETAIL ("toolbar") || DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin"))
893 WidgetParameters params;
894 ToolbarParameters toolbar;
897 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
898 clearlooks_set_toolbar_parameters (&toolbar, widget, window, x, y);
900 toolbar.style = clearlooks_style->toolbarstyle;
902 if ((DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin")) && GE_IS_BIN (widget))
904 GtkWidget* child = gtk_bin_get_child ((GtkBin*) widget);
905 /* This is to draw the correct shadow on the handlebox.
906 * We need to draw it here, as otherwise the handle will not get the
908 if (GE_IS_TOOLBAR (child))
909 gtk_widget_style_get (child, "shadow-type", &shadow_type, NULL);
912 horizontal = height < 2*width;
913 /* This is not that great. Ideally we would have a nice vertical toolbar. */
914 if ((shadow_type != GTK_SHADOW_NONE) && horizontal)
915 STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height);
917 else if (DETAIL ("trough"))
919 /* Nothing? Why benjamin? */
921 else if (DETAIL ("menu"))
923 WidgetParameters params;
925 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
927 STYLE_FUNCTION(draw_menu_frame) (cr, colors, ¶ms, x, y, width, height);
929 else if (DETAIL ("hseparator") || DETAIL ("vseparator"))
931 gchar *new_detail = (gchar*) detail;
932 /* Draw a normal separator, we just use this because it gives more control
933 * over sizing (currently). */
935 /* This isn't nice ... but it seems like the best cleanest way to me right now.
936 * It will get slightly nicer in the future hopefully. */
937 if (GE_IS_MENU_ITEM (widget))
938 new_detail = "menuitem";
940 if (DETAIL ("hseparator"))
942 gtk_paint_hline (style, window, state_type, area, widget, new_detail,
943 x, x + width - 1, y + height/2);
946 gtk_paint_vline (style, window, state_type, area, widget, new_detail,
947 y, y + height - 1, x + width/2);
951 GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_box (style, window, state_type, shadow_type, area,
952 widget, detail, x, y, width, height);
959 clearlooks_style_draw_slider (DRAW_ARGS, GtkOrientation orientation)
961 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
962 const ClearlooksColors *colors;
965 cr = ge_gdk_drawable_to_cairo (window, area);
966 colors = &clearlooks_style->colors;
971 if (DETAIL ("hscale") || DETAIL ("vscale"))
973 WidgetParameters params;
974 SliderParameters slider;
976 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
978 slider.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
979 slider.lower = FALSE;
980 slider.fill_level = FALSE;
982 if (clearlooks_style->style == CL_STYLE_GLOSSY) /* XXX! */
983 params.corners = CR_CORNER_ALL;
985 STYLE_FUNCTION(draw_slider_button) (cr, &clearlooks_style->colors,
987 x, y, width, height);
989 else if (DETAIL ("slider"))
991 WidgetParameters params;
992 ScrollBarParameters scrollbar;
994 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
995 params.corners = CR_CORNER_NONE;
997 scrollbar.has_color = FALSE;
998 scrollbar.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL);
999 scrollbar.junction = clearlooks_scrollbar_get_junction (widget);
1001 if (clearlooks_style->colorize_scrollbar)
1003 scrollbar.color = colors->spot[1];
1004 scrollbar.has_color = TRUE;
1007 /* Set scrollbar color */
1008 if (clearlooks_style->has_scrollbar_color)
1010 ge_gdk_color_to_cairo (&clearlooks_style->scrollbar_color, &scrollbar.color);
1011 scrollbar.has_color = TRUE;
1014 if ((clearlooks_style->style == CL_STYLE_GLOSSY || clearlooks_style->style == CL_STYLE_GUMMY)
1015 && !scrollbar.has_color)
1016 scrollbar.color = colors->bg[0];
1018 STYLE_FUNCTION(draw_scrollbar_slider) (cr, colors, ¶ms, &scrollbar,
1019 x, y, width, height);
1023 GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_slider (style, window, state_type, shadow_type, area,
1024 widget, detail, x, y, width, height, orientation);
1031 clearlooks_style_draw_option (DRAW_ARGS)
1033 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1034 const ClearlooksColors *colors;
1035 WidgetParameters params;
1036 CheckboxParameters checkbox;
1042 cr = ge_gdk_drawable_to_cairo (window, area);
1043 colors = &clearlooks_style->colors;
1045 checkbox.shadow_type = shadow_type;
1046 checkbox.in_menu = (widget && GTK_IS_MENU(widget->parent));
1048 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1050 STYLE_FUNCTION(draw_radiobutton) (cr, colors, ¶ms, &checkbox, x, y, width, height);
1056 clearlooks_style_draw_check (DRAW_ARGS)
1058 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1059 WidgetParameters params;
1060 CheckboxParameters checkbox;
1066 cr = ge_gdk_drawable_to_cairo (window, area);
1068 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1070 params.corners = CR_CORNER_ALL;
1072 checkbox.shadow_type = shadow_type;
1073 checkbox.in_cell = DETAIL("cellcheck");
1075 checkbox.in_menu = (widget && widget->parent && GTK_IS_MENU(widget->parent));
1077 STYLE_FUNCTION(draw_checkbox) (cr, &clearlooks_style->colors, ¶ms, &checkbox,
1078 x, y, width, height);
1084 clearlooks_style_draw_vline (GtkStyle *style,
1086 GtkStateType state_type,
1089 const gchar *detail,
1094 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1095 const ClearlooksColors *colors;
1096 SeparatorParameters separator = { FALSE };
1101 colors = &clearlooks_style->colors;
1103 cr = ge_gdk_drawable_to_cairo (window, area);
1105 /* There is no such thing as a vertical menu separator
1106 * (and even if, a normal one should be better on menu bars) */
1107 STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator,
1114 clearlooks_style_draw_hline (GtkStyle *style,
1116 GtkStateType state_type,
1119 const gchar *detail,
1124 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1125 const ClearlooksColors *colors;
1127 SeparatorParameters separator;
1131 colors = &clearlooks_style->colors;
1133 cr = ge_gdk_drawable_to_cairo (window, area);
1135 separator.horizontal = TRUE;
1137 if (!DETAIL ("menuitem"))
1138 STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator,
1141 STYLE_FUNCTION(draw_menu_item_separator) (cr, colors, NULL, &separator,
1148 clearlooks_style_draw_shadow_gap (DRAW_ARGS,
1149 GtkPositionType gap_side,
1153 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1154 const ClearlooksColors *colors;
1160 cr = ge_gdk_drawable_to_cairo (window, area);
1161 colors = &clearlooks_style->colors;
1163 if (DETAIL ("frame"))
1165 WidgetParameters params;
1166 FrameParameters frame;
1168 frame.shadow = shadow_type;
1169 frame.gap_side = gap_side;
1170 frame.gap_x = gap_x;
1171 frame.gap_width = gap_width;
1172 frame.border = &colors->shade[5];
1174 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1176 params.corners = CR_CORNER_ALL;
1178 STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame,
1179 x, y, width, height);
1183 GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_shadow_gap (style, window, state_type, shadow_type, area,
1184 widget, detail, x, y, width, height,
1185 gap_side, gap_x, gap_width);
1192 clearlooks_style_draw_resize_grip (GtkStyle *style,
1194 GtkStateType state_type,
1197 const gchar *detail,
1204 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1205 ClearlooksColors *colors = &clearlooks_style->colors;
1207 WidgetParameters params;
1208 ResizeGripParameters grip;
1213 grip.edge = (ClearlooksWindowEdge)edge;
1215 g_return_if_fail (window != NULL);
1217 cr = ge_gdk_drawable_to_cairo (window, area);
1219 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1221 STYLE_FUNCTION(draw_resize_grip) (cr, colors, ¶ms, &grip,
1222 x, y, width, height);
1228 clearlooks_style_draw_tab (DRAW_ARGS)
1230 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1231 ClearlooksColors *colors = &clearlooks_style->colors;
1232 WidgetParameters params;
1233 ArrowParameters arrow;
1239 cr = ge_gdk_drawable_to_cairo (window, area);
1241 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1242 arrow.type = CL_ARROW_COMBO;
1243 arrow.direction = CL_DIRECTION_DOWN;
1245 STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height);
1251 clearlooks_style_draw_arrow (GtkStyle *style,
1253 GtkStateType state_type,
1254 GtkShadowType shadow,
1257 const gchar *detail,
1258 GtkArrowType arrow_type,
1265 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1266 ClearlooksColors *colors = &clearlooks_style->colors;
1267 WidgetParameters params;
1268 ArrowParameters arrow;
1269 cairo_t *cr = ge_gdk_drawable_to_cairo (window, area);
1274 if (arrow_type == GTK_ARROW_NONE)
1280 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1281 arrow.type = CL_ARROW_NORMAL;
1282 arrow.direction = (ClearlooksDirection)arrow_type;
1284 if (ge_is_combo_box (widget, FALSE) && !ge_is_combo_box_entry (widget))
1286 arrow.type = CL_ARROW_COMBO;
1289 /* I have no idea why, but the arrow of GtkCombo is larger than in other places.
1290 * Subtracting 3 seems to fix this. */
1291 if (widget && widget->parent && GE_IS_COMBO (widget->parent->parent))
1300 STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height);
1306 clearlooks_style_init_from_rc (GtkStyle * style,
1307 GtkRcStyle * rc_style)
1309 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1311 GTK_STYLE_CLASS (clearlooks_style_parent_class)->init_from_rc (style, rc_style);
1313 g_assert ((CLEARLOOKS_RC_STYLE (rc_style)->style >= 0) && (CLEARLOOKS_RC_STYLE (rc_style)->style < CL_NUM_STYLES));
1314 clearlooks_style->style = CLEARLOOKS_RC_STYLE (rc_style)->style;
1316 clearlooks_style->reliefstyle = CLEARLOOKS_RC_STYLE (rc_style)->reliefstyle;
1317 clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle;
1318 clearlooks_style->toolbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->toolbarstyle;
1319 clearlooks_style->has_focus_color = CLEARLOOKS_RC_STYLE (rc_style)->flags & CL_FLAG_FOCUS_COLOR;
1320 clearlooks_style->has_scrollbar_color = CLEARLOOKS_RC_STYLE (rc_style)->flags & CL_FLAG_SCROLLBAR_COLOR;
1321 clearlooks_style->colorize_scrollbar = CLEARLOOKS_RC_STYLE (rc_style)->colorize_scrollbar;
1322 clearlooks_style->animation = CLEARLOOKS_RC_STYLE (rc_style)->animation;
1323 clearlooks_style->radius = CLAMP (CLEARLOOKS_RC_STYLE (rc_style)->radius, 0.0, 10.0);
1325 if (clearlooks_style->has_focus_color)
1326 clearlooks_style->focus_color = CLEARLOOKS_RC_STYLE (rc_style)->focus_color;
1327 if (clearlooks_style->has_scrollbar_color)
1328 clearlooks_style->scrollbar_color = CLEARLOOKS_RC_STYLE (rc_style)->scrollbar_color;
1332 clearlooks_style_realize (GtkStyle * style)
1334 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1335 double shades[] = {1.15, 0.95, 0.896, 0.82, 0.7, 0.665, 0.475, 0.45, 0.4};
1336 CairoColor spot_color;
1337 CairoColor bg_normal;
1341 GTK_STYLE_CLASS (clearlooks_style_parent_class)->realize (style);
1343 contrast = CLEARLOOKS_RC_STYLE (style->rc_style)->contrast;
1345 /* Lighter to darker */
1346 ge_gdk_color_to_cairo (&style->bg[GTK_STATE_NORMAL], &bg_normal);
1348 for (i = 0; i < 9; i++)
1350 ge_shade_color (&bg_normal, (shades[i] < 1.0) ?
1351 (shades[i]/contrast) : (shades[i]*contrast),
1352 &clearlooks_style->colors.shade[i]);
1355 ge_gdk_color_to_cairo (&style->bg[GTK_STATE_SELECTED], &spot_color);
1357 /* Andrea Cimitan wants something like the following to handle dark themes.
1358 * However, these two lines are broken currently, as ge_hsb_from_color expects
1359 * a CairoColor and not GdkColor
1360 * ge_hsb_from_color (&style->bg[GTK_STATE_SELECTED], &hue_spot, &saturation_spot, &brightness_spot);
1361 * ge_hsb_from_color (&style->bg[GTK_STATE_NORMAL], &hue_bg, &saturation_bg, &brightness_bg);
1364 /* Here to place some checks for dark themes.
1365 * We should use a different shade value for spot[2]. */
1367 ge_shade_color (&spot_color, 1.25, &clearlooks_style->colors.spot[0]);
1368 ge_shade_color (&spot_color, 1.05, &clearlooks_style->colors.spot[1]);
1369 ge_shade_color (&spot_color, 0.65, &clearlooks_style->colors.spot[2]);
1373 ge_gdk_color_to_cairo (&style->fg[i], &clearlooks_style->colors.fg[i]);
1374 ge_gdk_color_to_cairo (&style->bg[i], &clearlooks_style->colors.bg[i]);
1375 ge_gdk_color_to_cairo (&style->base[i], &clearlooks_style->colors.base[i]);
1376 ge_gdk_color_to_cairo (&style->text[i], &clearlooks_style->colors.text[i]);
1381 clearlooks_style_draw_focus (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
1382 GdkRectangle *area, GtkWidget *widget, const gchar *detail,
1383 gint x, gint y, gint width, gint height)
1385 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1386 ClearlooksColors *colors = &clearlooks_style->colors;
1387 WidgetParameters params;
1388 FocusParameters focus;
1396 cr = gdk_cairo_create (window);
1398 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1401 params.corners = CR_CORNER_ALL;
1402 if (CHECK_HINT (GE_HINT_COMBOBOX_ENTRY))
1405 params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
1407 params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
1409 if (params.xthickness > 2)
1417 focus.has_color = FALSE;
1418 focus.interior = FALSE;
1419 focus.line_width = 1;
1425 gtk_widget_style_get (widget,
1426 "focus-line-width", &focus.line_width,
1427 "focus-line-pattern", &dash_list,
1428 "focus-padding", &focus.padding,
1429 "interior-focus", &focus.interior,
1433 focus.dash_list = dash_list;
1435 focus.dash_list = (guint8*) g_strdup ("\1\1");
1438 if (DETAIL("button"))
1440 if (CHECK_HINT (GE_HINT_TREEVIEW_HEADER))
1442 focus.type = CL_FOCUS_TREEVIEW_HEADER;
1446 GtkReliefStyle relief = GTK_RELIEF_NORMAL;
1447 /* Check for the shadow type. */
1448 if (widget && GTK_IS_BUTTON (widget))
1449 g_object_get (G_OBJECT (widget), "relief", &relief, NULL);
1451 if (relief == GTK_RELIEF_NORMAL)
1452 focus.type = CL_FOCUS_BUTTON;
1454 focus.type = CL_FOCUS_BUTTON_FLAT;
1456 /* This is a workaround for the bogus focus handling that
1457 * clearlooks has currently.
1458 * I truely dislike putting it here, but I guess it is better
1459 * then having such a visible bug. It should be removed in the
1460 * next unstable release cycle. -- Benjamin */
1461 if (ge_object_is_a (G_OBJECT (widget), "ButtonWidget"))
1462 focus.type = CL_FOCUS_LABEL;
1465 else if (detail && g_str_has_prefix (detail, "treeview"))
1467 /* Focus in a treeview, and that means a lot of different detail strings. */
1468 if (g_str_has_prefix (detail, "treeview-drop-indicator"))
1469 focus.type = CL_FOCUS_TREEVIEW_DND;
1471 focus.type = CL_FOCUS_TREEVIEW_ROW;
1473 if (g_str_has_suffix (detail, "left"))
1475 focus.continue_side = CL_CONT_RIGHT;
1477 else if (g_str_has_suffix (detail, "right"))
1479 focus.continue_side = CL_CONT_LEFT;
1481 else if (g_str_has_suffix (detail, "middle"))
1483 focus.continue_side = CL_CONT_LEFT | CL_CONT_RIGHT;
1487 /* This may either mean no continuation, or unknown ...
1488 * if it is unknown we assume it continues on both sides */
1489 gboolean row_ending_details = FALSE;
1491 /* Try to get the style property. */
1493 gtk_widget_style_get (widget,
1494 "row-ending-details", &row_ending_details,
1497 if (row_ending_details)
1498 focus.continue_side = CL_CONT_NONE;
1500 focus.continue_side = CL_CONT_LEFT | CL_CONT_RIGHT;
1504 else if (detail && g_str_has_prefix (detail, "trough") && CHECK_HINT (GE_HINT_SCALE))
1506 focus.type = CL_FOCUS_SCALE;
1508 else if (DETAIL("tab"))
1510 focus.type = CL_FOCUS_TAB;
1512 else if (detail && g_str_has_prefix (detail, "colorwheel"))
1514 if (DETAIL ("colorwheel_dark"))
1515 focus.type = CL_FOCUS_COLOR_WHEEL_DARK;
1517 focus.type = CL_FOCUS_COLOR_WHEEL_LIGHT;
1519 else if (DETAIL("checkbutton") || DETAIL("radiobutton"))
1521 focus.type = CL_FOCUS_LABEL; /* Let's call it "LABEL" :) */
1523 else if (CHECK_HINT (GE_HINT_TREEVIEW))
1525 focus.type = CL_FOCUS_TREEVIEW; /* Treeview without content is focused. */
1529 focus.type = CL_FOCUS_UNKNOWN; /* Custom widgets (Beagle) and something unknown */
1533 if (clearlooks_style->has_focus_color)
1535 ge_gdk_color_to_cairo (&clearlooks_style->focus_color, &focus.color);
1536 focus.has_color = TRUE;
1539 focus.color = colors->bg[GTK_STATE_SELECTED];
1541 STYLE_FUNCTION(draw_focus) (cr, colors, ¶ms, &focus, x, y, width, height);
1543 g_free (focus.dash_list);
1549 clearlooks_style_copy (GtkStyle * style, GtkStyle * src)
1551 ClearlooksStyle * cl_style = CLEARLOOKS_STYLE (style);
1552 ClearlooksStyle * cl_src = CLEARLOOKS_STYLE (src);
1554 cl_style->colors = cl_src->colors;
1555 cl_style->reliefstyle = cl_src->reliefstyle;
1556 cl_style->menubarstyle = cl_src->menubarstyle;
1557 cl_style->toolbarstyle = cl_src->toolbarstyle;
1558 cl_style->focus_color = cl_src->focus_color;
1559 cl_style->has_focus_color = cl_src->has_focus_color;
1560 cl_style->scrollbar_color = cl_src->scrollbar_color;
1561 cl_style->has_scrollbar_color = cl_src->has_scrollbar_color;
1562 cl_style->colorize_scrollbar = cl_src->colorize_scrollbar;
1563 cl_style->animation = cl_src->animation;
1564 cl_style->radius = cl_src->radius;
1565 cl_style->style = cl_src->style;
1567 GTK_STYLE_CLASS (clearlooks_style_parent_class)->copy (style, src);
1571 clearlooks_style_unrealize (GtkStyle * style)
1573 GTK_STYLE_CLASS (clearlooks_style_parent_class)->unrealize (style);
1577 set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent)
1580 guchar *data, *current;
1581 guint x, y, rowstride, height, width;
1583 g_return_val_if_fail (pixbuf != NULL, NULL);
1584 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
1586 /* Returns a copy of pixbuf with it's non-completely-transparent pixels to
1587 have an alpha level "alpha_percent" of their original value. */
1589 target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
1591 if (alpha_percent == 1.0)
1593 width = gdk_pixbuf_get_width (target);
1594 height = gdk_pixbuf_get_height (target);
1595 rowstride = gdk_pixbuf_get_rowstride (target);
1596 data = gdk_pixbuf_get_pixels (target);
1598 for (y = 0; y < height; y++)
1600 for (x = 0; x < width; x++)
1602 /* The "4" is the number of chars per pixel, in this case, RGBA,
1603 the 3 means "skip to the alpha" */
1604 current = data + (y * rowstride) + (x * 4) + 3;
1605 *(current) = (guchar) (*(current) * alpha_percent);
1613 scale_or_ref (GdkPixbuf *src,
1617 if (width == gdk_pixbuf_get_width (src) &&
1618 height == gdk_pixbuf_get_height (src))
1620 return g_object_ref (src);
1624 return gdk_pixbuf_scale_simple (src,
1626 GDK_INTERP_BILINEAR);
1631 clearlooks_style_draw_layout (GtkStyle * style,
1633 GtkStateType state_type,
1635 GdkRectangle * area,
1637 const gchar * detail, gint x, gint y, PangoLayout * layout)
1641 g_return_if_fail (GTK_IS_STYLE (style));
1642 g_return_if_fail (window != NULL);
1644 gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
1647 gdk_gc_set_clip_rectangle (gc, area);
1649 if (state_type == GTK_STATE_INSENSITIVE)
1651 ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style);
1652 ClearlooksColors *colors = &clearlooks_style->colors;
1654 WidgetParameters params;
1658 clearlooks_set_widget_parameters (widget, style, state_type, ¶ms);
1660 if (GTK_WIDGET_NO_WINDOW (widget))
1661 ge_shade_color (¶ms.parentbg, 1.2, &temp);
1663 ge_shade_color (&colors->bg[widget->state], 1.2, &temp);
1665 etched.red = (int) (temp.r * 65535);
1666 etched.green = (int) (temp.g * 65535);
1667 etched.blue = (int) (temp.b * 65535);
1669 gdk_draw_layout_with_colors (window, gc, x + 1, y + 1, layout, &etched, NULL);
1670 gdk_draw_layout (window, gc, x, y, layout);
1673 gdk_draw_layout (window, gc, x, y, layout);
1676 gdk_gc_set_clip_rectangle (gc, NULL);
1680 clearlooks_style_draw_render_icon (GtkStyle *style,
1681 const GtkIconSource *source,
1682 GtkTextDirection direction,
1692 GdkPixbuf *base_pixbuf;
1694 GtkSettings *settings;
1696 /* Oddly, style can be NULL in this function, because
1697 * GtkIconSet can be used without a style and if so
1698 * it uses this function.
1701 base_pixbuf = gtk_icon_source_get_pixbuf (source);
1703 g_return_val_if_fail (base_pixbuf != NULL, NULL);
1705 if (widget && gtk_widget_has_screen (widget))
1707 screen = gtk_widget_get_screen (widget);
1708 settings = gtk_settings_get_for_screen (screen);
1710 else if (style->colormap)
1712 screen = gdk_colormap_get_screen (style->colormap);
1713 settings = gtk_settings_get_for_screen (screen);
1717 settings = gtk_settings_get_default ();
1718 GTK_NOTE (MULTIHEAD,
1719 g_warning ("Using the default screen for gtk_default_render_icon()"));
1722 if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
1724 g_warning (G_STRLOC ": invalid icon size '%d'", size);
1728 /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
1731 if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
1732 scaled = scale_or_ref (base_pixbuf, width, height);
1734 scaled = g_object_ref (base_pixbuf);
1736 /* If the state was wildcarded, then generate a state. */
1737 if (gtk_icon_source_get_state_wildcarded (source))
1739 if (state == GTK_STATE_INSENSITIVE)
1741 stated = set_transparency (scaled, 0.3);
1742 gdk_pixbuf_saturate_and_pixelate (stated, stated, 0.1, FALSE);
1744 g_object_unref (scaled);
1746 else if (state == GTK_STATE_PRELIGHT)
1748 stated = gdk_pixbuf_copy (scaled);
1750 gdk_pixbuf_saturate_and_pixelate (scaled, stated, 1.2, FALSE);
1752 g_object_unref (scaled);
1766 clearlooks_style_register_types (GTypeModule *module)
1768 clearlooks_style_register_type (module);
1772 clearlooks_style_init (ClearlooksStyle * style)
1777 clearlooks_style_class_init (ClearlooksStyleClass * klass)
1779 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
1781 style_class->copy = clearlooks_style_copy;
1782 style_class->realize = clearlooks_style_realize;
1783 style_class->unrealize = clearlooks_style_unrealize;
1784 style_class->init_from_rc = clearlooks_style_init_from_rc;
1785 style_class->draw_handle = clearlooks_style_draw_handle;
1786 style_class->draw_slider = clearlooks_style_draw_slider;
1787 style_class->draw_shadow_gap = clearlooks_style_draw_shadow_gap;
1788 style_class->draw_focus = clearlooks_style_draw_focus;
1789 style_class->draw_box = clearlooks_style_draw_box;
1790 style_class->draw_shadow = clearlooks_style_draw_shadow;
1791 style_class->draw_box_gap = clearlooks_style_draw_box_gap;
1792 style_class->draw_extension = clearlooks_style_draw_extension;
1793 style_class->draw_option = clearlooks_style_draw_option;
1794 style_class->draw_check = clearlooks_style_draw_check;
1795 style_class->draw_flat_box = clearlooks_style_draw_flat_box;
1796 style_class->draw_vline = clearlooks_style_draw_vline;
1797 style_class->draw_hline = clearlooks_style_draw_hline;
1798 style_class->draw_resize_grip = clearlooks_style_draw_resize_grip;
1799 style_class->draw_tab = clearlooks_style_draw_tab;
1800 style_class->draw_arrow = clearlooks_style_draw_arrow;
1801 style_class->draw_layout = clearlooks_style_draw_layout;
1802 style_class->render_icon = clearlooks_style_draw_render_icon;
1804 clearlooks_register_style_classic (&klass->style_functions[CL_STYLE_CLASSIC],
1805 &klass->style_constants[CL_STYLE_CLASSIC]);
1807 klass->style_functions[CL_STYLE_GLOSSY] = klass->style_functions[CL_STYLE_CLASSIC];
1808 klass->style_constants[CL_STYLE_GLOSSY] = klass->style_constants[CL_STYLE_CLASSIC];
1809 clearlooks_register_style_glossy (&klass->style_functions[CL_STYLE_GLOSSY],
1810 &klass->style_constants[CL_STYLE_GLOSSY]);
1812 klass->style_functions[CL_STYLE_INVERTED] = klass->style_functions[CL_STYLE_CLASSIC];
1813 klass->style_constants[CL_STYLE_INVERTED] = klass->style_constants[CL_STYLE_CLASSIC];
1814 clearlooks_register_style_inverted (&klass->style_functions[CL_STYLE_INVERTED],
1815 &klass->style_constants[CL_STYLE_INVERTED]);
1817 klass->style_functions[CL_STYLE_GUMMY] = klass->style_functions[CL_STYLE_CLASSIC];
1818 klass->style_constants[CL_STYLE_GUMMY] = klass->style_constants[CL_STYLE_CLASSIC];
1819 clearlooks_register_style_gummy (&klass->style_functions[CL_STYLE_GUMMY],
1820 &klass->style_constants[CL_STYLE_GUMMY]);
1824 clearlooks_style_class_finalize (ClearlooksStyleClass *klass)