Statistics
| Revision:

root / src / gtkshruler.c @ 880

History | View | Annotate | Download (5.5 kB)

1
/* GtkSHRuler
2
 *
3
 *  Copyright (C) 2000-2005 Alfons Hoogervorst & The Sylpheed Claws Team
4
 *
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.
9
 *
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.
14
 *
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.
19
 */
20
 
21
/* I derived this class from hruler. S in HRuler could be read as
22
 * Sylpheed (sylpheed.good-day.net), but also [S]ettable HRuler.
23
 * I basically ripped apart the draw_ticks member of HRuler; it
24
 * now draws the ticks at ruler->max_size. so gtk_ruler_set_range's
25
 * last parameter has the distance between two ticks (which is
26
 * the width of the fixed font character!
27
 * 
28
 * -- Alfons
29
 */
30
31
#include <math.h>
32
#include <stdio.h>
33
#include <string.h>
34
#include <gtk/gtkhruler.h>
35
#include "gtkshruler.h"
36
37
#define RULER_HEIGHT          14
38
#define MINIMUM_INCR          5
39
#define MAXIMUM_SUBDIVIDE     5
40
#define MAXIMUM_SCALES        10
41
42
#define ROUND(x) ((int) ((x) + 0.5))
43
44
static void gtk_shruler_class_init           (GtkSHRulerClass *klass);
45
static void gtk_shruler_init                 (GtkSHRuler      *hruler);
46
static void gtk_shruler_draw_ticks         (GtkRuler        *ruler);
47
#if 0
48
static void gtk_shruler_draw_pos              (GtkRuler        *ruler);
49
#endif
50
51
GType
52
gtk_shruler_get_type(void)
53
{
54
        static GType shruler_type = 0;
55
56
          if ( !shruler_type ) {
57
                   static const GTypeInfo shruler_info = {
58
                        sizeof (GtkSHRulerClass),
59
60
                        (GBaseInitFunc) NULL,
61
                        (GBaseFinalizeFunc) NULL,
62
63
                        (GClassInitFunc) gtk_shruler_class_init,
64
                        (GClassFinalizeFunc) NULL,
65
                        NULL,        /* class_data */
66
67
                        sizeof (GtkSHRuler),
68
                        0,        /* n_preallocs */
69
                        (GInstanceInitFunc) gtk_shruler_init,
70
                };
71
                /* inherit from GtkHRuler */
72
                shruler_type = g_type_register_static (GTK_TYPE_HRULER, "GtkSHRuler", &shruler_info, (GTypeFlags)0);
73
        }
74
        return shruler_type;
75
}
76
77
static void
78
gtk_shruler_class_init(GtkSHRulerClass * klass)
79
{
80
         GtkWidgetClass * widget_class;
81
          GtkRulerClass * hruler_class;
82
83
          widget_class = (GtkWidgetClass*) klass;
84
          hruler_class = (GtkRulerClass*) klass;
85
86
        /* just neglect motion notify events */
87
          widget_class->motion_notify_event = NULL /* gtk_shruler_motion_notify */;
88
89
          /* we want the old ruler draw ticks... */
90
          /* ruler_class->draw_ticks = gtk_hruler_draw_ticks; */
91
        hruler_class->draw_ticks = gtk_shruler_draw_ticks;
92
        
93
        /* unimplemented draw pos */
94
        hruler_class->draw_pos = NULL;
95
/*
96
          hruler_class->draw_pos = gtk_shruler_draw_pos;
97
*/
98
}
99
100
static void
101
gtk_shruler_init (GtkSHRuler * shruler)
102
{
103
        GtkWidget * widget;
104
        
105
        widget = GTK_WIDGET (shruler);
106
        widget->requisition.width = widget->style->xthickness * 2 + 1;
107
        widget->requisition.height = widget->style->ythickness * 2 + RULER_HEIGHT;
108
}
109
110
111
GtkWidget*
112
gtk_shruler_new(void)
113
{
114
        return GTK_WIDGET( g_object_new( gtk_shruler_get_type(), NULL ) );
115
}
116
117
static void
118
gtk_shruler_draw_ticks(GtkRuler *ruler)
119
{
120
        GtkWidget *widget;
121
        GdkGC *gc, *bg_gc;
122
        gint i;
123
        gint width, height;
124
        gint xthickness;
125
        gint ythickness;
126
        gint pos;
127
128
        g_return_if_fail (ruler != NULL);
129
        g_return_if_fail (GTK_IS_HRULER (ruler));
130
131
        if (!GTK_WIDGET_DRAWABLE (ruler)) 
132
                return;
133
134
        widget = GTK_WIDGET (ruler);
135
        
136
        gc = widget->style->fg_gc[GTK_STATE_NORMAL];
137
        bg_gc = widget->style->bg_gc[GTK_STATE_NORMAL];
138
139
        xthickness = widget->style->xthickness;
140
        ythickness = widget->style->ythickness;
141
142
        width = widget->allocation.width;
143
        height = widget->allocation.height - ythickness * 2;
144
  
145
        gtk_paint_box (widget->style, ruler->backing_store,
146
                       GTK_STATE_NORMAL, GTK_SHADOW_OUT, 
147
                       NULL, widget, "hruler",
148
                       0, 0, 
149
                       widget->allocation.width, widget->allocation.height);
150
151
#if 0
152
        gdk_draw_line (ruler->backing_store, gc,
153
                       xthickness,
154
                       height + ythickness,
155
                       widget->allocation.width - xthickness,
156
                       height + ythickness);
157
#endif
158
159
        /* assume ruler->max_size has the char width */
160
        /* i is increment of char_width,  pos is label number
161
         * y position is based on height of widget itself */
162
        for ( i = 0, pos = 0; i < widget->allocation.width - xthickness; i += ruler->max_size, pos++ ) {        
163
                gint length = height / 8;
164
        
165
                if ( pos % 10 == 0 ) length = ( 2 * height / 3 );
166
                else if ( pos % 5 == 0 ) length = ( height / 3 );
167
                
168
                gdk_draw_line(ruler->backing_store, gc,
169
                              i, height + ythickness,
170
                              i, height - length);                        
171
                
172
                if ( pos % 10 == 0 ) {
173
                        gchar buf[8];
174
                        PangoLayout *layout;
175
176
                        /* draw label */
177
                        g_snprintf(buf, sizeof buf, "%d", pos);
178
179
                        layout = gtk_widget_create_pango_layout
180
                                (GTK_WIDGET(ruler), buf);
181
182
                        gdk_draw_layout(ruler->backing_store, gc, i + 2,
183
                                        0, layout);
184
185
                        g_object_unref(layout);
186
                }
187
        }
188
}
189
190
/* gtk_ruler_set_pos() - does not work yet, need to reimplement 
191
 * gtk_ruler_draw_pos(). */
192
void
193
gtk_shruler_set_pos(GtkSHRuler * ruler, gfloat pos)
194
{
195
        GtkRuler * ruler_;
196
        g_return_if_fail( ruler != NULL );
197
        
198
        ruler_ = GTK_RULER(ruler);
199
        
200
        if ( pos < ruler_->lower ) 
201
                pos = ruler_->lower;
202
        if ( pos > ruler_->upper )
203
                pos = ruler_->upper;
204
        
205
        ruler_->position = pos;        
206
        
207
        /*  Make sure the ruler has been allocated already  */
208
        if ( ruler_->backing_store != NULL )
209
                gtk_ruler_draw_pos(ruler_);
210
}