# bind

Команда bind позволяет привязать выполнение скриптов Tcl к X событиям. Команда назначает событиям ввода от "Мыши" и клавиатуры (Х событиям) исполнение скрипта Tcl.

## СИНТАКСИС

          bind тег
          bind тег последовательность
          bind тег последовательность скрипт
          bind тег последовательность +скрипт

## ОПИСАНИЕ

Команда bind привязывает Tcl скрипты к X событиям. Если заданы все три аргумента команды, то при каждом наступлении события последовательность в окне (окнах), описанных тегом, будет выполняться скрипт (скрипт Tcl). Если аргументу скрипт предшествует знак +, то скрипт добавляется к уже существующим привязкам к последовательности; в противном случае он замещает все имеющиеся привязки. Если аргумент скрипт пуст, то все имеющиеся привязки к последовательности отменяются, и последовательность становится несвязанной. Если аргумент скрипт присутствует, то команда bind возвращает пустую строку.

Если при отсутствии аргумента скрипт аргумент последовательность задан, то команда возвращает скрипт, привязанный к данной последовательности, или, в случае отсутствия такого скрипта, пустую строку. Если не задан ни один из аргументов последовательность и скрипт, то команда возвращает список, элементами которого служат все последовательности, имеющие привязки к окну тег.

Аргумент тег перечисляет окна, к которым выполняется привязка. Если значение аргумента начинается с точки, скажем ".a.b.c", то оно должно представлять собой путь к окну; в противном случае оно может быть произвольной строкой. Каждому окну приписан некоторый список тегов, и привязка к данному окну осуществляется, если значение аргумента тег присутствует в этом списке. Команда bindtags позволяет приписать окну произвольный набор тегов привязки; кроме того, по умолчанию окнам приписаны следующие теги:

- тег, являющийся именем внутреннего окна, приписывается этому окну;
- тег, являющийся именем окна верхнего уровня, приписывается этому окну и всем его внутренним окнам;
- тег, являющийся именем класса примитивов, скажем Button, приписывается всем примитивам этого класса;
- тег с именем all приписывается всем окнам приложения.

## ОБРАЗЦЫ СОБЫТИЙ

Аргумент последовательность представляет собой последовательность одного или нескольких образцов событий. Каждый образец может быть записан в одном из трех видов. В простейшем случае это символ ASCII, скажем a или |. Этот символ не может быть пробелом или знаком <. Этот вид образцов соответствует событию KeyPress для конкретной клавиши. Образцы второго вида длиннее, однако, этот вид носит более общий характер. Его синтаксис выглядит следующим образом:

          <модификатор-модификатор-тип-детализация>

Образец события целиком заключен в угловые скобки. Внутри угловых скобок располагаются несколько модификаторов (быть может, ни одного), тип события и дополнительная порция информации (детализация), указывающая конкретную кнопку или комбинацию клавиш. Одно из полей тип или детализация должно обязательно присутствовать, остальные могут быть опущены. Поля разделяются пробелами или дефисами.

Третья форма образца используется для задания поименованного виртуального события, определенного пользователем. У нее следующий синтаксис:

          <<имя>>

Образец события целиком заключен в двойные угловые скобки. Внутри этих скобок содержится определенное пользователем имя виртуального события. С виртуальным событием нельзя комбинировать модификаторы, такие как Shiftили Control. Привязки к виртуальному событию можно создавать до описания самого события; при динамическом изменении этого описания все окна, привязанные к событию, будут обращаться к новому описанию.

## МОДИФИКАТОРЫ

Модификаторы могут быть следующими:

- Alt
- Button1, B1
- Button2, B2
- Button3, B3
- Button4, B4
- Button5, B5
- Control
- Double
- Lock
- Meta, M
- Mod1, M1
- Mod2, M2
- Mod3, M3
- Mod4, M4
- Mod5, M5
- Shift
- Triple

Если в строке приведено несколько элементов, разделенных запятыми, то они взаимозаменяемы. У большинства модификаторов есть очевидное X значение. Например, модификатор Button1 требует нажатия кнопки 1 для наступления события. Чтобы привязка соответствовала данному событию, среди модификаторов события должны содержаться все модификаторы, заданные в образце события. Кроме того событие может содержать и другие модификаторы, не приведенные в описании привязки. Например, при нажатии кнопки 1 одновременно с нажатием клавиш Shift и Ctrl событие подойдет под образец <Control-Button-1>, но не подойдет под образец <Mod1-Button-1>. Если ни один из модификаторов не был задан, то в событии может присутствовать любая комбинация модификаторов.

