various fixes to MidiRegionView selection handling, key handling, drawing of ghost...
[ardour2.git] / libs / clearlooks-newer / support.c
blob6d4d8a286dfcae0cc177a8892b8e4b2b04b6e499
1 /* Clearlooks theme engine
2 * Copyright (C) 2005 Richard Stellingwerff.
3 * Copyright (C) 2007 Benjamin Berg <benjamin@sipsolutions.net>.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 #include "support.h"
24 void clearlooks_treeview_get_header_index (GtkTreeView *tv, GtkWidget *header,
25 gint *column_index, gint *columns,
26 gboolean *resizable)
28 GList *list, *list_start;
29 *column_index = *columns = 0;
30 list_start = list = gtk_tree_view_get_columns (tv);
34 GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(list->data);
35 if ( column->button == header )
37 *column_index = *columns;
38 *resizable = column->resizable;
40 if ( column->visible )
41 (*columns)++;
42 } while ((list = g_list_next(list)));
44 g_list_free (list_start);
47 void clearlooks_clist_get_header_index (GtkCList *clist, GtkWidget *button,
48 gint *column_index, gint *columns)
50 int i;
51 *columns = clist->columns;
53 for (i=0; i<*columns; i++)
55 if (clist->column[i].button == button)
57 *column_index = i;
58 break;
63 void
64 clearlooks_get_parent_bg (const GtkWidget *widget, CairoColor *color)
66 GtkStateType state_type;
67 const GtkWidget *parent;
68 GdkColor *gcolor;
70 if (widget == NULL)
71 return;
73 parent = widget->parent;
75 while (parent && GTK_WIDGET_NO_WINDOW (parent) && !((GTK_IS_NOTEBOOK (parent)) || (GTK_IS_TOOLBAR (parent))))
76 parent = parent->parent;
78 if (parent == NULL)
79 return;
81 state_type = GTK_WIDGET_STATE (parent);
83 gcolor = &parent->style->bg[state_type];
85 ge_gdk_color_to_cairo (gcolor, color);
88 ClearlooksStepper
89 clearlooks_scrollbar_get_stepper (GtkWidget *widget,
90 GdkRectangle *stepper)
92 ClearlooksStepper value = CL_STEPPER_UNKNOWN;
93 GdkRectangle tmp;
94 GdkRectangle check_rectangle;
95 GtkOrientation orientation;
97 if (!GE_IS_RANGE (widget))
98 return CL_STEPPER_UNKNOWN;
100 check_rectangle.x = widget->allocation.x;
101 check_rectangle.y = widget->allocation.y;
102 check_rectangle.width = stepper->width;
103 check_rectangle.height = stepper->height;
105 orientation = GTK_RANGE (widget)->orientation;
107 if (widget->allocation.x == -1 && widget->allocation.y == -1)
108 return CL_STEPPER_UNKNOWN;
110 if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
111 value = CL_STEPPER_A;
113 if (value == CL_STEPPER_UNKNOWN) /* Haven't found a match */
115 if (orientation == GTK_ORIENTATION_HORIZONTAL)
116 check_rectangle.x = widget->allocation.x + stepper->width;
117 else
118 check_rectangle.y = widget->allocation.y + stepper->height;
120 if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
121 value = CL_STEPPER_B;
124 if (value == CL_STEPPER_UNKNOWN) /* Still haven't found a match */
126 if (orientation == GTK_ORIENTATION_HORIZONTAL)
127 check_rectangle.x = widget->allocation.x + widget->allocation.width - (stepper->width * 2);
128 else
129 check_rectangle.y = widget->allocation.y + widget->allocation.height - (stepper->height * 2);
131 if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
132 value = CL_STEPPER_C;
135 if (value == CL_STEPPER_UNKNOWN) /* STILL haven't found a match */
137 if (orientation == GTK_ORIENTATION_HORIZONTAL)
138 check_rectangle.x = widget->allocation.x + widget->allocation.width - stepper->width;
139 else
140 check_rectangle.y = widget->allocation.y + widget->allocation.height - stepper->height;
142 if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
143 value = CL_STEPPER_D;
146 return value;
149 ClearlooksStepper
150 clearlooks_scrollbar_visible_steppers (GtkWidget *widget)
152 ClearlooksStepper steppers = 0;
154 if (!GE_IS_RANGE (widget))
155 return 0;
157 if (GTK_RANGE (widget)->has_stepper_a)
158 steppers |= CL_STEPPER_A;
160 if (GTK_RANGE (widget)->has_stepper_b)
161 steppers |= CL_STEPPER_B;
163 if (GTK_RANGE (widget)->has_stepper_c)
164 steppers |= CL_STEPPER_C;
166 if (GTK_RANGE (widget)->has_stepper_d)
167 steppers |= CL_STEPPER_D;
169 return steppers;
172 ClearlooksJunction
173 clearlooks_scrollbar_get_junction (GtkWidget *widget)
175 GtkAdjustment *adj;
176 ClearlooksJunction junction = CL_JUNCTION_NONE;
178 if (!GE_IS_RANGE (widget))
179 return CL_JUNCTION_NONE;
181 adj = GTK_RANGE (widget)->adjustment;
183 if (adj->value <= adj->lower &&
184 (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b))
186 junction |= CL_JUNCTION_BEGIN;
189 if (adj->value >= adj->upper - adj->page_size &&
190 (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d))
192 junction |= CL_JUNCTION_END;
195 return junction;
198 void
199 clearlooks_set_toolbar_parameters (ToolbarParameters *toolbar, GtkWidget *widget, GdkWindow *window, gint x, gint y)
201 toolbar->topmost = FALSE;
203 if (x == 0 && y == 0) {
204 if (widget && widget->allocation.x == 0 && widget->allocation.y == 0)
206 if (widget->window == window && GE_IS_TOOLBAR (widget))
208 toolbar->topmost = TRUE;
214 void
215 clearlooks_get_notebook_tab_position (GtkWidget *widget,
216 gboolean *start,
217 gboolean *end)
219 /* default value */
220 *start = TRUE;
221 *end = FALSE;
223 if (GE_IS_NOTEBOOK (widget)) {
224 gboolean found_tabs = FALSE;
225 gint i, n_pages;
226 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
228 /* got a notebook, so walk over all the tabs and decide based
229 * on that ...
230 * It works like this:
231 * - If there is any visible tab that is expanded, set both.
232 * - Set start/end if there is any visible tab that is at
233 * the start/end.
234 * - If one has the child_visibility set to false, arrows
235 * are present; so none
236 * The heuristic falls over if there is a notebook that just
237 * happens to fill up all the available space. ie. All tabs
238 * are left aligned, but it does not require scrolling.
239 * (a more complex heuristic could calculate the tabs width
240 * and add them all up) */
242 n_pages = gtk_notebook_get_n_pages (notebook);
243 for (i = 0; i < n_pages; i++) {
244 GtkWidget *tab_child;
245 GtkWidget *tab_label;
246 gboolean expand;
247 GtkPackType pack_type;
249 tab_child = gtk_notebook_get_nth_page (notebook, i);
251 /* Skip invisible tabs */
252 tab_label = gtk_notebook_get_tab_label (notebook, tab_child);
253 if (!tab_label || !GTK_WIDGET_VISIBLE (tab_label))
254 continue;
255 /* This is the same what the notebook does internally. */
256 if (tab_label && !gtk_widget_get_child_visible (tab_label)) {
257 /* One child is hidden because scroll arrows are present.
258 * So both corners are rounded. */
259 *start = FALSE;
260 *end = FALSE;
261 return;
264 gtk_notebook_query_tab_label_packing (notebook, tab_child,
265 &expand,
266 NULL, /* don't need fill */
267 &pack_type);
269 if (!found_tabs) {
270 found_tabs = TRUE;
271 *start = FALSE;
272 *end = FALSE;
275 if (expand) {
276 *start = TRUE;
277 *end = TRUE;
278 } else if (pack_type == GTK_PACK_START) {
279 *start = TRUE;
280 } else {
281 *end = TRUE;