SCROLLBAR E SCALE WIDGET

 

Questi due widget rientrano nella categoria dei Range-Widget e sono molto simili nell'implementazione.

Scrollbar Widgets

Sono usati per scrollare altri widget come liste e testi.
Ci sono due separati tipi per scrollbar orizzontali e verticali.
Per creare una nuova scrollbar useremo le funzioni:

GtkWidget *gtk_hscrollbar_new( GtkAdjustment *adjustment );

GtkWidget *gtk_vscrollbar_new( GtkAdjustment *adjustment );

L'argomento adjustment può essere un puntatore ad un GtkAdjustment esistente, o NULL, nel qual caso ne sarà creato uno nuovo, cosa che di solito si usa normalmente in questo caso.

Scale Widgets

Gli Scale widgets sono usati per selezionare a manipolare un valore all'interno di uno specifico range come ad esempio specificare il numero di minuti dopo i quali deve partire uno screen-saver.

Come per le scrolbar ci sono due diferenti tipi (orizzontale e verticale) per i Scale Widget.
Per creare un nuovo scale widget useremo:

GtkWidget *gtk_vscale_new( GtkAdjustment *adjustment );

GtkWidget *gtk_hscale_new( GtkAdjustment *adjustment );

Anche in questo caso se diamo NULL all'argomento adjustment ne sarà automaticamente creato uno per noi.

Functions and Signals (well, functions, at least)

Per cambiare il valore di default di uno scale widget si può usare la funzione:

void gtk_scale_set_draw_value( GtkScale *scale,
gint draw_value );

Il valore mostrato da un scale widget è settato di default ad un decimale, si può cambiare questo con la funzione::

void gtk_scale_set_digits( GtkScale *scale,
gint digits );

dove digits è il numero di decimali che si vogliono.

Il valore può inoltre essere visualizzato in diverse posizioni:

void gtk_scale_set_value_pos( GtkScale *scale,
GtkPositionType pos );

Dove l'argomento pos può asumenre uno dei seguenti valori:

GTK_POS_LEFT
GTK_POS_RIGHT
GTK_POS_TOP
GTK_POS_BOTTOM

Funzioni Comuni

Queste riguardano tutti i range-widget.

L' "update policy" di un range widget definisce quando deve essere emesso il segnale "value_changed":

GTK_UPDATE_POLICY_CONTINUOUS - E' il default. Il segnale viene emesso continuativamente.

GTK_UPDATE_POLICY_DISCONTINUOUS - Il segnale viene emesso discontinuamente.

GTK_UPDATE_POLICY_DELAYED - Il segnale viene emesso quando l'utente rilascia il bottone del mouse.

Per settare l' update policy si usa la funzione:

void gtk_range_set_update_policy( GtkRange *range,
GtkUpdateType policy) ;

Per ricavare o settare un ajustment collegato ad un range widget si usano:

GtkAdjustment* gtk_range_get_adjustment( GtkRange *range );

void gtk_range_set_adjustment( GtkRange *range,
GtkAdjustment *adjustment );

 

 

ESEMPIO

#include <gtk/gtk.h>

GtkWidget *hscale, *vscale;

void cb_pos_menu_select( GtkWidget *item,
GtkPositionType pos )
{
/* Setta il value position di entrambi gli scale widgets */
gtk_scale_set_value_pos (GTK_SCALE (hscale), pos);
gtk_scale_set_value_pos (GTK_SCALE (vscale), pos);
}

void cb_update_menu_select( GtkWidget *item,
GtkUpdateType policy )
{
/* Setta la update policy per entrambe le scale widgets */
gtk_range_set_update_policy (GTK_RANGE (hscale), policy);
gtk_range_set_update_policy (GTK_RANGE (vscale), policy);
}

void cb_digits_scale( GtkAdjustment *adj )
{
/* Setta il numero dei decimali */
gtk_scale_set_digits (GTK_SCALE (hscale), (gint) adj->value);
gtk_scale_set_digits (GTK_SCALE (vscale), (gint) adj->value);
}

void cb_page_size( GtkAdjustment *get,
GtkAdjustment *set )
{
/* Setta il page size e il page increment */
set->page_size = get->value;
set->page_increment = get->value;
/* Ora emette i segnale "changed" per riconfigurare tutti
* i widget collegati alladjustment */
gtk_signal_emit_by_name (GTK_OBJECT (set), "changed");
}

void cb_draw_value( GtkToggleButton *button )
{
/* Setta il valore della scale widgets */
gtk_scale_set_draw_value (GTK_SCALE (hscale), button->active);
gtk_scale_set_draw_value (GTK_SCALE (vscale), button->active);
}

GtkWidget *make_menu_item( gchar *name,
GtkSignalFunc callback,
gpointer data )
{
GtkWidget *item;

item = gtk_menu_item_new_with_label (name);
gtk_signal_connect (GTK_OBJECT (item), "activate",
callback, data);
gtk_widget_show (item);

return(item);
}

void scale_set_default_values( GtkScale *scale )
{
gtk_range_set_update_policy (GTK_RANGE (scale),
GTK_UPDATE_CONTINUOUS);
gtk_scale_set_digits (scale, 1);
gtk_scale_set_value_pos (scale, GTK_POS_TOP);
gtk_scale_set_draw_value (scale, TRUE);
}