Модификаторы Meta и M заменяют любой из идентификаторов от M1 до M5, ассоциированный с метаклавишами на клавиатуре (коды клавиш Meta_R и Meta_L). При отсутствии метаклавиш или в случае, если они не ассоциированы ни с каким модификатором, модификаторы Meta и M не будут соответствовать никакому событию. Аналогично модификатор Alt заменяет любой из модификаторов, ассоциированных с alt-клавишами на клавиатуре (коды клавиш Alt_L и Alt_R).

Модификаторы Doubleи Triple обеспечивают удобную обработку двойного щелчка .Мыши. и других повторяющихся событий. Они требуют, чтобы данное событие повторилось дважды или трижды, и накладывают ограничения на время и место его повторения: для того, чтобы последовательность событий подходила под образец Double или Triple, промежуток времени между событиями должен быть коротким, а "Мышь" не должна сдвигаться. Например, комбинация <Double-Button-1> эквивалентна паре <Button-1><Button-1> с дополнительными временными и пространственными ограничениями.

## ТИПЫ СОБЫТИЙ

Значением поля тип может быть любой из стандартных типов X событий, а также некоторые дополнительные сокращения. Ниже приведен список всех допустимых значений. Два имени, составляющие пару, синонимичны.

- Activate
- Button
- ButtonPress
- ButtonRelease
- Circulate
- Colormap
- Configure
- Deactivate
- Destroy
- Enter
- Expose
- FocusIn
- FocusOut
- Gravity
- Key Unmap
- KeyPress
- KeyRelease
- Leave
- Map
- Motion
- Property
- Reparent
- Visibility

Последней частью длинной спецификации события является детализация. Для типов ButtonPress и ButtonRelease это номер кнопки (1-5). Если номер кнопки задан, то под образец подойдет только событие на указанной кнопке; если номер кнопки не задан, то под образец подойдет событие на любой из кнопок. Замечание: задание номера кнопки отличается от задания модификатора кнопки: в первом случае требуется, чтобы кнопка была нажата или отжата; во втором чтобы какая-то другая кнопка была отжата при наступлении события. Если номер кнопки задан, то поле тип можно опустить: по умолчанию оно будет иметь значение ButtonPress. Например, спецификатор <1> эквивалентен спецификатору <ButtonPress-1>.

Для типов KeyPress и KeyRelease детализацию можно указать в виде описателя X клавиши. В их число входят все алфавитно-цифровые символы ASCII (например, описатель a служит для описания символа ASCII "a"), а также описатели для неалфавитно-цифровых символов (описатель comma для запятой) и описатели для всех не ASCII-клавиш клавиатуры (Shift_L для левой клавиши верхнего регистра, F1 для первой функциональной клавиши при ее наличии). Мы не приводим здесь полный список клавиш. Он меняется от системы к системе, и его можно найти в других частях X документации. При необходимости можно получить описатель клавиши с помощью обозначения %K, описанного ниже. Если приведена детализация описателя клавиши, то поле тип может отсутствовать, по умолчанию принимается значение KeyPress. Например, спецификатор <Control-comma> эквивалентен спецификатору <Control-KeyPress-comma>.

## ПОДСТАНОВКИ И СКРИПТЫ ПРИВЯЗКИ

Аргумент скрипт команды bind должен быть скриптом Tcl; при каждом наступлении события происходит выполнение этого скрипта. Команда выполняется тем же интерпретатором, что и команда bind, причем интерпретация происходит на верхнем уровне (доступны только значения глобальных переменных). Если в скрипте есть символы %, то его исполнение не будет осуществляться непосредственно. Каждый символ % и символ, следующий за ним, заменяются данными о происшедшем событии, в результате чего генерируется новый скрипт. Подстановка осуществляется в соответствии с приводимым ниже списком символов. Если не оговорено противное, то подставляемая строка представляет собой десятичное содержимое указанного поля события. Некоторые подстановки допустимы только для событий определенных типов: при использовании их с событиями других типов результат подстановки не определен.

%%
  Заменяется однократным процентом.
%#
  Номер последнего обработанного сервером запроса клиента (сериальное поле события). Допустимо для событий всех типов.
