Statistics
| Revision:

root / src / gtkshruler.c @ 1607

History | View | Annotate | Download (5.9 kB)

1 1 hiro
/* GtkSHRuler
2 1 hiro
 *
3 1595 hiro
 * Copyright (C) 2000-2005 Alfons Hoogervorst & The Sylpheed Claws Team
4 1595 hiro
 * Copyright (C) 2007 Hiroyuki Yamamoto
5 1 hiro
 *
6 1 hiro
 * This library is free software; you can redistribute it and/or
7 1 hiro
 * modify it under the terms of the GNU Library General Public
8 1 hiro
 * License as published by the Free Software Foundation; either
9 1 hiro
 * version 2 of the License, or (at your option) any later version.
10 1 hiro
 *
11 1 hiro
 * This library is distributed in the hope that it will be useful,
12 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 1 hiro
 * Library General Public License for more details.
15 1 hiro
 *
16 1 hiro
 * You should have received a copy of the GNU Library General Public
17 1 hiro
 * License along with this library; if not, write to the
18 1 hiro
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 1 hiro
 * Boston, MA 02111-1307, USA.
20 1 hiro
 */
21 1 hiro
22 1 hiro
/* I derived this class from hruler. S in HRuler could be read as
23 1179 hiro
 * Sylpheed (sylpheed.sraoss.jp), but also [S]ettable HRuler.
24 1 hiro
 * I basically ripped apart the draw_ticks member of HRuler; it
25 1 hiro
 * now draws the ticks at ruler->max_size. so gtk_ruler_set_range's
26 1 hiro
 * last parameter has the distance between two ticks (which is
27 1 hiro
 * the width of the fixed font character!
28 1 hiro
 *
29 1 hiro
 * -- Alfons
30 1 hiro
 */
