Ввод данных и сенсоры
Жесты у края экрана
Как мы видели в "Командный пользовательский интерфейс" , вам не нужно делать ничего особенного, чтобы появлялись верхняя и нижняя панели приложения: Windows автоматически обрабатывает скольжение от верхнего и нижнего краев, как и щелчок правой кнопкой мыши, сочетание клавиш Win+Z, нажатие клавиши контекстного меню на клавиатуре. Тем не менее, вы можете обнаружить, когда именно происходят эти события, прослушивая события starting, completed и canceled объекта Windows.UI.EdgeGestures1Как для событий объектов WinRT, для них справедливы соображения, изложенные в лекции 3, в разделе "События WinRT и removeEventListener". :
var edgeGesture = Windows.UI.Input.EdgeGesture.getForCurrentView(); edgeGesture.addEventListener("starting", onStarting); edgeGesture.addEventListener("completed", onCompleted); edgeGesture.addEventListener("canceled", onCanceled);
Cобытие completed вызывается для всех типов ввода. События starting и canceled происходят только для сенсорных жестов. В этих событиях, свойство eventArgs.kind содержит значение из перечисления EdgeGestureKind, которое указывает на вид ввода данных, который вызвал событие. События starting и canceled всегда имеют вид touch, очевидно, в то время, как comleted может иметь вид touch, keyboard или mouse:
function onCompleted(e) { // Определяет, было ли это событие инициировано мышью, клавиатурой или касанием if (e.kind === Windows.UI.Input.EdgeGestureKind.touch) { id("ScenarioOutput").innerText = "Invoked with touch."; } else if (e.kind === Windows.UI.Input.EdgeGestureKind.mouse) { id("ScenarioOutput").innerText = "Invoked with right-click."; } else if (e.kind === Windows.UI.Input.EdgeGestureKind.keyboard) { id("ScenarioOutput").innerText = "Invoked with keyboard."; } }
Этот код был взят из Сценария 1 примера "Инициация жестов у края экрана" (http://code.msdn.microsoft.com/windowsapps/Edge-gesture-invocation-76a474dd). В Сценарии 2 пример показывает, как вы можете предотвратить выполнение событий жестов у края для конкретного элемента, если вы обработаете событие contextmenu для этого элемента и вызовите eventArgs.preventDefault в вашем обработчике. Подобное делает это для одного элемента на экране, в итоге щелчок правой кнопкой мыши по элементу или нажатие клавиши контекстного меню, когда элемент имеет фокус ввода, предотвратит события жестов у края:
document.getElementById("handleContextMenuDiv"). addEventListener("contextmenu", onContextMenu); function onContextMenu(e) { e.preventDefault(); id("ScenarioOutput").innerText = "The ContextMenu event was handled. The EdgeGesture event will not fire."; }
Обратите внимание на то, что этот метод не подействует на жесты у края, выполняемые путем касания и на сочетание клавиш Win+Z, которое обычно активирует панель приложения. Это, в основном, для того, чтобы показать, что если вам нужно обработать именно событие contextmenu, вам обычно нужно предотвратить обработку жестов у края.
CSS-стили, влияющие на ввод информации
Во время разговора о вводе данных самое время упомянуть о множестве CSS-стилей, которые могут влиять на ввод данных в приложение.
- none – деактивирует прямое выделение, хотя элемент, в целом, может быть выделен, если его элемент-родитель может быть выделен.
- inherit – устанавливает поведение выделения элемента таким же, как у элемента-родителя.
- text – активирует возможность выделения текста, даже если элемент-родитель установлен в none.
- element – активирует возможность выделения для произвольного элеменнта.
- auto – значение по умолчанию, может либо активировать возможность выделения, либо нет, в зависимости от типа элемента управления и стилизации элемента-родителя. Для элементов управления, не являющихся текстовыми элементами и не имеющими установки contenteditable="true", возможность выделения не активируется, несмотря на то, что они содержатся в элементе-родителе, который может быть выделен.
Если вы хотите поэкспериментировать с различными вариантами, обратитесь к примеру "Невыделяемые области содержимого с CSS-атрибутом –ms-user-select" ( http://code.msdn.microsoft.com/windowsapps/Unselectable-content-areas-963eccd9), которому я присуждаю приз за самое длинное название JavaScript-примера во всем Windows SDK!
Связанный стиль, но не показанный в примере – это –ms-touch-select, который может принимать находиться в состоянии none или grippers, последнее – это стиль, который включает выделение с помощью маркеров в виде окружностей для сенсорного взаимодействия:
Выделяемые текстовые элементы автоматически получают этот стиль, как и другие текстовые элементы с contenteditable = "true". Вы можете использовать –ms-touch-select для того, чтобы выключить эту возможность. Для того, чтобы увидеть его действие, попробуйте это с некоторыми элементами в Сценарии 1 вышеупомянутого примера с по-настоящему длинным именем!
В лекции 6 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript" мы говорили об использовании точек прикрепления для сдвига, с использованием стилей –ms-scroll-snap*. В том же духе, стили, перечисленные в материале "Сенсорное взаимодействие: изменение масштаба и сдвиг" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh453816.aspx), используются для масштабирования содержимого, такие, как –ms-content-zooming и –ms-content-zoom*, которые предоставляют точки прикрепления и для операций масштабирования. Важно здесь то, что –ms-content-zooming: zoom (в противоположность значению по умолчанию – none) активирует автоматическое зуммирование с помощью жестов или колеса мыши, обеспечивая элементам того, о чем идет речь, возможность перехода за границы (переполнения) по измерениям X и Y. Существует множество вариантов подобного для сдвига и изменения масштаба, и того, как жесты взаимодействуют с элементами управления WinJS. Оставляю объяснения подробностей этого для примера "HTML-прокрутка, сдвиг и масштабирование" (http://code.msdn.microsoft.com/windowsapps/Scrolling-panning-and-47d70d4c).
И, наконец, стиль –ms-touch-action предоставляет элементу множествовозможностей2Вариант double-tap-zoom не поддерживается приложениями для Магазина Windows.
- none – отключает возможность сенсорного взаимодействия с элементом.
- auto – активирует обычное сенсорное поведение.
- pan-x / pan-y – элементу разрешен горизонтальный / вертикальный сдвиг, что выполняется на ближайшем элементе-предке, который поддерживает возможности горизонтальной / вертикальной прокрутки, на таком, как родительский div.
- pinch-zoom – активирует изменение масштаба с помощью сведения/разведения пальцев, что выполняется на ближайшем предке, имеющем –ms-content-zooming: zoom и возможность переполнения. Например, сам по себе элемент img не отреагирует на жест с подобным стилем, однако, если вы поместите его в родительский div с установленным свойством overflow, то отреагирует.
- manipulation – короткое имя для pan-x pan-y pinch-zoom.
Для того, чтобы привести пример сдвига и изменения масштаба, попробуем создать простое приложение с разметкой, похожей на эту (используйте здесь любое изображение):
<div id="imageContainer"> <img id="image1" src="/images/flowers.jpg" /> </div>
И стилизуем контейнер следующим образом:
#imageContainer { overflow: auto; -ms-content-zooming:zoom; -ms-touch-action: manipulation; }
Что могут предоставить возможности ввода данных?
API WinRT в пространстве имен Windows.Devices.Input (http://msdn.microsoft.com/library/windows/apps/br225648.aspx) предоставляют всю необходимую информацию о возможностях по вводу данных, присутствующих на текущем устройстве, в частности, посредством этих трех объектов: MouseCapabilities (http://msdn.microsoft.com/library/windows/apps/windows.devices.input.mousecapabilities.aspx) имеет свойства mousePresent (0 или 1), horizontalWheelPresent (0 или 1), verticalWheelPresent (0 или 1), numberOfButtons (число), и swapButtons (0 или 1). KeyboardCapabilities (http://msdn.microsoft.com/library/windows/apps/windows.devices.input.keyboardcapabilities.aspx) содержит лишь одно свойство: keyboardPresent (0 или 1). Обратите внимание, что это свойство не отражает присутствия экранной клавиатуры, которая всегда доступна. Свойство этого объекта указывает на физическое устройство – клавиатуру. TouchCapabilities (http://msdn.microsoft.com/library/windows/apps/windows.devices.input.touchcapabilities.aspx) имеет свойства touchPresent (0 или 1) и contacts (число). Обратите внимание на то, что когда речь идет о сенсорном вводе, может быть интересным свойство Windows.UI.ViewManagement.UISettings.handPreference (http://msdn.microsoft.com/library/windows/apps/windows.ui.viewmanagement.uisettings.handpreference.aspx), которое позволяет узнать о направлении пользовательского интерфейса, о том, правша пользователь или левша.
Для проверки доступности сенсорных возможностей, таким образом, вы можете использовать такой код:
var tc = new Windows.Devices.Input.TouchCapabilities(); var touchPoints = 0; if (tc.touchPresent) { touchPoints = tc.contacts; }
Примечание. В веб-контексте, где WinRT недоступна, некоторые данные о возможностях по вводу данных могут быть получены с помощью свойств элементов DOM msPointerEnabled (http://msdn.microsoft.com/library/windows/apps/Hh972607.aspx), msManipulationViewsEnabled (http://msdn.microsoft.com/library/windows/apps/Hh972607.aspx), и msMaxTouchPoints (http://msdn.microsoft.com/library/windows/apps/hh779855.aspx). Это так же работает в локальном контексте.
Вы могли заметить, что возможности, перечисленные выше, ничего не сообщают о пере или ручке. Для них, а так же для более подробной информации обо всех устройствах для работы с указателями, включая сенсорный экран и мышь, у нас есть метод Windows.Devices.Input.PointerDevice.getPointerDevices. Он возвращает массив объектов типа PointerDevice (http://msdn.microsoft.com/library/windows/apps/windows.devices.input.pointerdevice.aspx), каждый из которых имеет следующие свойства:
- pointerDeviceType – значение из Windows.Devices.Input.PointerDeviceType (http://msdn.microsoft.com/library/windows/apps/windows.devices.input.pointerdevicetype.aspx), которое может содержать touch, pen, или mouse.
- maxContacts – максимальное количество контактных точек, которое может поддерживать устройство. Обычно 1 для мыши и пера, и любое другое количество для сенсорного экрана.
- isIntegrated – значение true говорит о том, что устройство ввода встроено в компьютер, то есть на его присутствие можно рассчитывать. Значение false указывает на периферийное устройство, которое может отключить пользователь.
- physicalDeviceRect – этот объект типа Windows.Foundation.Rect предоставляет ограничивающий прямоугольник, в виде которого устройство воспринимает свою рабочую поверхность. Часто разрешение ввода сенсорного экрана не совпадает с экранными пикселями, что означает, что устройство ввода не способно выделить в точности один пиксель. Один из моих ноутбуков с сенсорным экраном, например, показывает это разрешение как 968x548 для экрана разрешением 1366x768 пикселей (как сообщает screenRect ниже). Рабочая поверхность мыши, с другой стороны, обычно один в один совпадает с экранным разрешением. Это может быть важно для приложений для рисования, которые работают с пером, если разрешение ввода меньше, чем разрешение экрана, это может означать некоторую неточность при переводе координат ввода данных в экранные пиксели.
- screenRect – этот объект типа Windows.Foundation.Rect предоставляет ограничивающий прямоугольник для экрана устройства, то есть, минимальные и максимальные координаты, на которые вам следует рассчитывать, обрабатывая события устройства. Этот прямоугольник принимает в расчет системы с несколькими мониторами, и он подстраивается под масштабирование разрешения.
- supportedUsages – массив структур Windows.Devices.Input.PointerDeviceUsage (http://msdn.microsoft.com/library/windows/apps/windows.devices.input.pointerdeviceusage.aspx), которые идентифицируют то, что называется использованием устройств HID (human interface device). Эта тема выходит за пределы данного курса, поэтому я предлагаю вам воспользоваться документом "Использование HID" (http://msdn.microsoft.com/library/windows/hardware/ff539946.aspx) в MSDN для того, чтобы получить первоначальные сведения.
Пример "Ввод данных: возможности устройств" (http://code.msdn.microsoft.com/windowsapps/Input-device-capabilities-31b67745) в Windows SDK получает эту информацию и выводит ее на экран посредством кода в js/pointer.js. Я не привожу здесь этот код, так как все, что он делает – это обходит массив, создает длинную HTML-строку и помещает ее в DOM. В имитаторе выходные данные выглядят следующим образом. Обратите внимание на то, что имитатор, в данном случае, сообщает о наличии мыши и сенсорного экрана.
Любопытная фальсификация? Интересно то, что я запустил этот пример в отладчике Visual Studio на локальном компьютере, на ноутбуке, который совершенно определенно не имеет сенсорного экрана, но о наличии сенсорного устройства ввода, все равно, сообщалось, как на вышеприведенном изображении. Почему? Потому, что все еще был запущен имитатор Visual Studio, который добавляет виртуальное сенсорное устройство к аппаратному профилю. После того, как симулятор был полностью закрыт (а не только свернут в значок), я получил точные сведения о возможностях моего ноутбука. Так что помните об этом, если вы пишете программный код для проверки конкретных возможностей.
Пробовали удаленную отладку? Говоря об отладке, как упомянуто во врезке в лекции 6 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", тестирование приложений на устройствах с разными возможностями – это отличная возможность для применения удаленной отладки в Visual Studio. Если вы еще не сделали этого, сделайте, все настойки займут лишь несколько минут. Для того, чтобы узнать подробности, обратитесь к материалу "Выполнение приложений для Магазина Windows на удаленном компьютере" (http://msdn.microsoft.com/library/windows/apps/hh441469%28v=vs.110%29.aspx).