📄 sec-gtkdial.html
字号:
gdk_window_set_user_data (widget->window, widget); gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);}static void gtk_dial_size_request (GtkWidget *widget, GtkRequisition *requisition){ requisition->width = DIAL_DEFAULT_SIZE; requisition->height = DIAL_DEFAULT_SIZE;}static voidgtk_dial_size_allocate (GtkWidget *widget, GtkAllocation *allocation){ GtkDial *dial; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_DIAL (widget)); g_return_if_fail (allocation != NULL); widget->allocation = *allocation; dial = GTK_DIAL (widget); if (GTK_WIDGET_REALIZED (widget)) { gdk_window_move_resize (widget->window, allocation->x, allocation->y, allocation->width, allocation->height); } dial->radius = MIN(allocation->width,allocation->height) * 0.45; dial->pointer_width = dial->radius / 5;}static gintgtk_dial_expose (GtkWidget *widget, GdkEventExpose *event){ GtkDial *dial; GdkPoint points[6]; gdouble s,c; gdouble theta, last, increment; GtkStyle *blankstyle; gint xc, yc; gint upper, lower; gint tick_length; gint i, inc; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (event->count > 0) return FALSE; dial = GTK_DIAL (widget);/* gdk_window_clear_area (widget->window, 0, 0, widget->allocation.width, widget->allocation.height);*/ xc = widget->allocation.width/2; yc = widget->allocation.height/2; upper = dial->adjustment->upper; lower = dial->adjustment->lower; /* Erase old pointer */ s = sin(dial->last_angle); c = cos(dial->last_angle); dial->last_angle = dial->angle; points[0].x = xc + s*dial->pointer_width/2; points[0].y = yc + c*dial->pointer_width/2; points[1].x = xc + c*dial->radius; points[1].y = yc - s*dial->radius; points[2].x = xc - s*dial->pointer_width/2; points[2].y = yc - c*dial->pointer_width/2; points[3].x = xc - c*dial->radius/10; points[3].y = yc + s*dial->radius/10; points[4].x = points[0].x; points[4].y = points[0].y; blankstyle = gtk_style_new (); blankstyle->bg_gc[GTK_STATE_NORMAL] = widget->style->bg_gc[GTK_STATE_NORMAL]; blankstyle->dark_gc[GTK_STATE_NORMAL] = widget->style->bg_gc[GTK_STATE_NORMAL]; blankstyle->light_gc[GTK_STATE_NORMAL] = widget->style->bg_gc[GTK_STATE_NORMAL]; blankstyle->black_gc = widget->style->bg_gc[GTK_STATE_NORMAL]; gtk_draw_polygon (blankstyle, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, points, 5, FALSE); gtk_style_unref(blankstyle); /* Draw ticks */ if ((upper - lower) == 0) return; increment = (100*M_PI)/(dial->radius*dial->radius); inc = (upper - lower); while (inc < 100) inc *=10; while (inc >= 1000) inc /=10; last = -1; for (i=0; i<=inc; i++) { theta = ((gfloat)i*M_PI/(18*inc/24.) - M_PI/6.); if ((theta - last) < (increment)) continue; last = theta; s = sin(theta); c = cos(theta); tick_length = (i%(inc/10) == 0) ? dial->pointer_width : dial->pointer_width/2; gdk_draw_line (widget->window, widget->style->fg_gc[widget->state], xc + c*(dial->radius - tick_length), yc - s*(dial->radius - tick_length), xc + c*dial->radius, yc - s*dial->radius); } /* Draw pointer */ s = sin(dial->angle); c = cos(dial->angle); dial->last_angle = dial->angle; points[0].x = xc + s*dial->pointer_width/2; points[0].y = yc + c*dial->pointer_width/2; points[1].x = xc + c*dial->radius; points[1].y = yc - s*dial->radius; points[2].x = xc - s*dial->pointer_width/2; points[2].y = yc - c*dial->pointer_width/2; points[3].x = xc - c*dial->radius/10; points[3].y = yc + s*dial->radius/10; points[4].x = points[0].x; points[4].y = points[0].y; gtk_draw_polygon (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, points, 5, TRUE); return FALSE;}static gintgtk_dial_button_press (GtkWidget *widget, GdkEventButton *event){ GtkDial *dial; gint dx, dy; double s, c; double d_parallel; double d_perpendicular; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); dial = GTK_DIAL (widget); /* Determine if button press was within pointer region - we do this by computing the parallel and perpendicular distance of the point where the mouse was pressed from the line passing through the pointer */ dx = event->x - widget->allocation.width / 2; dy = widget->allocation.height / 2 - event->y; s = sin(dial->angle); c = cos(dial->angle); d_parallel = s*dy + c*dx; d_perpendicular = fabs(s*dx - c*dy); if (!dial->button && (d_perpendicular < dial->pointer_width/2) && (d_parallel > - dial->pointer_width)) { gtk_grab_add (widget); dial->button = event->button; gtk_dial_update_mouse (dial, event->x, event->y); } return FALSE;}static gintgtk_dial_button_release (GtkWidget *widget, GdkEventButton *event){ GtkDial *dial; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); dial = GTK_DIAL (widget); if (dial->button == event->button) { gtk_grab_remove (widget); dial->button = 0; if (dial->policy == GTK_UPDATE_DELAYED) gtk_timeout_remove (dial->timer); if ((dial->policy != GTK_UPDATE_CONTINUOUS) && (dial->old_value != dial->adjustment->value)) gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed"); } return FALSE;}static gintgtk_dial_motion_notify (GtkWidget *widget, GdkEventMotion *event){ GtkDial *dial; GdkModifierType mods; gint x, y, mask; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); dial = GTK_DIAL (widget); if (dial->button != 0) { x = event->x; y = event->y; if (event->is_hint || (event->window != widget->window)) gdk_window_get_pointer (widget->window, &x, &y, &mods); switch (dial->button) { case 1: mask = GDK_BUTTON1_MASK; break; case 2: mask = GDK_BUTTON2_MASK; break; case 3: mask = GDK_BUTTON3_MASK; break; default: mask = 0; break; } if (mods & mask) gtk_dial_update_mouse (dial, x,y); } return FALSE;}static gintgtk_dial_timer (GtkDial *dial){ g_return_val_if_fail (dial != NULL, FALSE); g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE); if (dial->policy == GTK_UPDATE_DELAYED) gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed"); return FALSE;}static voidgtk_dial_update_mouse (GtkDial *dial, gint x, gint y){ gint xc, yc; gfloat old_value; g_return_if_fail (dial != NULL); g_return_if_fail (GTK_IS_DIAL (dial)); xc = GTK_WIDGET(dial)->allocation.width / 2; yc = GTK_WIDGET(dial)->allocation.height / 2; old_value = dial->adjustment->value; dial->angle = atan2(yc-y, x-xc); if (dial->angle < -M_PI/2.) dial->angle += 2*M_PI; if (dial->angle < -M_PI/6) dial->angle = -M_PI/6; if (dial->angle > 7.*M_PI/6.) dial->angle = 7.*M_PI/6.; dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) * (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.); if (dial->adjustment->value != old_value) { if (dial->policy == GTK_UPDATE_CONTINUOUS) { gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed"); } else { gtk_widget_draw (GTK_WIDGET(dial), NULL); if (dial->policy == GTK_UPDATE_DELAYED) { if (dial->timer) gtk_timeout_remove (dial->timer); dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH, (GtkFunction) gtk_dial_timer, (gpointer) dial); } } }}static voidgtk_dial_update (GtkDial *dial){ gfloat new_value; g_return_if_fail (dial != NULL); g_return_if_fail (GTK_IS_DIAL (dial)); new_value = dial->adjustment->value; if (new_value < dial->adjustment->lower) new_value = dial->adjustment->lower; if (new_value > dial->adjustment->upper) new_value = dial->adjustment->upper; if (new_value != dial->adjustment->value) { dial->adjustment->value = new_value; gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed"); } dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. / (dial->adjustment->upper - dial->adjustment->lower); gtk_widget_draw (GTK_WIDGET(dial), NULL);}static voidgtk_dial_adjustment_changed (GtkAdjustment *adjustment, gpointer data){ GtkDial *dial; g_return_if_fail (adjustment != NULL); g_return_if_fail (data != NULL); dial = GTK_DIAL (data); if ((dial->old_value != adjustment->value) || (dial->old_lower != adjustment->lower) || (dial->old_upper != adjustment->upper)) { gtk_dial_update (dial); dial->old_value = adjustment->value; dial->old_lower = adjustment->lower; dial->old_upper = adjustment->upper; }}static voidgtk_dial_adjustment_value_changed (GtkAdjustment *adjustment, gpointer data){ GtkDial *dial; g_return_if_fail (adjustment != NULL); g_return_if_fail (data != NULL); dial = GTK_DIAL (data); if (dial->old_value != adjustment->value) { gtk_dial_update (dial); dial->old_value = adjustment->value; }}/* example-end */</PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN3290">C.2.3. dial_test.c</A></H2><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">#include <stdio.h>#include <gtk/gtk.h>#include "gtkdial.h"void value_changed( GtkAdjustment *adjustment, GtkWidget *label ){ char buffer[16]; sprintf(buffer,"%4.2f",adjustment->value); gtk_label_set (GTK_LABEL (label), buffer);}int main( int argc, char *argv[]){ GtkWidget *window; GtkAdjustment *adjustment; GtkWidget *dial; GtkWidget *frame; GtkWidget *vbox; GtkWidget *label; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Dial"); gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_exit), NULL); gtk_container_border_width (GTK_CONTAINER (window), 10); vbox = gtk_vbox_new (FALSE, 5); gtk_container_add (GTK_CONTAINER (window), vbox); gtk_widget_show(vbox); frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_widget_show (frame); adjustment = GTK_ADJUSTMENT(gtk_adjustment_new (0, 0, 100, 0.01, 0.1, 0)); dial = gtk_dial_new(adjustment); gtk_dial_set_update_policy (GTK_DIAL(dial), GTK_UPDATE_DELAYED); /* gtk_widget_set_usize (dial, 100, 100); */ gtk_container_add (GTK_CONTAINER (frame), dial); gtk_widget_show (dial); label = gtk_label_new("0.00"); gtk_box_pack_end (GTK_BOX(vbox), label, 0, 0, 0); gtk_widget_show (label); gtk_signal_connect (GTK_OBJECT(adjustment), "value_changed", GTK_SIGNAL_FUNC (value_changed), label); gtk_widget_show (window); gtk_main (); return 0;}</PRE></TD></TR></TABLE></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="app-codeexamples.html"><<< Previous</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="gtk-tut.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="sec-scribble.html">Next >>></A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Code Examples</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="app-codeexamples.html">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Scribble</TD></TR></TABLE></DIV> </td> </tr></table> </td> </tr></table></body></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -