gtkhscale.c 6.38 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1
/* GTK - The GIMP Toolkit
2
 * Copyright (C) 2001 Red Hat, Inc.
Elliot Lee's avatar
Elliot Lee committed
3 4
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10 11
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15 16 17
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
18
 */
19 20

/*
21
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22 23 24 25 26
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

Elliot Lee's avatar
Elliot Lee committed
27 28 29
#include <stdio.h>
#include "gtkhscale.h"
#include "gtksignal.h"
Alexander Larsson's avatar
Alexander Larsson committed
30
#include "gtkintl.h"
Elliot Lee's avatar
Elliot Lee committed
31

32
static gpointer parent_class;
Elliot Lee's avatar
Elliot Lee committed
33

34 35
static void     gtk_hscale_class_init       (GtkHScaleClass *klass);
static void     gtk_hscale_init             (GtkHScale      *hscale);
36 37
static gboolean gtk_hscale_expose           (GtkWidget      *widget,
                                             GdkEventExpose *event);
Elliot Lee's avatar
Elliot Lee committed
38

39
GtkType
40
gtk_hscale_get_type (void)
Elliot Lee's avatar
Elliot Lee committed
41
{
42 43
  static GtkType hscale_type = 0;
  
Elliot Lee's avatar
Elliot Lee committed
44 45
  if (!hscale_type)
    {
46
      static const GtkTypeInfo hscale_info =
Elliot Lee's avatar
Elliot Lee committed
47
      {
48 49 50 51 52 53
        "GtkHScale",
        sizeof (GtkHScale),
        sizeof (GtkHScaleClass),
        (GtkClassInitFunc) gtk_hscale_class_init,
        (GtkObjectInitFunc) gtk_hscale_init,
        /* reserved_1 */ NULL,
54
        /* reserved_2 */ NULL,
55
        (GtkClassInitFunc) NULL,
Elliot Lee's avatar
Elliot Lee committed
56
      };
57 58
      
      hscale_type = gtk_type_unique (GTK_TYPE_SCALE, &hscale_info);
Elliot Lee's avatar
Elliot Lee committed
59
    }
60
  
Elliot Lee's avatar
Elliot Lee committed
61 62 63 64 65 66
  return hscale_type;
}

static void
gtk_hscale_class_init (GtkHScaleClass *class)
{
Alexander Larsson's avatar
Alexander Larsson committed
67
  GObjectClass *gobject_class;
Elliot Lee's avatar
Elliot Lee committed
68 69
  GtkWidgetClass *widget_class;
  GtkRangeClass *range_class;
70
  
71 72 73
  gobject_class = G_OBJECT_CLASS (class);
  widget_class = GTK_WIDGET_CLASS (class);
  range_class = GTK_RANGE_CLASS (class);
74

75
  parent_class = g_type_class_peek_parent (class);
76

77
  range_class->slider_detail = "hscale";
78
  
79
  widget_class->expose_event = gtk_hscale_expose;
80 81
}

Elliot Lee's avatar
Elliot Lee committed
82 83 84
static void
gtk_hscale_init (GtkHScale *hscale)
{
85 86 87 88 89 90
  GtkRange *range;

  range = GTK_RANGE (hscale);

  range->orientation = GTK_ORIENTATION_HORIZONTAL;
  range->flippable = TRUE;
Elliot Lee's avatar
Elliot Lee committed
91 92 93 94 95
}

GtkWidget*
gtk_hscale_new (GtkAdjustment *adjustment)
{
96 97 98 99 100
  GtkWidget *hscale;
  
  hscale = gtk_widget_new (GTK_TYPE_HSCALE,
			   "adjustment", adjustment,
			   NULL);
Elliot Lee's avatar
Elliot Lee committed
101

102
  return hscale;
Elliot Lee's avatar
Elliot Lee committed
103 104
}

105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
/**
 * gtk_hscale_new_with_range:
 * @min: minimum value
 * @max: maximum value
 * @step: step increment (tick size) used with keyboard shortcuts
 * 
 * Creates a new horizontal scale widget that lets the user
 * input a number between @min and @max with the increment @step.
 * @step must be nonzero; it's the distance the slider moves when
 * using the arrow keys to adjust the scale value.
 * 
 * Return value: a new #GtkHScale
 **/