/* crea la finestra per l'esempio */

void create_range_controls( void )
{
GtkWidget *window;
GtkWidget *box1, *box2, *box3;
GtkWidget *button;
GtkWidget *scrollbar;
GtkWidget *separator;
GtkWidget *opt, *menu, *item;
GtkWidget *label;
GtkWidget *scale;
GtkObject *adj1, *adj2;

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);
gtk_window_set_title (GTK_WINDOW (window), "range controls");

box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show (box1);

box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);

adj1 = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);

vscale = gtk_vscale_new (GTK_ADJUSTMENT (adj1));
scale_set_default_values (GTK_SCALE (vscale));
gtk_box_pack_start (GTK_BOX (box2), vscale, TRUE, TRUE, 0);
gtk_widget_show (vscale);

box3 = gtk_vbox_new (FALSE, 10);
gtk_box_pack_start (GTK_BOX (box2), box3, TRUE, TRUE, 0);
gtk_widget_show (box3);

/* Riusiamo lo stesso adjustment */
hscale = gtk_hscale_new (GTK_ADJUSTMENT (adj1));
gtk_widget_set_usize (GTK_WIDGET (hscale), 200, 30);
scale_set_default_values (GTK_SCALE (hscale));
gtk_box_pack_start (GTK_BOX (box3), hscale, TRUE, TRUE, 0);
gtk_widget_show (hscale);

/* Riusiamo ancora lo stesso adjustment */
scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adj1));
gtk_range_set_update_policy (GTK_RANGE (scrollbar),
GTK_UPDATE_CONTINUOUS);
gtk_box_pack_start (GTK_BOX (box3), scrollbar, TRUE, TRUE, 0);
gtk_widget_show (scrollbar);

box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);

/* Un checkbutton per controllare se il value è visualizzato o no*/
button = gtk_check_button_new_with_label("Display value on scale widgets");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_signal_connect (GTK_OBJECT (button), "toggled",
GTK_SIGNAL_FUNC(cb_draw_value), NULL);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);

box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);

/* Un option menu per cambiare la posizione del value */
label = gtk_label_new ("Scale Value Position:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);

opt = gtk_option_menu_new();
menu = gtk_menu_new();

item = make_menu_item ("Top",
GTK_SIGNAL_FUNC(cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_TOP));
gtk_menu_append (GTK_MENU (menu), item);

item = make_menu_item ("Bottom", GTK_SIGNAL_FUNC (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_BOTTOM));
gtk_menu_append (GTK_MENU (menu), item);

item = make_menu_item ("Left", GTK_SIGNAL_FUNC (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_LEFT));
gtk_menu_append (GTK_MENU (menu), item);

item = make_menu_item ("Right", GTK_SIGNAL_FUNC (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_RIGHT));
gtk_menu_append (GTK_MENU (menu), item);

gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu);
gtk_box_pack_start (GTK_BOX (box2), opt, TRUE, TRUE, 0);
gtk_widget_show (opt);

gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);

box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);

/* Un altro option menu per l'update policy della
* scale widgets */
label = gtk_label_new ("Scale Update Policy:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);

opt = gtk_option_menu_new();
menu = gtk_menu_new();

item = make_menu_item ("Continuous",
GTK_SIGNAL_FUNC (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_CONTINUOUS));
gtk_menu_append (GTK_MENU (menu), item);

item = make_menu_item ("Discontinuous",
GTK_SIGNAL_FUNC (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_DISCONTINUOUS));
gtk_menu_append (GTK_MENU (menu), item);

item = make_menu_item ("Delayed",
GTK_SIGNAL_FUNC (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_DELAYED));
gtk_menu_append (GTK_MENU (menu), item);

gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu);
gtk_box_pack_start (GTK_BOX (box2), opt, TRUE, TRUE, 0);
gtk_widget_show (opt);

gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);

box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);

/* Una GtkHScale widget per aggiustare il numero dei digits */
label = gtk_label_new ("Scale Digits:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);

adj2 = gtk_adjustment_new (1.0, 0.0, 5.0, 1.0, 1.0, 0.0);
gtk_signal_connect (GTK_OBJECT (adj2), "value_changed",
GTK_SIGNAL_FUNC (cb_digits_scale), NULL);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adj2));
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
gtk_widget_show (scale);

gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);

box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);

/* E una GtkHScale widget per aggiustare la page size della
* scrollbar. */
label = gtk_label_new ("Scrollbar Page Size:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);

adj2 = gtk_adjustment_new (1.0, 1.0, 101.0, 1.0, 1.0, 0.0);
gtk_signal_connect (GTK_OBJECT (adj2), "value_changed",
GTK_SIGNAL_FUNC (cb_page_size), adj1);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adj2));
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
gtk_widget_show (scale);

gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);

separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
gtk_widget_show (separator);

box2 = gtk_vbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
gtk_widget_show (box2);

button = gtk_button_new_with_label ("Quit");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);

gtk_widget_show (window);
}

int main( int argc,
char *argv[] )
{
gtk_init(&argc, &argv);

create_range_controls();

gtk_main();

return(0);
}

 

Torna all'indice