Борьба с дребезгом при перетаскивании
Если объект можно как выделить, так и перетащить, очень важно, чтобы курсор мыши отдавал предпочтение операции выделения.
Крайне трудно щелкнуть по объекту, не сдвинув при этом указатель мыши на пару пикселов, поэтому часто выполняемая операция выде' ления объекта не должна ошибочно приниматься за начало операции перетаскивания. Пользователи редко пытаются передвинуть объект на два пиксела. (А если в некоторых случаях и пытаются, например в приложениях для рисования, полезно сделать порог смещения более высоким, чтобы предотвратить случайное перемещение.)
В аппаратуре применяются кнопки, содержащие механические кон' такты, в которых часто проявляется так называемый эффект дребез- га, обусловленный тем, что тонкие контактные пластинки вибрируют, когда на них кто'то нажимает. В электрических устройствах, вроде дверного звонка, такая вибрация, длящаяся миллисекунды, несуще' ственна, но в микроэлектронике подобное явление, приводящее к по' вторным щелчкам, может играть заметную роль. В устройствах, включающих в себя механические переключатели, реализована спе' циальная логика, игнорирующая «лишние» переключения, если они имеют место в пределах нескольких миллисекунд после первого. Вот почему ваша стереосистема, например, не отключается через тысяч' ную долю секунды после того, как вы ее включили. Описанная ситуа' ция возникает и в сверхчувствительной схеме работы мыши. Реше' ние, как и в случае переключателей, состоит в компенсации дребезга.
Чтобы избежать проблем, программа должна устанавливать порог сме- щения, чтобы все системные сообщения о перемещении мыши, посту' пившие после сообщения о нажатии на кнопку, игнорировались, если перемещение происходит в небольших пределах, например три пиксе' ла. Тем самым обеспечивается некоторая защита от случайного пере' таскивания. Если пользователь в состоянии удержать мышь в пределах трех пикселов в момент щелчка, щелчок интерпретируется как коман' да выделения, а все мелкие паразитные перемещения игнорируются. Так достигается компенсация дребезга. Если же мышь выйдет за преде' лы трехпиксельного порога, программа сможет уверенно приступить к операции перетаскивания. Это проиллюстрировано на рис. 19.8. Все' гда, когда объект допускает как выделение, так и перетаскивание, не' обходима компенсация дребезга.
Компенсируйте дребезг перетаскивания.
В некоторых приложениях может потребоваться более сложная реали' зация порога смещения. В программах трехмерной графики часто не' обходимы пороги смещения по экрану вдоль сразу трех координатных осей в проекции. Сходная ситуация возникла однажды при разработке генератора отчетов для одного из наших клиентов. Пользователь имел возможность сортировать столбцы в отчете, перетаскивая их по гори' зонтали. Например, он мог поставить столбец с именами слева от
координаты
нажатия кнопки мыши
мертвая зона, интерпретируем как выделение
6 px
начинаем перемещение
6 px
Рис. 19.8. Для любого объекта, допускающего и выделение, и перетаскивание, следует компенсировать дребезг. Когда пользователь щелкает по объекту, это действие следует интерпретировать как выделение, а не перетаскива- ние, даже если пользователь случайно сдвинет мышь на пару пикселов, пока кнопка еще нажата. Программа должна игнорировать всякое движение
в пределах мертвой зоны, простирающейся на три пиксела в каждую сторону от точки щелчка. Если указатель мыши сдвинется более чем на три пиксела от точки щелчка, объект должен считаться «сдвинутым» и операция выделе- ния должна смениться перетаскиванием. Это называется порогом смещения
столбца с фамилиями, ухватившись мышью за любое место столбца. Это была наиболее востребованная идиома перетаскивания. Была, од' нако, и другая операция перетаскивания, которая применялась на' много реже. Она позволяла объединять значения в одном столбце со значениями в соответствующих строках другого столбца. Например, можно было объединить столбец адреса со столбцом, в котором указы' вался штат (рис. 19.9).
Мы хотели следовать ментальной модели персонажа и позволить ему перетаскивать значения одного столбца на значения другого, но это конфликтовало с обычным переупорядочиванием столбцов. Мы реши' ли проблему, разделив операции перетаскивания на горизонтальные и вертикальные. Если пользователь перетаскивал столбец вправо или влево, это означало перемещение столбца как целого. Когда пользова' тель перетаскивал столбец вверх или вниз, это означало его намерение объединить значения ячеек этого столбца со значениями другого.
Поскольку горизонтальное перетаскивание было преобладающей опе' рацией, а вертикальное выполнялось сравнительно редко, мы настро' или порог смещения для предпочтения горизонтальных движений. Вместо квадратной мертвой зоны мы создали зону в форме катушки, изображенную на рис. 19.10. Благодаря четырехпиксельному порогу горизонтального смещения от пользователя не требовалось широких движений, чтобы началось обычное перетаскивание по горизонтали, а случайное перетаскивание по вертикали компенсировалось. Чтобы выполнить гораздо более редкую операцию вертикального перетаски' вания, пользователь должен был сдвинуть курсор на восемь пикселов вдоль вертикальной оси, не отклонившись в сторону более чем на че' тыре пиксела. Такое движение оказалось вполне естественным и легко запоминаемым.
Name 1 Ginger Beef | Address/City 342 Easton Lane Waltham | |
C. U. Lator | 339 Disk Drive Borham | |
Justin Case | 68 Elm Albion | |
Creighton Barrel | 9348 N. Blenheim Five Island | |
Dewey Decimal | 1003 Water St. Freeport |
Рис. 19.9. Этот генератор отчетов предлагал пользователю интересную возможность слияния значений в двух столбцах путем перетаскивания одного из них на другой. Такая операция непосредственного манипулирования конфликтовала с другой, более частой операцией переупорядочивания столб- цов перетаскиванием (например, перемещением столбца City влево от столб- ца Address). Мы применили специальный двухмерный порог смещения
для разрешения конфликта
начало вертикального перемещения
координаты нажатия кнопки мыши
начало горизонтального
перемещения 16 px
мертвая зона
8 px
Рис. 19.10. Этот порог смещения в форме катушки позволил реализовать
в программе предпочтение горизонтального перетаскивания вертикальному. В данном приложении горизонтальное перетаскивание применялось чаще, чем вертикальное. Такой порог смещения препятствовал непреднамеренно- му перемещению по вертикали. Однако если пользователь действительно хотел выполнить вертикальное перетаскивание, решительное движение
по вертикали заставляло программу переключиться в соответствующий режим и не отягощать пользователя лишними действиями
Такой асимметричный по осям порог может использоваться и в других целях. В программе Visio реализована сходная идиома, позволяющая отличить рисование прямой линии от рисования кривой.
Точная прокрутка
Слабая пригодность мыши в качестве устройства точного указания оче' видна и особенно ярко проявляется при перетаскивании объектов в про' граммах рисования. Ужасно трудно перетащить объект точно в нуж' ную позицию, особенно учитывая, что разрешение экрана – 72 пиксела на дюйм, а перемещения мыши масштабируются в соотношении шесть к одному. Чтобы переместить указатель мыши на один пиксел, вы должны сдвинуть ее саму на одну пятисотую дюйма. Это нелегко.
Проблема решается добавлением функции точной прокрутки, позво' ляющей пользователю изменять соотношение между перемещением мыши и курсора на экране. Если в ходе операции перетаскивания пользователю понадобилось более точное маневрирование, он включа' ет режим точной прокрутки. Любая программа, в которой может потре' боваться точное выравнивание, должна предлагать пользователю воз' можность точной прокрутки. Это касается в первую очередь всех про' грамм для черчения и рисования, презентационных программ и про' грамм манипулирования изображениями.
Любая программа, в которой требуется точное выравнива- ние, должна предлагать пользователю верньер.
Существует несколько вариантов этой идиомы. Обычно мышь перево' дится в режим верньера удержанием служебной клавиши во время пе' ретаскивания. В этом режиме перемещению мыши на десять пикселов будет соответствовать перемещение объекта на один пиксел.
Другим эффективным методом является использование во время пере' таскивания клавиш со стрелками. Удерживая кнопку мыши нажатой, пользователь может передвигать выделенный объект клавишами со стрелками на один пиксел вверх, вниз, влево или вправо. Как и всегда, перетаскивание заканчивается, когда пользователь отпускает кнопку мыши.
Проблема с такой реализацией верньера состоит в том, что в момент высвобождения кнопки рука пользователя может дрогнуть и сдвинуть мышь на один'два пиксела – и столь тщательно установленный объект сместится в самый последний момент. Справиться с этой проблемой можно, лишив мышь чувствительностипосле первого нажатия на клавишу в режиме верньера. Это реализуется путем игнорирования всех перемещений мыши в пределах, установленных неким порогом, равным, скажем, пяти пикселам. В конечном итоге получается, что пользователь может начать с размашистых движений мышью, потом выполнить окончательную подгонку позиции с помощью клавиш со
Манипулирование элементами управления461
стрелками, а затем отпустить кнопку мыши без риска сдвинуть объект на экране. Если уже после переключения в режим верньера пользова' телю понадобится снова перейти к размашистым движениям, он про' сто выводит мышь за пределы зоны, установленной порогом, тем са' мым отключая режим.
Если, как принято в графических редакторах, клавиши со стрелками не используются, их можно задействовать для точного позициониро' вания выделенного объекта. Это означает, что пользователю не при' дется держать кнопку мыши нажатой. Такой подход реализован в Adobe Illustrator, Photoshop и PowerPoint. В последнем приложении клавиши со стрелками передвигают выделенный объект на один шаг сетки, по умолчанию равный примерно двум миллиметрам. Если удер' живать клавишу <Alt>, то каждое нажатие на клавишу со стрелкой бу' дет перемещать объект на один пиксел.