source: trunk/third/gtk/gtk/gtkruler.c @ 14482

Revision 14482, 10.1 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
Line 
1/* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
22 * file for a list of people on the GTK+ Team.  See the ChangeLog
23 * files for a list of changes.  These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27#include "gtkruler.h"
28
29enum {
30  ARG_0,
31  ARG_LOWER,
32  ARG_UPPER,
33  ARG_POSITION,
34  ARG_MAX_SIZE
35};
36
37static void gtk_ruler_class_init    (GtkRulerClass  *klass);
38static void gtk_ruler_init          (GtkRuler       *ruler);
39static void gtk_ruler_realize       (GtkWidget      *widget);
40static void gtk_ruler_unrealize     (GtkWidget      *widget);
41static void gtk_ruler_size_allocate (GtkWidget      *widget,
42                                     GtkAllocation  *allocation);
43static gint gtk_ruler_expose        (GtkWidget      *widget,
44                                     GdkEventExpose *event);
45static void gtk_ruler_make_pixmap   (GtkRuler       *ruler);
46static void gtk_ruler_set_arg       (GtkObject      *object,
47                                     GtkArg         *arg,
48                                     guint           arg_id);
49static void gtk_ruler_get_arg       (GtkObject      *object,
50                                     GtkArg         *arg,
51                                     guint           arg_id);
52
53static GtkWidgetClass *parent_class;
54
55static const GtkRulerMetric ruler_metrics[] =
56{
57  {"Pixels", "Pi", 1.0, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }},
58  {"Inches", "In", 72.0, { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 }, { 1, 2, 4, 8, 16 }},
59  {"Centimeters", "Cn", 28.35, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }},
60};
61
62
63GtkType
64gtk_ruler_get_type (void)
65{
66  static GtkType ruler_type = 0;
67
68  if (!ruler_type)
69    {
70      static const GtkTypeInfo ruler_info =
71      {
72        "GtkRuler",
73        sizeof (GtkRuler),
74        sizeof (GtkRulerClass),
75        (GtkClassInitFunc) gtk_ruler_class_init,
76        (GtkObjectInitFunc) gtk_ruler_init,
77        /* reserved_1 */ NULL,
78        /* reserved_2 */ NULL,
79        (GtkClassInitFunc) NULL,
80      };
81
82      ruler_type = gtk_type_unique (GTK_TYPE_WIDGET, &ruler_info);
83    }
84
85  return ruler_type;
86}
87
88static void
89gtk_ruler_class_init (GtkRulerClass *class)
90{
91  GtkObjectClass *object_class;
92  GtkWidgetClass *widget_class;
93
94  object_class = (GtkObjectClass*) class;
95  widget_class = (GtkWidgetClass*) class;
96
97  parent_class = gtk_type_class (GTK_TYPE_WIDGET);
98 
99  object_class->set_arg = gtk_ruler_set_arg;
100  object_class->get_arg = gtk_ruler_get_arg;
101
102  widget_class->realize = gtk_ruler_realize;
103  widget_class->unrealize = gtk_ruler_unrealize;
104  widget_class->size_allocate = gtk_ruler_size_allocate;
105  widget_class->expose_event = gtk_ruler_expose;
106
107  class->draw_ticks = NULL;
108  class->draw_pos = NULL;
109
110  gtk_object_add_arg_type ("GtkRuler::lower", GTK_TYPE_FLOAT,
111                           GTK_ARG_READWRITE, ARG_LOWER);
112  gtk_object_add_arg_type ("GtkRuler::upper", GTK_TYPE_FLOAT,
113                           GTK_ARG_READWRITE, ARG_UPPER);
114  gtk_object_add_arg_type ("GtkRuler::position", GTK_TYPE_FLOAT,
115                           GTK_ARG_READWRITE, ARG_POSITION);
116  gtk_object_add_arg_type ("GtkRuler::max_size", GTK_TYPE_FLOAT,
117                           GTK_ARG_READWRITE, ARG_MAX_SIZE);
118}
119
120static void
121gtk_ruler_init (GtkRuler *ruler)
122{
123  ruler->backing_store = NULL;
124  ruler->non_gr_exp_gc = NULL;
125  ruler->xsrc = 0;
126  ruler->ysrc = 0;
127  ruler->slider_size = 0;
128  ruler->lower = 0;
129  ruler->upper = 0;
130  ruler->position = 0;
131  ruler->max_size = 0;
132
133  gtk_ruler_set_metric (ruler, GTK_PIXELS);
134}
135
136static void
137gtk_ruler_set_arg (GtkObject  *object,
138                   GtkArg     *arg,
139                   guint       arg_id)
140{
141  GtkRuler *ruler = GTK_RULER (object);
142
143  switch (arg_id)
144    {
145    case ARG_LOWER:
146      gtk_ruler_set_range (ruler, GTK_VALUE_FLOAT (*arg), ruler->upper,
147                           ruler->position, ruler->max_size);
148      break;
149    case ARG_UPPER:
150      gtk_ruler_set_range (ruler, ruler->lower, GTK_VALUE_FLOAT (*arg),
151                           ruler->position, ruler->max_size);
152      break;
153    case ARG_POSITION:
154      gtk_ruler_set_range (ruler, ruler->lower, ruler->upper,
155                           GTK_VALUE_FLOAT (*arg), ruler->max_size);
156      break;
157    case ARG_MAX_SIZE:
158      gtk_ruler_set_range (ruler, ruler->lower, ruler->upper,
159                           ruler->position,  GTK_VALUE_FLOAT (*arg));
160      break;
161    }
162}
163
164static void
165gtk_ruler_get_arg (GtkObject  *object,
166                   GtkArg     *arg,
167                   guint       arg_id)
168{
169  GtkRuler *ruler = GTK_RULER (object);
170 
171  switch (arg_id)
172    {
173    case ARG_LOWER:
174      GTK_VALUE_FLOAT (*arg) = ruler->lower;
175      break;
176    case ARG_UPPER:
177      GTK_VALUE_FLOAT (*arg) = ruler->upper;
178      break;
179    case ARG_POSITION:
180      GTK_VALUE_FLOAT (*arg) = ruler->position;
181      break;
182    case ARG_MAX_SIZE:
183      GTK_VALUE_FLOAT (*arg) = ruler->max_size;
184      break;
185    default:
186      arg->type = GTK_TYPE_INVALID;
187      break;
188    }
189}
190
191void
192gtk_ruler_set_metric (GtkRuler      *ruler,
193                      GtkMetricType  metric)
194{
195  g_return_if_fail (ruler != NULL);
196  g_return_if_fail (GTK_IS_RULER (ruler));
197
198  ruler->metric = (GtkRulerMetric *) &ruler_metrics[metric];
199
200  if (GTK_WIDGET_DRAWABLE (ruler))
201    gtk_widget_queue_draw (GTK_WIDGET (ruler));
202}
203
204void
205gtk_ruler_set_range (GtkRuler *ruler,
206                     gfloat    lower,
207                     gfloat    upper,
208                     gfloat    position,
209                     gfloat    max_size)
210{
211  g_return_if_fail (ruler != NULL);
212  g_return_if_fail (GTK_IS_RULER (ruler));
213
214  ruler->lower = lower;
215  ruler->upper = upper;
216  ruler->position = position;
217  ruler->max_size = max_size;
218
219  if (GTK_WIDGET_DRAWABLE (ruler))
220    gtk_widget_queue_draw (GTK_WIDGET (ruler));
221}
222
223void
224gtk_ruler_draw_ticks (GtkRuler *ruler)
225{
226  g_return_if_fail (ruler != NULL);
227  g_return_if_fail (GTK_IS_RULER (ruler));
228
229  if (GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_ticks)
230    (* GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_ticks) (ruler);
231}
232
233void
234gtk_ruler_draw_pos (GtkRuler *ruler)
235{
236  g_return_if_fail (ruler != NULL);
237  g_return_if_fail (GTK_IS_RULER (ruler));
238
239  if (GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_pos)
240    (* GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_pos) (ruler);
241}
242
243
244static void
245gtk_ruler_realize (GtkWidget *widget)
246{
247  GtkRuler *ruler;
248  GdkWindowAttr attributes;
249  gint attributes_mask;
250
251  g_return_if_fail (widget != NULL);
252  g_return_if_fail (GTK_IS_RULER (widget));
253
254  ruler = GTK_RULER (widget);
255  GTK_WIDGET_SET_FLAGS (ruler, GTK_REALIZED);
256
257  attributes.window_type = GDK_WINDOW_CHILD;
258  attributes.x = widget->allocation.x;
259  attributes.y = widget->allocation.y;
260  attributes.width = widget->allocation.width;
261  attributes.height = widget->allocation.height;
262  attributes.wclass = GDK_INPUT_OUTPUT;
263  attributes.visual = gtk_widget_get_visual (widget);
264  attributes.colormap = gtk_widget_get_colormap (widget);
265  attributes.event_mask = gtk_widget_get_events (widget);
266  attributes.event_mask |= (GDK_EXPOSURE_MASK |
267                            GDK_POINTER_MOTION_MASK |
268                            GDK_POINTER_MOTION_HINT_MASK);
269
270  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
271
272  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
273  gdk_window_set_user_data (widget->window, ruler);
274
275  widget->style = gtk_style_attach (widget->style, widget->window);
276  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
277
278  gtk_ruler_make_pixmap (ruler);
279}
280
281static void
282gtk_ruler_unrealize (GtkWidget *widget)
283{
284  GtkRuler *ruler;
285
286  g_return_if_fail (widget != NULL);
287  g_return_if_fail (GTK_IS_RULER (widget));
288
289  ruler = GTK_RULER (widget);
290
291  if (ruler->backing_store)
292    gdk_pixmap_unref (ruler->backing_store);
293  if (ruler->non_gr_exp_gc)
294    gdk_gc_destroy (ruler->non_gr_exp_gc);
295
296  ruler->backing_store = NULL;
297  ruler->non_gr_exp_gc = NULL;
298
299  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
300    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
301}
302
303static void
304gtk_ruler_size_allocate (GtkWidget     *widget,
305                         GtkAllocation *allocation)
306{
307  GtkRuler *ruler;
308
309  g_return_if_fail (widget != NULL);
310  g_return_if_fail (GTK_IS_RULER (widget));
311
312  ruler = GTK_RULER (widget);
313  widget->allocation = *allocation;
314
315  if (GTK_WIDGET_REALIZED (widget))
316    {
317      gdk_window_move_resize (widget->window,
318                              allocation->x, allocation->y,
319                              allocation->width, allocation->height);
320
321      gtk_ruler_make_pixmap (ruler);
322    }
323}
324
325static gint
326gtk_ruler_expose (GtkWidget      *widget,
327                  GdkEventExpose *event)
328{
329  GtkRuler *ruler;
330
331  g_return_val_if_fail (widget != NULL, FALSE);
332  g_return_val_if_fail (GTK_IS_RULER (widget), FALSE);
333  g_return_val_if_fail (event != NULL, FALSE);
334
335  if (GTK_WIDGET_DRAWABLE (widget))
336    {
337      ruler = GTK_RULER (widget);
338
339      gtk_ruler_draw_ticks (ruler);
340     
341      gdk_draw_pixmap (widget->window,
342                       ruler->non_gr_exp_gc,
343                       ruler->backing_store,
344                       0, 0, 0, 0,
345                       widget->allocation.width,
346                       widget->allocation.height);
347     
348      gtk_ruler_draw_pos (ruler);
349    }
350
351  return FALSE;
352}
353
354static void
355gtk_ruler_make_pixmap (GtkRuler *ruler)
356{
357  GtkWidget *widget;
358  gint width;
359  gint height;
360
361  widget = GTK_WIDGET (ruler);
362
363  if (ruler->backing_store)
364    {
365      gdk_window_get_size (ruler->backing_store, &width, &height);
366      if ((width == widget->allocation.width) &&
367          (height == widget->allocation.height))
368        return;
369
370      gdk_pixmap_unref (ruler->backing_store);
371    }
372
373  ruler->backing_store = gdk_pixmap_new (widget->window,
374                                         widget->allocation.width,
375                                         widget->allocation.height,
376                                         -1);
377
378  ruler->xsrc = 0;
379  ruler->ysrc = 0;
380
381  if (!ruler->non_gr_exp_gc)
382    {
383      ruler->non_gr_exp_gc = gdk_gc_new (widget->window);
384      gdk_gc_set_exposures (ruler->non_gr_exp_gc, FALSE);
385    }
386}
Note: See TracBrowser for help on using the repository browser.