31 1 hiro
32 1 hiro
#include <math.h>
33 1 hiro
#include <stdio.h>
34 1 hiro
#include <string.h>
35 1 hiro
#include <gtk/gtkhruler.h>
36 1 hiro
#include "gtkshruler.h"
37 1 hiro
38 1 hiro
#define RULER_HEIGHT          14
39 1 hiro
#define MINIMUM_INCR          5
40 1 hiro
#define MAXIMUM_SUBDIVIDE     5
41 1 hiro
#define MAXIMUM_SCALES        10
42 1 hiro
43 1 hiro
#define ROUND(x) ((int) ((x) + 0.5))
44 1 hiro
45 1 hiro
static void gtk_shruler_class_init           (GtkSHRulerClass *klass);
46 1 hiro
static void gtk_shruler_init                 (GtkSHRuler      *hruler);
47 1 hiro
static void gtk_shruler_draw_ticks         (GtkRuler        *ruler);
48 1 hiro
#if 0
49 1 hiro
static void gtk_shruler_draw_pos              (GtkRuler        *ruler);
50 1 hiro
#endif
51 1 hiro
52 1 hiro
GType
53 1 hiro
gtk_shruler_get_type(void)
54 1 hiro
{
55 1 hiro
        static GType shruler_type = 0;
56 1 hiro
57 1 hiro
          if ( !shruler_type ) {
58 1 hiro
                   static const GTypeInfo shruler_info = {
59 1 hiro
                        sizeof (GtkSHRulerClass),
60 1 hiro
61 1 hiro
                        (GBaseInitFunc) NULL,
62 1 hiro
                        (GBaseFinalizeFunc) NULL,
63 1 hiro
64 1 hiro
                        (GClassInitFunc) gtk_shruler_class_init,
65 1 hiro
                        (GClassFinalizeFunc) NULL,
66 1 hiro
                        NULL,        /* class_data */
67 1 hiro
68 1 hiro
                        sizeof (GtkSHRuler),
69 1 hiro
                        0,        /* n_preallocs */
70 1 hiro
                        (GInstanceInitFunc) gtk_shruler_init,
71 1 hiro
                };
72 1 hiro
                /* inherit from GtkHRuler */
73 29 hiro
                shruler_type = g_type_register_static (GTK_TYPE_HRULER, "GtkSHRuler", &shruler_info, (GTypeFlags)0);
74 1 hiro
        }
75 1 hiro
        return shruler_type;
76 1 hiro
}
77 1 hiro
78 1 hiro
static void
79 1 hiro
gtk_shruler_class_init(GtkSHRulerClass * klass)
80 1 hiro
{
81 1 hiro
         GtkWidgetClass * widget_class;
82 1 hiro
          GtkRulerClass * hruler_class;
83 1 hiro
84 1 hiro
          widget_class = (GtkWidgetClass*) klass;
85 1 hiro
          hruler_class = (GtkRulerClass*) klass;
86 1 hiro
87 1 hiro
        /* just neglect motion notify events */
88 1 hiro
          widget_class->motion_notify_event = NULL /* gtk_shruler_motion_notify */;
89 1 hiro
90 1 hiro
          /* we want the old ruler draw ticks... */
91 1 hiro
          /* ruler_class->draw_ticks = gtk_hruler_draw_ticks; */
92 1 hiro
        hruler_class->draw_ticks = gtk_shruler_draw_ticks;
93 1 hiro
94 1 hiro
        /* unimplemented draw pos */
95 1 hiro
        hruler_class->draw_pos = NULL;
96 1 hiro
/*
97 1 hiro
          hruler_class->draw_pos = gtk_shruler_draw_pos;
98 1 hiro
*/
99 1 hiro
}
100 1 hiro
101 1 hiro
static void
102 1 hiro
gtk_shruler_init (GtkSHRuler * shruler)
103 1 hiro
{
104 1 hiro
        GtkWidget * widget;
105 1 hiro
106 1 hiro
        widget = GTK_WIDGET (shruler);
107 1 hiro
        widget->requisition.width = widget->style->xthickness * 2 + 1;
108 1 hiro
        widget->requisition.height = widget->style->ythickness * 2 + RULER_HEIGHT;
109 1595 hiro
        shruler->start_pos = 0;
110 1 hiro
}
111 1 hiro
112 1 hiro
113 1 hiro
GtkWidget*
114 1 hiro
gtk_shruler_new(void)
115 1 hiro
{
116 1 hiro
        return GTK_WIDGET( g_object_new( gtk_shruler_get_type(), NULL ) );
117 1 hiro
}
118 1 hiro
119 1595 hiro
void
120 1595 hiro
gtk_shruler_set_start_pos(GtkSHRuler *ruler, gint pos)
121 1595 hiro
{
122 1595 hiro
        g_return_if_fail (GTK_IS_SHRULER (ruler));
123 1595 hiro
124 1595 hiro
        ruler->start_pos = pos;
125 1595 hiro
}
126 1595 hiro
127 1595 hiro
gint
128 1595 hiro
gtk_shruler_get_start_pos(GtkSHRuler *ruler)
129 1595 hiro
{
130 1595 hiro
        g_return_if_fail (GTK_IS_SHRULER (ruler));
131 1595 hiro
132 1595 hiro
        return ruler->start_pos;
133 1595 hiro
}
134 1595 hiro
135 1 hiro
static void
136 1 hiro
gtk_shruler_draw_ticks(GtkRuler *ruler)
137 1 hiro
{
138 1 hiro
        GtkWidget *widget;
139 1 hiro
        GdkGC *gc, *bg_gc;
140 1 hiro
        gint i;
141 1 hiro
        gint width, height;
142 1 hiro
        gint xthickness;
143 1 hiro
        gint ythickness;
144 1 hiro
        gint pos;
145 1 hiro
146 1 hiro
        g_return_if_fail (ruler != NULL);
147 1 hiro
        g_return_if_fail (GTK_IS_HRULER (ruler));
148 1 hiro
149 1 hiro
        if (!GTK_WIDGET_DRAWABLE (ruler))
150 1 hiro
                return;
151 1 hiro
152 1 hiro
        widget = GTK_WIDGET (ruler);
153 1 hiro
154 1 hiro
        gc = widget->style->fg_gc[GTK_STATE_NORMAL];
155 1 hiro
        bg_gc = widget->style->bg_gc[GTK_STATE_NORMAL];
156 1 hiro
157 1 hiro
        xthickness = widget->style->xthickness;
158 1 hiro
        ythickness = widget->style->ythickness;
159 1 hiro
160 1 hiro
        width = widget->allocation.width;
161 1 hiro
        height = widget->allocation.height - ythickness * 2;
162 1 hiro
163 1 hiro
        gtk_paint_box (widget->style, ruler->backing_store,
164 1 hiro
                       GTK_STATE_NORMAL, GTK_SHADOW_OUT,
165 1 hiro
                       NULL, widget, "hruler",
166 1 hiro
                       0, 0,
167 1 hiro
                       widget->allocation.width, widget->allocation.height);
168 1 hiro
169 1 hiro
#if 0
170 1 hiro
        gdk_draw_line (ruler->backing_store, gc,
171 1 hiro
                       xthickness,
172 1 hiro
                       height + ythickness,
173 1 hiro
                       widget->allocation.width - xthickness,
174 1 hiro
                       height + ythickness);
175 1 hiro
#endif
176 1 hiro
177 29 hiro
        /* assume ruler->max_size has the char width */
178 29 hiro
        /* i is increment of char_width,  pos is label number
179 29 hiro
         * y position is based on height of widget itself */
180 1595 hiro
        for ( pos = GTK_SHRULER(ruler)->start_pos, i = 0; pos < widget->allocation.width - xthickness; pos += ruler->max_size, i++ ) {
181 29 hiro
                gint length = height / 8;
182 1 hiro
183 1595 hiro
                if ( i % 10 == 0 ) length = ( 2 * height / 3 );
184 1595 hiro
                else if ( i % 5 == 0 ) length = ( height / 3 );
185 1 hiro
186 1 hiro
                gdk_draw_line(ruler->backing_store, gc,
187 1595 hiro
                              pos, height + ythickness,
188 1595 hiro
                              pos, height - length);
189 1 hiro
190 1595 hiro
                if ( i % 10 == 0 ) {
191 29 hiro
                        gchar buf[8];
192 29 hiro
                        PangoLayout *layout;
193 29 hiro
194 1 hiro
                        /* draw label */
195 1595 hiro
                        g_snprintf(buf, sizeof buf, "%d", i);
196 29 hiro
197 29 hiro
                        layout = gtk_widget_create_pango_layout
198 29 hiro
                                (GTK_WIDGET(ruler), buf);
199 29 hiro
200 1595 hiro
                        gdk_draw_layout(ruler->backing_store, gc, pos + 2,
201 29 hiro
                                        0, layout);
202 29 hiro
203 29 hiro
                        g_object_unref(layout);
204 29 hiro
                }
205 1 hiro
        }
206 1 hiro
}
207 1 hiro
208 1 hiro
/* gtk_ruler_set_pos() - does not work yet, need to reimplement
209 1 hiro
 * gtk_ruler_draw_pos(). */
210 1 hiro
void
211 1 hiro
gtk_shruler_set_pos(GtkSHRuler * ruler, gfloat pos)
212 1 hiro
{
213 1 hiro
        GtkRuler * ruler_;
214 1 hiro
        g_return_if_fail( ruler != NULL );
215 1 hiro
216 1 hiro
        ruler_ = GTK_RULER(ruler);
217 1 hiro
218 1 hiro
        if ( pos < ruler_->lower )
219 1 hiro
                pos = ruler_->lower;
220 1 hiro
        if ( pos > ruler_->upper )
221 1 hiro
                pos = ruler_->upper;
222 1 hiro
223 1 hiro
        ruler_->position = pos;
224 1 hiro
225 1 hiro
        /*  Make sure the ruler has been allocated already  */
226 1 hiro
        if ( ruler_->backing_store != NULL )
227 1 hiro
                gtk_ruler_draw_pos(ruler_);
228 1 hiro
}