%a
  Поле выше события, отформатированное как шестнадцатеричное число. Допустимо только для событий Configure.
%b
  Номер нажатой или отпущенной кнопки. Допустимо только для событий ButtonPress и ButtonRelease.
%c
  Поле счетчик события. Допустимо только для событий Expose.
  %d
  Поле детализация события. Символы %d заменяются строкой детализации. Для событий Enter, Leave, FocusIn, FocusOut строка должна быть одной из следующих: NotifyAncestor, NotifyNonlinearVirtual NotifyDetailNone, NotifyPointer, NotifyInterior, NotifyPointerRoot, NotifyNonlinear, NotifyVirtual.

  Для прочих событий подставляемая строка не определена.

%f
  Поле фокус события (0 или 1). Допустимо только для событий Enter и Leave.
%h
  Поле высота события. Допустимо только для событий Configure и Expose.
%k
  Поле код_клавиши события. Допустимо только для событий KeyPress и KeyRelease.
%m
  Поле режим события. Подставляется одна из строк NotifyNormal, NotifyGrab, NotifyUngrab или NotifyWhileGrabbed. Допустимо только для событий Enter, FocusIn, FocusOut и Leave.
%o
  Поле подавить_перенаправление события.Допустимо только для событий Map, Reparent и Configure.
%p
  Поле размещать события. Строка подстановки имеет вид PlaceOnTop или PlaceOnBottom. Допустимо только для событий Circulate.
%s
  Поле состояние события. Для событий ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave и Motion происходит подстановка десятичного числа. Для события Visibility подставляется одна из строк isibilityUnobscured, VisibilityPartiallyObscured или VisibilityFullyObscured.
%t
  Поле время события. Допустимо только для событий, содержащих поле время.
%w
  Поле ширина события. Допустимо только для событий Configure и Expose.
%x
  Поле x события. Допустимо только для событий, содержащих поле x.
%y
  Поле y события.Допустимо только для событий, содержащих поле y.
%A
  Заменяется символом ASCII, отвечающим происшедшему событию,или пустой строкой, если событию не соответствует никакой символ ASCII (например, нажата клавиша верхнего регистра). Работу по переводу события в ASCII символ выполняет XLookupString. Допустимо только для событий KeyPress и KeyRelease.
%B
  Поле ширина_бордюра события.Допустимо только для событий Configure.
%E
  Поле послать_событие события.Допустимо для событий всех типов.
%K
  Код клавиши, соответствующей данному событию, представленный текстовой строкой. Допустимо только для событий KeyPress и KeyRelease.
%N
  Код клавиши, соответствующей данному событию, представленный десятичным числом. Допустимо только для событий KeyPress и KeyRelease.
%R
  Идентификатор корневого окна события.Допустимо только для событий содержащих поле корень.
%S
  Идентификатор подокна события, представленный в виде шестнадцатиричного числа. Допустимо только для событий содержащих поле подокно.
%T
  Поле тип события. Допустимо для событий всех типов.
%W
  Путь к окну, к которому отнесено событие (поле окно события). Допустимо для событий всех типов.
%X
  Поле x_корень события. При использовании виртуально-корневого менеджера окон подставляемое значение равняется x-координате в виртуальном корне. Допустимо только для событий ButtonPress, ButtonRelease, KeyPress, KeyRelease и Motion.
%Y
  Поле y_корень события. При использовании виртуально-корневого менеджера окон подставляемое значение равняется y-координате в виртуальном корне. Допустимо только для событий ButtonPress, ButtonRelease, KeyPress, KeyRelease и Motion.

