Выравнивание

Иерархия наследования

Object +--- Data +--- Adjustment

Gtk имеют несколько типов виджетов, которые могут быть визуально расставлены пользователем при помощи клавиатуры и мыши, подобно range widgets, описанных в соответствующей главе. Есть так-же несколько виджетов, которые показывают показ текста или иного вида данных в соответствии с размером облисти их отображения. Например text widget или viewport widget.

Очевидно, что приложение должно уметь реагировать на изменения, которые пользователь вносит в отображение виджета. Один путь для реализации этой концепции состоит в том, чтобы каждый виджет испускал собственный сигнал при изменении его размеров и любое изменение этого размера будет сопровождаться сопоставлением с данными внутри виждета и соответственно как-то это изменение отрабатывать для каждого виджета. Другойпуть заключается в том, чтобы изменение одного виджета провоцировало изменение других виджетов, то есть связанное изменение. Наиболее очевидным примером для этого может являться связка scrollbar-panning viewport или scrollbar-text area. В случае, когда каждый виджет отдельно обрабабатывает изменение своих размеров, разработчику необходимо связывать воедино изменения различных элементов так, чтобы они вели себя как единое целое.

Gtk решает эту проблему при помощи Adjustment object, который не является виджетом, но заставляет виджет хранить и передавать информацию в абстрактрой и гибкой форме. Примером такого реглирования является хранение конфигурационных параметров и их изменение в соответствии с виджетными размерами, например scrollbars и scale controls. Однако, так как регулирование наследуется из объекта, видоизменяемые виджеты имеют некоторые специфические возможности в отличие от нормальных структур данных. Наиболее важным в регулировании отображения виджетов является то, что такие свойства виджетов мугут выдавать сигналы, подобные выдаваемым виджетами при совершении над последними каких-то действий, и эти сигналы могут давать соответствующую регулировку для остальных виджетов(например в пропорциях между ними). К сожалению, выравнивание может быть довольно трудной концепцией в тех случаях, когда нет визуальных примеров, показывающих её дейтсвие например при работе виджетов, подобных progress bars, viewports, scrolled windows и им подобных.

Определение объекта, отвечающего за выравнивание

Некоторые виджеты в случае пользоватльского вмешательства видоизменяются пропорциональным образом автоматически, но в некоторых случаях(которые будутпоказаны позднее в примерах) операцию изменения приходится проделывать автоматически. Создать объект, отвечающий за такой тип взаимодействия между виджетами, можно при помощи функции Gtk::Adjustment():

new Gtk::Adjustment( $value, $lower, $upper, $step_increment, $page_increment, $page_size );

Перемення $valie - начальное значение, которое необходимо сохранить при изменении элементов окна, оно обычно соответствует левому верхнему положению элементов. Переменная $lower является минимальным значением, которе будет изменятся в соответствии с парвилами всего Adjustment. Переменная $step_increment определяет минимальное значение, из двух приращений, которое может инициировать пользователь, соответственно переменная $page_increment является максимальным допустимым изменяемым значением. Переменная $page_size соответствует видимой части виджета. Переменная $upper используется для выбора, что изменять в первую очередь, нижнюю или правую часть дочернего отображаемого виджета. Поэтому она не обладает наибольшим значением которое моежт иметь $value.

Использование авторегуляции виджетов.

Виджеты описываемой группы могут быть грубо разделены на те, которые настраиваются разработчиками, и те, которые все "делают" автомтически. К автоподстраиваемым виджетам относятся скроллбары, скейлы, прогрессбары и кнопки прокрутки. Эти виджеты являются виджетами, которые автоматически подстраивают свои размеры в соответствии с действиями пользователя.

Другая группа виджетов включает в себя text widget, viewport, CList и scrolles window. Все они используют попиксельное позиционирование. Также эти виджеты ковенно используют позиционирование при помощи скроллбаров.

Нижеследующий английский текст переводчик до конца не понял и будет благодарен за правильный его перевод

While all widgets which use adjustments can either create their own adjustments or use ones you supply, you'll generally want to let this particular category of widgets create its own adjustments. Usually, they will eventually override all the values except the value itself in whatever adjustments you give them, but the results are, in general, undefined (meaning, you'll have to read the source code to find out, and it may be different from widget to widget).

Now, you might be thinking, since text widgets and viewports insist on setting everything except the value of their adjustments, while scrollbars will only touch the adjustment's value, if you share an adjustment object between a scrollbar and a text widget, will manipulating the scrollbar automagically adjust the text widget? Of course it will! Just like this:

# creates its own adjustments $text = new Gtk::Text( "", "" ); # uses the newly-created adjustment for the scrollbar as well $vscrollbar = new Gtk::VScrollbar( $text->vadj );

Внутреннее регулирование

Если необходимо создать собственный механизм регулирования взаимного (пере- ?)расположения виджетов, то в Gtk-Perl возможно было бы использовать

get_adjustment->adjustment_name

где adjustment_name любая величина из перечисленных value, lower, upper, step_increment, page_increment, или page_size. Если необходимо переопределить значение какого-либо вида выравнивания для всех виджетов одним махом, то пишется строчка:

$adjustment->set_value( $value );

Как было упомянуто ранее, регулирование может инициировать сигналы в случае, когда, например, изменяется значение для сроллбара и вместе с ним текст внутри окна, где действует скроллбар.

Различные виджеты, которые используют объект выравнивания, испускают сигнал при изменении значения переменных, ответственных за виджеты(возможно, неправилен смысл перевода). Например, если имеется скейл-виджет и необходимо повращать картинку всякий раз, когда изменяются значения, влияющие на выравнивание, то используется следующий код:

sub cb_rotate_picture { ( $adjustment, $picture ) = @_; $picture->rotation( $adjustment->get_adjustment->value ); ... }

и далее соединяемся со скейл-виджетом, ответственным за выравнивание примерно так:

$adjustment->signal_connect( "value_changed", \&cb_rotate_picture, $picture );

В слече, если пользователь добавляет текст к текстовому виджету, то меняются значения переменной upper или lower и испускается сигнал 'changed'.

Range widgets typically connect a handler to this signal, which changes their appearance to reflect the change - for example, the size of the slider in a scrollbar will grow or shrink in inverse proportion to the difference between the lower and upper values of its adjustment.

You probably won't ever need to attach a handler to this signal, unless you're writing a new type of range widget. However, if you change any of the values in a Adjustment directly, you should emit this signal on it to reconfigure whatever widgets are using it, like this:

$adjustment->emit_by_name( "changed" );