GtkWidget*
gtk_hscale_new_with_range (gdouble min,
                           gdouble max,
                           gdouble step)
{
  GtkObject *adj;
  GtkScale *scale;
  gint digits;

  g_return_val_if_fail (min < max, NULL);
  g_return_val_if_fail (step != 0.0, NULL);

  adj = gtk_adjustment_new (min, min, max, step, 10 * step, step);
  
  scale = g_object_new (GTK_TYPE_HSCALE,
                        "adjustment", adj,
                        NULL);

  if (fabs (step) >= 1.0 || step == 0.0)
    digits = 0;
  else {
    digits = abs ((gint) floor (log10 (fabs (step))));
    if (digits > 5)
      digits = 5;
  }

  gtk_scale_set_digits (scale, digits);
  
  return GTK_WIDGET (scale);
}

149 150 151
static gboolean
gtk_hscale_expose (GtkWidget      *widget,
                   GdkEventExpose *event)
Elliot Lee's avatar
Elliot Lee committed
152 153
{
  GtkRange *range;
154
  GtkHScale *hscale;
Elliot Lee's avatar
Elliot Lee committed
155
  GtkScale *scale;
156
  
157 158 159
  range = GTK_RANGE (widget);
  scale = GTK_SCALE (widget);
  hscale = GTK_HSCALE (widget);
160
  
Elliot Lee's avatar
Elliot Lee committed
161 162
  if (scale->draw_value)
    {
163 164
      PangoLayout *layout;
      PangoRectangle logical_rect;
Havoc Pennington's avatar
Havoc Pennington committed
165
      gchar *txt;
166 167 168
      gint x, y;
      GtkStateType state_type;
      gint value_spacing;
Havoc Pennington's avatar
Havoc Pennington committed
169

170 171
      gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
      
Havoc Pennington's avatar
Havoc Pennington committed
172 173 174 175 176
      txt = _gtk_scale_format_value (scale,
                                     GTK_RANGE (scale)->adjustment->value);
      
      layout = gtk_widget_create_pango_layout (widget, txt);
      g_free (txt);
177
      
178
      pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
179
      
Elliot Lee's avatar
Elliot Lee committed
180
      switch (scale->value_pos)
181 182
        {
        case GTK_POS_LEFT:
183 184
          x = range->range_rect.x - value_spacing - logical_rect.width;
          y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
185 186
          break;
          
187 188 189
        case GTK_POS_RIGHT:
          x = range->range_rect.x + range->range_rect.width + value_spacing;
          y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
190 191
          break;
          
192 193 194 195 196
        case GTK_POS_TOP:
          x = range->slider_start +
            (range->slider_end - range->slider_start - logical_rect.width) / 2;
          x = CLAMP (x, 0, widget->allocation.width - logical_rect.width);
          y = range->range_rect.y - logical_rect.height - value_spacing;
197 198
          break;
          
199 200 201 202 203 204 205 206 207 208 209
        case GTK_POS_BOTTOM:
          x = range->slider_start +
            (range->slider_end - range->slider_start - logical_rect.width) / 2;
          x = CLAMP (x, 0, widget->allocation.width - logical_rect.width);
          y = range->range_rect.y + range->range_rect.height + value_spacing;
          break;

        default:
          g_return_val_if_reached (FALSE);
          x = 0;
          y = 0;
210 211 212
          break;
        }
      
Elliot Lee's avatar
Elliot Lee committed
213 214
      state_type = GTK_STATE_NORMAL;
      if (!GTK_WIDGET_IS_SENSITIVE (scale))
215
        state_type = GTK_STATE_INSENSITIVE;
216

217 218 219
      gtk_paint_layout (widget->style,
                        widget->window,
                        state_type,
220
			FALSE,
221 222 223 224 225
                        NULL,
                        widget,
                        "hscale",
                        x, y,
                        layout);
226

227
      g_object_unref (G_OBJECT (layout));
Elliot Lee's avatar
Elliot Lee committed
228
    }
229 230

  return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
Elliot Lee's avatar
Elliot Lee committed
231
}