Строка подстановки для %-замещения форматируется как обычный элемент списка Tcl. Это означает, что при наличии в строке пробелов она заключается в фигурные скобки, а специальным символам, таким как `$' и `{' может предшествовать обратная косая черта. Такая строка нормально обрабатывается синтаксическим анализатором Tcl при выполнении скрипта. Строки подстановки по большей части являются числами или корректно определенными строками как, например, Above; такие строки не нуждаются ни в каком специальном форматировании. Чаще всего форматирования требуют строки, замещающие %A. Если, например, скрипт имеет вид

    insert %A

и вводимым символом является открывающая квадратная скобка, то реально исполняемым скриптом будет

    insert \[

т.е. в качестве первого аргумента insert получит исходную строку подстановки (открывающую квадратную скобку). Если бы обратная косая черта не была добавлена, Tcl не смог бы правильно обработать скрипт.

## НЕСКОЛЬКО ПРИВЯЗОК, ОТВЕЧАЮЩИХ ОБРАЗЦУ

Данному X событию может отвечать несколько привязок. Если эти привязки соответствуют различным тегам, то все они выполняются по очереди. По умолчанию сначала исполняется привязка для примитива, затем привязка класса, затем привязка верхнего уровня и привязка all. Этот порядок для конкретного окна можно поменять с помощью команды bindtags, которая позволяет также выполнить дополнительные привязки к окну.

Управление обработкой скриптов, отвечающих образцу, осуществляется командами continue и break в привязанном скрипте. При выполнении команды continue выполнение текущего привязанного скрипта прерывается и Tk переходит к выполнению скриптов, соответствующих остальным тегам. При выполнении команды break выполнение текущего привязанного скрипта прерывается и никакие другие скрипты не выполняются.

Если данному событию соответствует несколько привязок с одним и тем же тегом, то из них выбирается наиболее конкретная привязка и выполняется ее скрипт. Выбор наиболее конкретной привязки осуществляется по следующим критериям:

1. образец события, задающий конкретную кнопку или клавишу, более конкретен, чем тот, в котором такой спецификации не задано;
2. более длинная последовательность (по числу отвечающих образцу событий) конкретнее более короткой;
3. если модификаторы первого образца содержатся среди модификаторов второго, то образец с большим числом модификаторов более конкретен;
4. виртуальное событие, физический образец которого соответствует последовательности, менее конкретно, чем тот же самый физический образец, не связанный ни с каким виртуальным событием;

5. если последовательность отвечает двум или более виртуальным событиям, то из них выбирается какое-нибудь одно, однако порядок выбора не определен.

   Если в подходящей последовательности событий больше одного события, то критерии 1 - 5 применяются ко всем событиям, начиная с самого последнего и до самого первого события последовательности. Если критерии не позволяют определить победителя, то победителем становится событие, зарегистрированное последним.

Если одна и та же последовательность осуществляет переключение к двум (или более) виртуальным событиям, и теги окон этих виртуальных событий совпадают, то переключение произойдет лишь к одному из этих виртуальных событий, выбранному случайным образом:

          event add <<Paste>> <Control-y>
          event add <<Paste>> <Button-2>
          event add <<Scroll>> <Button-2>
          bind Entry <<Paste>> {puts Paste}
          bind Entry <<Scroll>> {puts Scroll}

При нажатии Control-y будет выполнена привязка <<Paste>>, а при нажатии кнопки 2 одна из привязок <<Paste>> или <<Scroll>>, причем определить какой именно будет эта привязка, невозможно.

Если X событие не подходит ни под одну из существующих привязок, то событие игнорируется. Наступление не привязанного события не считается ошибкой.

## ПОСЛЕДОВАТЕЛЬНОСТИ НЕСКОЛЬКИХ СОБЫТИЙ И ИГНОРИРУЕМЫЕ СОБЫТИЯ

Если аргумент последовательность в команде bind состоит из нескольких образцов событий, то скрипт выполняется в случае, если последние события (включая самое последнее) подходят под данную последовательность. Это означает, например, что при неоднократном последовательном нажатии кнопки 1 каждое из нажатий, за исключением самого первого, отвечает образцу <Doudble-ButtonPress-1>. Если в последовательности событий происходят посторонние события, то они игнорируются, за исключением событий KeyPress и ButtonPress. Например, нажатия на кнопку 1 будут соответствовать образцу <Doudble-ButtonPress-1>, даже если их перемежают события ButtonRelease или Motion. Кроме того событию KeyPressможет предшествовать произвольная последовательность событий KeyPress для модификаторов, среди которых нет модификаторов, нарушающих соответствие образцу. Например, последовательности событий aB отвечает нажатие на клавишу a, отпускание клавиши a, нажатие на клавишу Shift и нажатие на клавишу b, так как нажатие на клавишу модификатора Shift игнорируется. И, наконец, если последовательно происходит несколько событий Motion, то для установления соответствия привязке берется последнее из них.

## ОШИБКИ

При возникновении ошибки в процессе исполнения привязанного скрипта для выдачи сообщения об ошибке используется механизм bgerror. Команда bgerror исполняется на верхнем уровне (вне контекста любой из процедур Tcl).