#include <gtk/gtk.h>
gtkwidget *hscale, *vscale;
void cb_pos_menu_select( gtkwidget *item,
gtkpositiontype pos )
{
/* устанавливаем позицию виджетов масштабирования */
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 )
{
/* устанавливаем "политику обновления" виджетов масштабирования */
gtk_range_set_update_policy (gtk_range (hscale), policy);
gtk_range_set_update_policy (gtk_range (vscale), policy);
}
void cb_digits_scale( gtkadjustment *adj )
{
/* устанавливаем десятичное значение до которого происходит округление adj->value */
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 )
{
/* устанавливаем размер страницы и размер увеличения (page increment)
* регулятором определённое значением масштаба "page size" */
set->page_size = get->value;
set->page_increment = get->value;
/* создаём регулятор и сигнал "changed" для перенастройки
всех виджетов связанных с этим сигналом. */
gtk_adjustment_set_value (set, clamp (set->value,
set->lower,
(set->upper - set->page_size)));
}
void cb_draw_value( gtktogglebutton *button )
{
/* включаем или выключаем отображение значения виджетов масштабирования
* в зависимости от состояния контроль-кнопки (checkbutton) */
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,
gcallback callback,
gpointer data)
{
gtkwidget *item;
item = gtk_menu_item_new_with_label (name);
g_signal_connect (g_object (item), "activate",
callback, (gpointer) 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);
}
/* создаём типовое окно */
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);
g_signal_connect (g_object (window), "destroy",
g_callback (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);
/* значение уменьшения(lower), увеличения(upper),
пошаговой инкрементации(step_increment),
постраничной(page_increment), размер страницы(page_size) */
/* заметьте, что значение page_size фактически равно наибольшему значению
* scrollbar widgets (upper - page_size). */
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);
/* многочисленные настройки */
hscale = gtk_hscale_new (gtk_adjustment (adj1));
gtk_widget_set_size_request (gtk_widget (hscale), 200, -1);
scale_set_default_values (gtk_scale (hscale));
gtk_box_pack_start (gtk_box (box3), hscale, true, true, 0);
gtk_widget_show (hscale);
/* ещё раз те же самые настройки */
scrollbar = gtk_hscrollbar_new (gtk_adjustment (adj1));
/* обратите внимание на постоянное обновление регулировок
* когда происходит перемещение scrollbar */
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);
/* отображать или нет значение контролируется с помощью контроль-кнопки (checkbutton) */
button = gtk_check_button_new_with_label("display value on scale widgets");
gtk_toggle_button_set_active (gtk_toggle_button (button), true);
g_signal_connect (g_object (button), "toggled",
g_callback (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);
/* опционное меню для изменения значения позиции */
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",
g_callback (cb_pos_menu_select),
gint_to_pointer (gtk_pos_top));
gtk_menu_shell_append (gtk_menu_shell (menu), item);
item = make_menu_item ("bottom", g_callback (cb_pos_menu_select),
gint_to_pointer (gtk_pos_bottom));
gtk_menu_shell_append (gtk_menu_shell (menu), item);
item = make_menu_item ("left", g_callback (cb_pos_menu_select),
gint_to_pointer (gtk_pos_left));
gtk_menu_shell_append (gtk_menu_shell (menu), item);
item = make_menu_item ("right", g_callback (cb_pos_menu_select),
gint_to_pointer (gtk_pos_right));
gtk_menu_shell_append (gtk_menu_shell (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);
/* еще одно меню опций, на сей раз для политики обновления виджетов масштаба */
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",
g_callback (cb_update_menu_select),
gint_to_pointer (gtk_update_continuous));
gtk_menu_shell_append (gtk_menu_shell (menu), item);
item = make_menu_item ("discontinuous",
g_callback (cb_update_menu_select),
gint_to_pointer (gtk_update_discontinuous));
gtk_menu_shell_append (gtk_menu_shell (menu), item);
item = make_menu_item ("delayed",
g_callback (cb_update_menu_select),
gint_to_pointer (gtk_update_delayed));
gtk_menu_shell_append (gtk_menu_shell (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);
/* виджет hscale для того, чтобы регулировать число цифр в типовых масштабах. */
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);
g_signal_connect (g_object (adj2), "value_changed",
g_callback (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);
/* и, один последний виджет hscale для того, чтобы регулировать размер страницы полосы прокрутки.*/
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);
g_signal_connect (g_object (adj2), "value_changed",
g_callback (cb_page_size), (gpointer) 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");
g_signal_connect_swapped (g_object (button), "clicked",
g_callback (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;
}
|