📄 gtkrange.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * 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/. */#include <stdio.h>#include "gtkmain.h"#include "gtkrange.h"#include "gtksignal.h"#define SCROLL_TIMER_LENGTH 20#define SCROLL_INITIAL_DELAY 100#define SCROLL_DELAY_LENGTH 300#define RANGE_CLASS(w) GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)enum { ARG_0, ARG_UPDATE_POLICY};static void gtk_range_class_init (GtkRangeClass *klass);static void gtk_range_init (GtkRange *range);static void gtk_range_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_range_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_range_destroy (GtkObject *object);static void gtk_range_finalize (GtkObject *object);static void gtk_range_draw (GtkWidget *widget, GdkRectangle *area);static void gtk_range_draw_focus (GtkWidget *widget);static void gtk_range_unrealize (GtkWidget *widget);static gint gtk_range_expose (GtkWidget *widget, GdkEventExpose *event);static gint gtk_range_button_press (GtkWidget *widget, GdkEventButton *event);static gint gtk_range_button_release (GtkWidget *widget, GdkEventButton *event);static gint gtk_range_motion_notify (GtkWidget *widget, GdkEventMotion *event);static gint gtk_range_key_press (GtkWidget *widget, GdkEventKey *event);static gint gtk_range_enter_notify (GtkWidget *widget, GdkEventCrossing *event);static gint gtk_range_leave_notify (GtkWidget *widget, GdkEventCrossing *event);static gint gtk_range_focus_in (GtkWidget *widget, GdkEventFocus *event);static gint gtk_range_focus_out (GtkWidget *widget, GdkEventFocus *event);static void gtk_range_style_set (GtkWidget *widget, GtkStyle *previous_style);static void gtk_real_range_draw_trough (GtkRange *range);static void gtk_real_range_draw_slider (GtkRange *range);static gint gtk_real_range_timer (GtkRange *range);static gint gtk_range_scroll (GtkRange *range, gfloat jump_perc);static void gtk_range_add_timer (GtkRange *range);static void gtk_range_remove_timer (GtkRange *range);static void gtk_range_adjustment_changed (GtkAdjustment *adjustment, gpointer data);static void gtk_range_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data);static void gtk_range_trough_hdims (GtkRange *range, gint *left, gint *right);static void gtk_range_trough_vdims (GtkRange *range, gint *top, gint *bottom);static GtkWidgetClass *parent_class = NULL;GtkTypegtk_range_get_type (void){ static GtkType range_type = 0; if (!range_type) { static const GtkTypeInfo range_info = { "GtkRange", sizeof (GtkRange), sizeof (GtkRangeClass), (GtkClassInitFunc) gtk_range_class_init, (GtkObjectInitFunc) gtk_range_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; range_type = gtk_type_unique (GTK_TYPE_WIDGET, &range_info); } return range_type;}static voidgtk_range_class_init (GtkRangeClass *class){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; parent_class = gtk_type_class (GTK_TYPE_WIDGET); gtk_object_add_arg_type ("GtkRange::update_policy", GTK_TYPE_UPDATE_TYPE, GTK_ARG_READWRITE, ARG_UPDATE_POLICY); object_class->set_arg = gtk_range_set_arg; object_class->get_arg = gtk_range_get_arg; object_class->destroy = gtk_range_destroy; object_class->finalize = gtk_range_finalize; widget_class->draw = gtk_range_draw; widget_class->draw_focus = gtk_range_draw_focus; widget_class->unrealize = gtk_range_unrealize; widget_class->expose_event = gtk_range_expose; widget_class->button_press_event = gtk_range_button_press; widget_class->button_release_event = gtk_range_button_release; widget_class->motion_notify_event = gtk_range_motion_notify; widget_class->key_press_event = gtk_range_key_press; widget_class->enter_notify_event = gtk_range_enter_notify; widget_class->leave_notify_event = gtk_range_leave_notify; widget_class->focus_in_event = gtk_range_focus_in; widget_class->focus_out_event = gtk_range_focus_out; widget_class->style_set = gtk_range_style_set; class->slider_width = 11; class->stepper_size = 11; class->stepper_slider_spacing = 1; class->min_slider_size = 7; class->trough = 1; class->slider = 2; class->step_forw = 3; class->step_back = 4; class->draw_background = NULL; class->clear_background = NULL; class->draw_trough = gtk_real_range_draw_trough; class->draw_slider = gtk_real_range_draw_slider; class->draw_step_forw = NULL; class->draw_step_back = NULL; class->trough_click = NULL; class->trough_keys = NULL; class->motion = NULL; class->timer = gtk_real_range_timer;}static voidgtk_range_set_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkRange *range; range = GTK_RANGE (object); switch (arg_id) { case ARG_UPDATE_POLICY: gtk_range_set_update_policy (range, GTK_VALUE_ENUM (*arg)); break; default: break; }}static voidgtk_range_get_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkRange *range; range = GTK_RANGE (object); switch (arg_id) { case ARG_UPDATE_POLICY: GTK_VALUE_ENUM (*arg) = range->policy; break; default: arg->type = GTK_TYPE_INVALID; break; }}static voidgtk_range_init (GtkRange *range){ range->trough = NULL; range->slider = NULL; range->step_forw = NULL; range->step_back = NULL; range->x_click_point = 0; range->y_click_point = 0; range->button = 0; range->digits = -1; range->policy = GTK_UPDATE_CONTINUOUS; range->scroll_type = GTK_SCROLL_NONE; range->in_child = 0; range->click_child = 0; range->need_timer = FALSE; range->timer = 0; range->old_value = 0.0; range->old_lower = 0.0; range->old_upper = 0.0; range->old_page_size = 0.0; range->adjustment = NULL;}GtkAdjustment*gtk_range_get_adjustment (GtkRange *range){ g_return_val_if_fail (range != NULL, NULL); g_return_val_if_fail (GTK_IS_RANGE (range), NULL); return range->adjustment;}voidgtk_range_set_update_policy (GtkRange *range, GtkUpdateType policy){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); range->policy = policy;}voidgtk_range_set_adjustment (GtkRange *range, GtkAdjustment *adjustment){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (!adjustment) adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); else g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); if (range->adjustment != adjustment) { if (range->adjustment) { gtk_signal_disconnect_by_data (GTK_OBJECT (range->adjustment), (gpointer) range); gtk_object_unref (GTK_OBJECT (range->adjustment)); } range->adjustment = adjustment; gtk_object_ref (GTK_OBJECT (adjustment)); gtk_object_sink (GTK_OBJECT (adjustment)); gtk_signal_connect (GTK_OBJECT (adjustment), "changed", (GtkSignalFunc) gtk_range_adjustment_changed, (gpointer) range); gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed", (GtkSignalFunc) gtk_range_adjustment_value_changed, (gpointer) range); range->old_value = adjustment->value; range->old_lower = adjustment->lower; range->old_upper = adjustment->upper; range->old_page_size = adjustment->page_size; gtk_range_adjustment_changed (adjustment, (gpointer) range); }}voidgtk_range_draw_background (GtkRange *range){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (range->trough && RANGE_CLASS (range)->draw_background) (* RANGE_CLASS (range)->draw_background) (range);}voidgtk_range_clear_background (GtkRange *range){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (range->trough && RANGE_CLASS (range)->clear_background) (* RANGE_CLASS (range)->clear_background) (range);}voidgtk_range_draw_trough (GtkRange *range){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (range->trough && RANGE_CLASS (range)->draw_trough) (* RANGE_CLASS (range)->draw_trough) (range);}voidgtk_range_draw_slider (GtkRange *range){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (range->slider && RANGE_CLASS (range)->draw_slider) (* RANGE_CLASS (range)->draw_slider) (range);}voidgtk_range_draw_step_forw (GtkRange *range){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (range->step_forw && RANGE_CLASS (range)->draw_step_forw) (* RANGE_CLASS (range)->draw_step_forw) (range);}voidgtk_range_draw_step_back (GtkRange *range){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (range->step_back && RANGE_CLASS (range)->draw_step_back) (* RANGE_CLASS (range)->draw_step_back) (range);}voidgtk_range_slider_update (GtkRange *range){ g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (RANGE_CLASS (range)->slider_update) (* RANGE_CLASS (range)->slider_update) (range);}gintgtk_range_trough_click (GtkRange *range, gint x, gint y, gfloat *jump_perc){ g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE); g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE); if (RANGE_CLASS (range)->trough_click) return (* RANGE_CLASS (range)->trough_click) (range, x, y, jump_perc); return GTK_TROUGH_NONE;}voidgtk_range_default_hslider_update (GtkRange *range){ gint left; gint right; gint x; g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (GTK_WIDGET_REALIZED (range)) { gtk_range_trough_hdims (range, &left, &right); x = left; if (range->adjustment->value < range->adjustment->lower) { range->adjustment->value = range->adjustment->lower; gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed"); } else if (range->adjustment->value > range->adjustment->upper) { range->adjustment->value = range->adjustment->upper; gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed"); } if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size)) x += ((right - left) * (range->adjustment->value - range->adjustment->lower) / (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size)); if (x < left) x = left; else if (x > right) x = right; gdk_window_move (range->slider, x, GTK_WIDGET (range)->style->klass->ythickness); }}voidgtk_range_default_vslider_update (GtkRange *range){ gint top; gint bottom; gint y; g_return_if_fail (range != NULL); g_return_if_fail (GTK_IS_RANGE (range)); if (GTK_WIDGET_REALIZED (range)) { gtk_range_trough_vdims (range, &top, &bottom); y = top; if (range->adjustment->value < range->adjustment->lower) { range->adjustment->value = range->adjustment->lower; gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed"); } else if (range->adjustment->value > range->adjustment->upper) { range->adjustment->value = range->adjustment->upper; gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed"); } if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size)) y += ((bottom - top) * (range->adjustment->value - range->adjustment->lower) / (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size)); if (y < top) y = top; else if (y > bottom) y = bottom; gdk_window_move (range->slider, GTK_WIDGET (range)->style->klass->xthickness, y); }}gintgtk_range_default_htrough_click (GtkRange *range, gint x, gint y, gfloat *jump_perc){ gint ythickness; gint trough_width; gint trough_height; gint slider_x; gint slider_length; gint left, right; g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE); g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE); ythickness = GTK_WIDGET (range)->style->klass->ythickness; gtk_range_trough_hdims (range, &left, &right); gdk_window_get_size (range->slider, &slider_length, NULL); right += slider_length; if ((x > left) && (y > ythickness)) { gdk_window_get_size (range->trough, &trough_width, &trough_height); if ((x < right) && (y < (trough_height - ythickness))) { if (jump_perc) { *jump_perc = ((gdouble) (x - left)) / ((gdouble) (right - left)); return GTK_TROUGH_JUMP; } gdk_window_get_position (range->slider, &slider_x, NULL); if (x < slider_x) return GTK_TROUGH_START; else return GTK_TROUGH_END; } } return GTK_TROUGH_NONE;}gintgtk_range_default_vtrough_click (GtkRange *range, gint x, gint y, gfloat *jump_perc){ gint xthickness; gint trough_width; gint trough_height; gint slider_y; gint top, bottom; gint slider_length; g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE); g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -