⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtk_tut_it-19.html

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 HTML
📖 第 1 页 / 共 4 页
字号:
guint          gtk_dial_get_type               (void);GtkAdjustment* gtk_dial_get_adjustment         (GtkDial      *dial);void           gtk_dial_set_update_policy      (GtkDial      *dial,                                                GtkUpdateType  policy);void           gtk_dial_set_adjustment         (GtkDial      *dial,                                                GtkAdjustment *adjustment);#ifdef __cplusplus}#endif /* __cplusplus */#endif /* __GTK_DIAL_H__ */</PRE></CODE></BLOCKQUOTE><P>Essendoci pi&ugrave; cose da fare con questo widget, rispetto al precedente,abbiamo pi&ugrave; cambi nella struttura dati, ma le altre cose sono abbastamza simili.<P>Dopo aver incluso i file di header e aver dichiarato alcune costanti,dobbiamo fornire alcune funzioni circa il widget e la suainizializzazione.<P><BLOCKQUOTE><CODE><PRE>#include &lt;math.h>#include &lt;stdio.h>#include &lt;gtk/gtkmain.h>#include &lt;gtk/gtksignal.h>#include "gtkdial.h"#define SCROLL_DELAY_LENGTH  300#define DIAL_DEFAULT_SIZE 100/* Dichiarazioni di funzioni successive */[ omesse per salvare spazio ]/* variabili locali. */static GtkWidgetClass *parent_class = NULL;guintgtk_dial_get_type (){  static guint dial_type = 0;  if (!dial_type)    {      GtkTypeInfo dial_info =      {        "GtkDial",        sizeof (GtkDial),        sizeof (GtkDialClass),        (GtkClassInitFunc) gtk_dial_class_init,        (GtkObjectInitFunc) gtk_dial_init,        (GtkArgSetFunc) NULL,        (GtkArgGetFunc) NULL,      };      dial_type = gtk_type_unique (gtk_widget_get_type (), &amp;dial_info);    }  return dial_type;}static voidgtk_dial_class_init (GtkDialClass *class){  GtkObjectClass *object_class;  GtkWidgetClass *widget_class;  object_class = (GtkObjectClass*) class;  widget_class = (GtkWidgetClass*) class;  parent_class = gtk_type_class (gtk_widget_get_type ());  object_class->destroy = gtk_dial_destroy;  widget_class->realize = gtk_dial_realize;  widget_class->expose_event = gtk_dial_expose;  widget_class->size_request = gtk_dial_size_request;  widget_class->size_allocate = gtk_dial_size_allocate;  widget_class->button_press_event = gtk_dial_button_press;  widget_class->button_release_event = gtk_dial_button_release;  widget_class->motion_notify_event = gtk_dial_motion_notify;}static voidgtk_dial_init (GtkDial *dial){  dial->button = 0;  dial->policy = GTK_UPDATE_CONTINUOUS;  dial->timer = 0;  dial->radius = 0;  dial->pointer_width = 0;  dial->angle = 0.0;  dial->old_value = 0.0;  dial->old_lower = 0.0;  dial->old_upper = 0.0;  dial->adjustment = NULL;}GtkWidget*gtk_dial_new (GtkAdjustment *adjustment){  GtkDial *dial;  dial = gtk_type_new (gtk_dial_get_type ());  if (!adjustment)    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);  gtk_dial_set_adjustment (dial, adjustment);  return GTK_WIDGET (dial);}static voidgtk_dial_destroy (GtkObject *object){  GtkDial *dial;  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_DIAL (object));  dial = GTK_DIAL (object);  if (dial->adjustment)    gtk_object_unref (GTK_OBJECT (dial->adjustment));  if (GTK_OBJECT_CLASS (parent_class)->destroy)    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);}</PRE></CODE></BLOCKQUOTE><P>Notate che questa funzione <CODE>init()</CODE> fa meno rispetto all'analoga delwidget Tictactoe, essendo questo un widget non composto, e la funzione <CODE>new()</CODE> fa di pi&ugrave;, essendoci un argomento. Inoltre, notate che quando memorizziamo un puntatore all'oggetto Adjustment,incrementiamo il conteggio dei suoi riferimenti(e corrispondentemente lo decrementato quando non lo usiamo pi&ugrave;) cos&igrave; che GTK pu&ograve; tener traccia di quando &egrave; possibile distruggerlo senza causare guai.<P><P>Inoltre, ci sono alcune funzioni per manipolare le opzioni del widget:<P><BLOCKQUOTE><CODE><PRE>GtkAdjustment*gtk_dial_get_adjustment (GtkDial *dial){  g_return_val_if_fail (dial != NULL, NULL);  g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);  return dial->adjustment;}voidgtk_dial_set_update_policy (GtkDial      *dial,                             GtkUpdateType  policy){  g_return_if_fail (dial != NULL);  g_return_if_fail (GTK_IS_DIAL (dial));  dial->policy = policy;}voidgtk_dial_set_adjustment (GtkDial      *dial,                          GtkAdjustment *adjustment){  g_return_if_fail (dial != NULL);  g_return_if_fail (GTK_IS_DIAL (dial));  if (dial->adjustment)    {      gtk_signal_disconnect_by_data (GTK_OBJECT (dial->adjustment), (gpointer) dial);      gtk_object_unref (GTK_OBJECT (dial->adjustment));    }  dial->adjustment = adjustment;  gtk_object_ref (GTK_OBJECT (dial->adjustment));  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",                      (GtkSignalFunc) gtk_dial_adjustment_changed,                      (gpointer) dial);  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",                      (GtkSignalFunc) gtk_dial_adjustment_value_changed,                      (gpointer) dial);  dial->old_value = adjustment->value;  dial->old_lower = adjustment->lower;  dial->old_upper = adjustment->upper;  gtk_dial_update (dial);}</PRE></CODE></BLOCKQUOTE><P><H3><CODE>gtk_dial_realize()</CODE></H3><P>Abbiamo ora raggiunto alcuni nuovi tipi di funzione. In primo luogo,abbiamo una funzione che crea la finestra di X. Noterete che vienepassata alla funzione <CODE>gdk_window_new()</CODE> una maschera che specifica quali campi della struttura GdkWindowAttr non sono vuoti (ai rimanenti campi pu&ograve; essere dato il valore predefinito). Anche il modo con cui la maschera degli eventi del widget  creata non &egrave;complicato. Chiameremo <CODE>gtk_widget_get_events()</CODE> per sapere la maschera degli eventi che l'utente ha specificato per questo widget(con <CODE>gtk_widget_set_events()</CODE>) e aggiungeremo gli eventi che ci possono interessare.<P><P>Dopo aver creato la finestra, settiamo lo stile e lo sfondo,e creiamo un puntatore al widget nel campo dei dati utente (user data)del GdkWindow. Quest'ultimo passo permette a GTK di mandare gli eventi della finestra al widget corretto.<P><BLOCKQUOTE><CODE><PRE>static voidgtk_dial_realize (GtkWidget *widget){  GtkDial *dial;  GdkWindowAttr attributes;  gint attributes_mask;  g_return_if_fail (widget != NULL);  g_return_if_fail (GTK_IS_DIAL (widget));  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);  dial = GTK_DIAL (widget);  attributes.x = widget->allocation.x;  attributes.y = widget->allocation.y;  attributes.width = widget->allocation.width;  attributes.height = widget->allocation.height;  attributes.wclass = GDK_INPUT_OUTPUT;  attributes.window_type = GDK_WINDOW_CHILD;  attributes.event_mask = gtk_widget_get_events (widget) |     GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |     GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |    GDK_POINTER_MOTION_HINT_MASK;  attributes.visual = gtk_widget_get_visual (widget);  attributes.colormap = gtk_widget_get_colormap (widget);  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;  widget->window = gdk_window_new (widget->parent->window, &amp;attributes, attributes_mask);  widget->style = gtk_style_attach (widget->style, widget->window);  gdk_window_set_user_data (widget->window, widget);  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);}</PRE></CODE></BLOCKQUOTE><P><H3>Negoziazione della dimensione</H3><P>Prima di visualizzare per la prima volta la finestra, e  se il layout della finestra cambia, GTK chiede ad ogni widget, incluso nellafinestra, la propria dimensione. Questa richiesta &egrave; fatta dallafunzione  <CODE>gtk_dial_size_request()</CODE>. Non essendo il nostro widget un contenitore, e non avendo dei veri limiti per la propriadimensione, restituiamo semplicemnte un valore ragionevole.<P><BLOCKQUOTE><CODE><PRE>static void gtk_dial_size_request (GtkWidget      *widget,                       GtkRequisition *requisition){  requisition->width = DIAL_DEFAULT_SIZE;  requisition->height = DIAL_DEFAULT_SIZE;}</PRE></CODE></BLOCKQUOTE><P><P>Dopo che tutti i widget hanno restituito una dimensione ideale, viene calcolata la disposizione della finestra  e ad ogni widget figlio &egrave;notificata la propria dimensione attuale . Usualmente, questo sar&agrave; almeno quanto richiesto, ma occasionalmente pu&ograve; essere pi&ugrave; piccolo. La notifica della dimensione  viene fatta dalla funzione<CODE>gtk_dial_size_allocate()</CODE>. Notate che questa funzione &egrave; utilizzataanche quando la finestra X del widget &egrave; spostata o modificata come dimensione.<P><BLOCKQUOTE><CODE><PRE>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;  if (GTK_WIDGET_REALIZED (widget))    {      dial = GTK_DIAL (widget);      gdk_window_move_resize (widget->window,                              allocation->x, allocation->y,                              allocation->width, allocation->height);      dial->radius = MAX(allocation->width,allocation->height) * 0.45;      dial->pointer_width = dial->radius / 5;    }}</PRE></CODE></BLOCKQUOTE>.<P><H3><CODE>gtk_dial_expose()</CODE></H3><P>Come menzionato sopra, tutto il lavoro di questo widget viene fatto nellagestione dell'evento ``expose''. Non c'&egrave; molto da notare su questo eccettol'uso della funzione <CODE>gtk_draw_polygon</CODE> per disegnare il puntatore con un'ombreggiatura a tre dimensioni in accordo con il colorememorizzato nello stile del wiget.<P><BLOCKQUOTE><CODE><PRE>static gintgtk_dial_expose (GtkWidget      *widget,                 GdkEventExpose *event){  GtkDial *dial;  GdkPoint points[3];  gdouble s,c;  gdouble theta;  gint xc, yc;  gint tick_length;  gint i;  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;  /* Draw ticks */  for (i=0; i&lt;25; i++)    {      theta = (i*M_PI/18. - M_PI/6.);      s = sin(theta);      c = cos(theta);      tick_length = (i%6 == 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);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -