source: trunk/third/gtk-engines/redmond95/redmond_style.c @ 18625

Revision 18625, 15.1 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18624, which included commits to RCS files with non-trunk default branches.
Line 
1#include "redmond_style.h"
2
3#include <math.h>
4#include <string.h>
5#include <gtk/gtk.h>
6
7/* Default values, not normally used
8 */
9static GtkRequisition default_option_indicator_size = { 9, 8 };
10static GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
11
12static GtkStyleClass *parent_class;
13
14typedef enum {
15  CHECK_AA,
16  CHECK_BASE,
17  CHECK_BLACK,
18  CHECK_DARK,
19  CHECK_LIGHT,
20  CHECK_MID,
21  CHECK_TEXT,
22  RADIO_BASE,
23  RADIO_BLACK,
24  RADIO_DARK,
25  RADIO_LIGHT,
26  RADIO_MID,
27  RADIO_TEXT
28} Part;
29
30#define PART_SIZE 13
31
32static char check_aa_bits[] = {
33 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
34 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
35static char check_base_bits[] = {
36 0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
37 0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00};
38static char check_black_bits[] = {
39 0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
40 0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00};
41static char check_dark_bits[] = {
42 0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
43 0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};
44static char check_light_bits[] = {
45 0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
46 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f};
47static char check_mid_bits[] = {
48 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
49 0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00};
50static char check_text_bits[] = {
51 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x88,0x03,0xd8,0x01,0xf8,
52 0x00,0x70,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
53static char radio_base_bits[] = {
54 0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
55 0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00};
56static char radio_black_bits[] = {
57 0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
58 0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
59static char radio_dark_bits[] = {
60 0xf0,0x01,0x0c,0x06,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
61 0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
62static char radio_light_bits[] = {
63 0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
64 0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x0c,0x06,0xf0,0x01};
65static char radio_mid_bits[] = {
66 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
67 0x08,0x00,0x08,0x00,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00};
68static char radio_text_bits[] = {
69 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0,
70 0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
71
72static struct {
73  char      *bits;
74  GdkBitmap *bmap;
75} parts[] = {
76  { check_aa_bits, NULL },
77  { check_base_bits, NULL },
78  { check_black_bits, NULL },
79  { check_dark_bits, NULL },
80  { check_light_bits, NULL },
81  { check_mid_bits, NULL },
82  { check_text_bits, NULL },
83  { radio_base_bits, NULL },
84  { radio_black_bits, NULL },
85  { radio_dark_bits, NULL },
86  { radio_light_bits, NULL },
87  { radio_mid_bits, NULL },
88  { radio_text_bits, NULL }
89};
90
91static gboolean
92sanitize_size (GdkWindow *window,
93               gint      *width,
94               gint      *height)
95{
96  gboolean set_bg = FALSE;
97
98  if ((*width == -1) && (*height == -1))
99    {
100      set_bg = GDK_IS_WINDOW (window);
101      gdk_window_get_size (window, width, height);
102    }
103  else if (*width == -1)
104    gdk_window_get_size (window, width, NULL);
105  else if (*height == -1)
106    gdk_window_get_size (window, NULL, height);
107
108  return set_bg;
109}
110
111static void
112draw_part (GdkDrawable  *drawable,
113           GdkGC        *gc,
114           GdkRectangle *area,
115           gint          x,
116           gint          y,
117           Part          part)
118{
119  if (area)
120    gdk_gc_set_clip_rectangle (gc, area);
121 
122  if (!parts[part].bmap)
123      parts[part].bmap = gdk_bitmap_create_from_data (drawable,
124                                                      parts[part].bits,
125                                                      PART_SIZE, PART_SIZE);
126
127  gdk_gc_set_ts_origin (gc, x, y);
128  gdk_gc_set_stipple (gc, parts[part].bmap);
129  gdk_gc_set_fill (gc, GDK_STIPPLED);
130
131  gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
132
133  gdk_gc_set_fill (gc, GDK_SOLID);
134
135  if (area)
136    gdk_gc_set_clip_rectangle (gc, NULL);
137}
138
139static void
140draw_check(GtkStyle      *style,
141           GdkWindow     *window,
142           GtkStateType   state,
143           GtkShadowType  shadow,
144           GdkRectangle  *area,
145           GtkWidget     *widget,
146           const gchar   *detail,
147           gint           x,
148           gint           y,
149           gint           width,
150           gint           height)
151{
152  x -= (1 + PART_SIZE - width) / 2;
153  y -= (1 + PART_SIZE - height) / 2;
154     
155  if (detail && strcmp (detail, "check") == 0)  /* Menu item */
156    {
157      if (shadow == GTK_SHADOW_IN)
158        {
159          draw_part (window, style->black_gc, area, x, y, CHECK_TEXT);
160          draw_part (window, style->dark_gc[state], area, x, y, CHECK_AA);
161        }
162    }
163  else
164    {
165      draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
166      draw_part (window, style->dark_gc[state], area, x, y, CHECK_DARK);
167      draw_part (window, style->mid_gc[state], area, x, y, CHECK_MID);
168      draw_part (window, style->light_gc[state], area, x, y, CHECK_LIGHT);
169      draw_part (window, style->base_gc[state], area, x, y, CHECK_BASE);
170     
171      if (shadow == GTK_SHADOW_IN)
172        {
173          draw_part (window, style->text_gc[state], area, x, y, CHECK_TEXT);
174          draw_part (window, style->text_aa_gc[state], area, x, y, CHECK_AA);
175        }
176    }
177}
178
179static void
180draw_option(GtkStyle      *style,
181            GdkWindow     *window,
182            GtkStateType   state,
183            GtkShadowType  shadow,
184            GdkRectangle  *area,
185            GtkWidget     *widget,
186            const gchar   *detail,
187            gint           x,
188            gint           y,
189            gint           width,
190            gint           height)
191{
192  x -= (1 + PART_SIZE - width) / 2;
193  y -= (1 + PART_SIZE - height) / 2;
194     
195  if (detail && strcmp (detail, "option") == 0) /* Menu item */
196    {
197      if (shadow == GTK_SHADOW_IN)
198        draw_part (window, style->fg_gc[state], area, x, y, RADIO_TEXT);
199    }
200  else
201    {
202      draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
203      draw_part (window, style->dark_gc[state], area, x, y, RADIO_DARK);
204      draw_part (window, style->mid_gc[state], area, x, y, RADIO_MID);
205      draw_part (window, style->light_gc[state], area, x, y, RADIO_LIGHT);
206      draw_part (window, style->base_gc[state], area, x, y, RADIO_BASE);
207     
208      if (shadow == GTK_SHADOW_IN)
209        draw_part (window, style->text_gc[state], area, x, y, RADIO_TEXT);
210    }
211}
212
213static void
214draw_varrow (GdkWindow     *window,
215             GdkGC         *gc,
216             GtkShadowType  shadow_type,
217             GdkRectangle  *area,
218             GtkArrowType   arrow_type,
219             gint           x,
220             gint           y,
221             gint           width,
222             gint           height)
223{
224  gint steps, extra;
225  gint y_start, y_increment;
226  gint i;
227
228  if (area)
229    gdk_gc_set_clip_rectangle (gc, area);
230 
231  width = width + width % 2 - 1;        /* Force odd */
232 
233  steps = 1 + width / 2;
234
235  extra = height - steps;
236
237  if (arrow_type == GTK_ARROW_DOWN)
238    {
239      y_start = y;
240      y_increment = 1;
241    }
242  else
243    {
244      y_start = y + height - 1;
245      y_increment = -1;
246    }
247
248#if 0
249  for (i = 0; i < extra; i++)
250    {
251      gdk_draw_line (window, gc,
252                     x,              y_start + i * y_increment,
253                     x + width - 1,  y_start + i * y_increment);
254    }
255#endif
256  for (i = extra; i < height; i++)
257    {
258      gdk_draw_line (window, gc,
259                     x + (i - extra),              y_start + i * y_increment,
260                     x + width - (i - extra) - 1,  y_start + i * y_increment);
261    }
262 
263
264  if (area)
265    gdk_gc_set_clip_rectangle (gc, NULL);
266}
267
268static void
269draw_harrow (GdkWindow     *window,
270             GdkGC         *gc,
271             GtkShadowType  shadow_type,
272             GdkRectangle  *area,
273             GtkArrowType   arrow_type,
274             gint           x,
275             gint           y,
276             gint           width,
277             gint           height)
278{
279  gint steps, extra;
280  gint x_start, x_increment;
281  gint i;
282
283  if (area)
284    gdk_gc_set_clip_rectangle (gc, area);
285 
286  height = height + height % 2 - 1;     /* Force odd */
287 
288  steps = 1 + height / 2;
289
290  extra = width - steps;
291
292  if (arrow_type == GTK_ARROW_RIGHT)
293    {
294      x_start = x;
295      x_increment = 1;
296    }
297  else
298    {
299      x_start = x + width - 1;
300      x_increment = -1;
301    }
302
303#if 0
304  for (i = 0; i < extra; i++)
305    {
306      gdk_draw_line (window, gc,
307                     x_start + i * x_increment, y,
308                     x_start + i * x_increment, y + height - 1);
309    }
310#endif
311  for (i = extra; i < width; i++)
312    {
313      gdk_draw_line (window, gc,
314                     x_start + i * x_increment, y + (i - extra),
315                     x_start + i * x_increment, y + height - (i - extra) - 1);
316    }
317 
318
319  if (area)
320    gdk_gc_set_clip_rectangle (gc, NULL);
321}
322
323static void
324draw_arrow (GtkStyle      *style,
325            GdkWindow     *window,
326            GtkStateType   state,
327            GtkShadowType  shadow,
328            GdkRectangle  *area,
329            GtkWidget     *widget,
330            const gchar   *detail,
331            GtkArrowType   arrow_type,
332            gboolean       fill,
333            gint           x,
334            gint           y,
335            gint           width,
336            gint           height)
337{
338  sanitize_size (window, &width, &height);
339 
340  if (detail && strcmp (detail, "spinbutton") == 0)
341    {
342      x += (width - 7) / 2;
343
344      if (arrow_type == GTK_ARROW_UP)
345        y += (height - 4) / 2;
346      else
347        y += (1 + height - 4) / 2;
348
349      draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
350                   x, y, 7, 4);
351    }
352  else if (detail && strcmp (detail, "vscrollbar") == 0)
353    {
354      parent_class->draw_box (style, window, state, shadow, area,
355                              widget, detail, x, y, width, height);
356     
357      x += (width - 7) / 2;
358      y += (height - 5) / 2;
359
360      draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
361                   x, y, 7, 5);
362     
363    }
364  else if (detail && strcmp (detail, "hscrollbar") == 0)
365    {
366      parent_class->draw_box (style, window, state, shadow, area,
367                              widget, detail, x, y, width, height);
368     
369      y += (height - 7) / 2;
370      x += (width - 5) / 2;
371
372      draw_harrow (window, style->fg_gc[state], shadow, area, arrow_type,
373                   x, y, 5, 7);
374    }
375  else
376    {
377      if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
378        {
379          x += (width - 7) / 2;
380          y += (height - 5) / 2;
381         
382          draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
383                       x, y, 7, 5);
384        }
385      else
386        {
387          x += (width - 5) / 2;
388          y += (height - 7) / 2;
389         
390          draw_harrow (window, style->fg_gc[state], shadow, area, arrow_type,
391                       x, y, 5, 7);
392        }
393    }
394}
395
396static void
397option_menu_get_props (GtkWidget      *widget,
398                       GtkRequisition *indicator_size,
399                       GtkBorder      *indicator_spacing)
400{
401  GtkRequisition *tmp_size = NULL;
402  GtkBorder *tmp_spacing = NULL;
403 
404  if (widget)
405    gtk_widget_style_get (widget,
406                          "indicator_size", &tmp_size,
407                          "indicator_spacing", &tmp_spacing,
408                          NULL);
409
410  if (tmp_size)
411    {
412      *indicator_size = *tmp_size;
413      g_free (tmp_size);
414    }
415  else
416    *indicator_size = default_option_indicator_size;
417
418  if (tmp_spacing)
419    {
420      *indicator_spacing = *tmp_spacing;
421      g_free (tmp_spacing);
422    }
423  else
424    *indicator_spacing = default_option_indicator_spacing;
425}
426
427static void
428draw_box (GtkStyle      *style,
429          GdkWindow     *window,
430          GtkStateType   state_type,
431          GtkShadowType  shadow_type,
432          GdkRectangle  *area,
433          GtkWidget     *widget,
434          const gchar   *detail,
435          gint           x,
436          gint           y,
437          gint           width,
438          gint           height)
439{
440  if (detail && strcmp (detail, "menuitem") == 0)
441    shadow_type = GTK_SHADOW_NONE;
442 
443  if ((detail && strcmp (detail, "trough") == 0) &&
444      !(widget && GTK_IS_PROGRESS_BAR (widget)))
445    {
446      GdkGCValues gc_values;
447      GdkGC *gc;
448      GdkPixmap *pixmap;
449
450      sanitize_size (window, &width, &height);
451         
452      pixmap = gdk_pixmap_new (window, 2, 2, -1);
453
454      gdk_draw_point (pixmap, style->bg_gc[GTK_STATE_NORMAL], 0, 0);
455      gdk_draw_point (pixmap, style->bg_gc[GTK_STATE_NORMAL], 1, 1);
456      gdk_draw_point (pixmap, style->light_gc[GTK_STATE_NORMAL], 1, 0);
457      gdk_draw_point (pixmap, style->light_gc[GTK_STATE_NORMAL], 0, 1);
458
459      gc_values.fill = GDK_TILED;
460      gc_values.tile = pixmap;
461      gc_values.ts_x_origin = x;
462      gc_values.ts_y_origin = y;
463      gc = gdk_gc_new_with_values (window, &gc_values,
464                                   GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN | GDK_GC_FILL | GDK_GC_TILE);
465
466      if (area)
467        gdk_gc_set_clip_rectangle (gc, area);
468     
469      gdk_draw_rectangle (window, gc, TRUE, x, y, width, height);
470
471      gdk_gc_unref (gc);
472      gdk_pixmap_unref (pixmap);
473     
474      return;
475    }
476     
477  parent_class->draw_box (style, window, state_type, shadow_type, area,
478                          widget, detail, x, y, width, height);
479
480  if (detail && strcmp (detail, "optionmenu") == 0)
481    {
482      GtkRequisition indicator_size;
483      GtkBorder indicator_spacing;
484      gint vline_x;
485
486      option_menu_get_props (widget, &indicator_size, &indicator_spacing);
487
488      sanitize_size (window, &width, &height);
489 
490      if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
491        vline_x = x + indicator_size.width + indicator_spacing.left + indicator_spacing.right;
492      else
493        vline_x = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
494
495      parent_class->draw_vline (style, window, state_type, area, widget,
496                                detail,
497                                y + style->ythickness + 1,
498                                y + height - style->ythickness - 3,
499                                vline_x);
500    }
501}
502
503static void
504draw_tab (GtkStyle      *style,
505          GdkWindow     *window,
506          GtkStateType   state,
507          GtkShadowType  shadow,
508          GdkRectangle  *area,
509          GtkWidget     *widget,
510          const gchar   *detail,
511          gint           x,
512          gint           y,
513          gint           width,
514          gint           height)
515{
516  GtkRequisition indicator_size;
517  GtkBorder indicator_spacing;
518 
519  gint arrow_height;
520 
521  g_return_if_fail (style != NULL);
522  g_return_if_fail (window != NULL);
523
524  if (widget)
525    gtk_widget_style_get (widget, "indicator_size", &indicator_size, NULL);
526
527  option_menu_get_props (widget, &indicator_size, &indicator_spacing);
528
529  x += (width - indicator_size.width) / 2;
530  arrow_height = (indicator_size.width + 1) / 2;
531 
532  y += (height - arrow_height) / 2;
533
534  draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
535               x, y, indicator_size.width, arrow_height);
536}
537
538static void
539redmond_style_init (RedmondStyle *style)
540{
541}
542
543static void
544redmond_style_class_init (RedmondStyleClass *klass)
545{
546  GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
547
548  parent_class = g_type_class_peek_parent (klass);
549
550  style_class->draw_arrow = draw_arrow;
551  style_class->draw_box = draw_box;
552  style_class->draw_check = draw_check;
553  style_class->draw_option = draw_option;
554  style_class->draw_tab = draw_tab;
555}
556
557GType redmond_type_style = 0;
558
559void
560redmond_style_register_type (GTypeModule *module)
561{
562  static const GTypeInfo object_info =
563  {
564    sizeof (RedmondStyleClass),
565    (GBaseInitFunc) NULL,
566    (GBaseFinalizeFunc) NULL,
567    (GClassInitFunc) redmond_style_class_init,
568    NULL,           /* class_finalize */
569    NULL,           /* class_data */
570    sizeof (RedmondStyle),
571    0,              /* n_preallocs */
572    (GInstanceInitFunc) redmond_style_init,
573  };
574 
575  redmond_type_style = g_type_module_register_type (module,
576                                                   GTK_TYPE_STYLE,
577                                                   "Redmond95Style",
578                                                   &object_info, 0);
579}
Note: See TracBrowser for help on using the repository browser.