Drag n drop что это: Мышь: Drag’n’Drop

and-drop — это… Что такое Drag-and-drop?

Пример работы с музыкальными композициями в онлайн-плеере Audiotoria методом Drag And Drop

Drag-and-drop (в переводе с английского означает буквально тащи-и-бросай; Бери-и-Брось) — способ оперирования элементами интерфейса в интерфейсах пользователя (как графическим, так и текстовым, где элементы GUI реализованы при помощи псевдографики) при помощи манипулятора «мышь» или сенсорного экрана.

Способ реализуется путём «захвата» (нажатием и удержанием главной (первой, чаще левой) кнопки мыши) отображаемого на экране компьютера объекта, программно доступного для подобной операции, и перемещении его в другое место (для изменения расположения) либо «бросания» его на другой элемент (для вызова соответствующего, предусмотренного программой, действия). По отношению к окнам (также способным к перемещению подобным способом) данный термин обычно не употребляется.

Базовыми действиями и самыми простыми примерами drag-and-drop действий являются: перемещение объекта, перемещение объекта в из панели в панель, хотя в современных операционных системах drag-and-drop получил широкое применение и является одним из главных способов взаимодействия с компьютером в графическом интерфейсе пользователя.

Объектами для перемещения могут быть следующие элементы интерфейса: значки (иконки) Рабочего стола, плавающие панели инструментов, ярлыки программ в Панели задач (начиная с Win XP), элементы TreeView, текстовая строка, ячейка DataGridView., также элементы OLE. Перемещаться объекты могут как в пределах некоторой определённой области, в пределах одного окна, между панелями одного окна, так и между разными окнами.

Событие перетаскивания должно инициироваться каким-либо действием пользователя. Чаще всего этим действием является нажатие левой кнопки мыши на элементе (событие это называется MouseDown), который может быть перемещен в своем контейнере. Некоторые компоненты обладают собственными событиями начала drag-n-drop — например, TreeView имеет событие ItemDrag.

Drag’n’Drop в QML — это просто! Или 5 шагов до цели / Хабр

Этот пост участвует в конкурсе „Умные телефоны за умные посты“.

Drag’n’Drop является неоспоримо важным элементом взаимодействия пользователя и графического окружения. К сожалению, в QML нет встроенного механизма Drag’n’Drop для View. Поэтому, я написал небольшой пример на основе GridView с 16 изображениями.

Этот пример Drag’n’Drop-а не претендует на совершенство (есть несколько других реализаций, которые визуально возможно более совершенны), а больше преследует цель показать, что QML является очень гибким и простым средством разработки.

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

Шаг 1. Создаем GridView

Начнем с создания GridView и небольшой модели. В качестве тестовых данных я взял стандартные изображения из Nokia N8.
Сделаем наш грид размером 4х4 изображения.
Rectangle {
    width: 420
    height: 420
    color: "#000000"

    Component {
        id: dndDelegate
        Item {
            id: wrapper
            width: dndGrid.cellWidth
            height: dndGrid.cellHeight
            Image {
                id: itemImage
                source: imagePath
                anchors.centerIn: parent
                width: 90
                height: 90
                smooth: true
                fillMode: Image.PreserveAspectFit
            }
        }
    }

    ListModel {
        id: dndModel
        ListElement { imagePath: "images/1.jpg" }
        //Еще 15 картинок
    }

    GridView {
        id: dndGrid
        anchors.fill: parent
        anchors.margins: 10
        cellWidth: 100
        cellHeight: 100
        model: dndModel
        delegate: dndDelegate
    }
}

После запуска в qmlviewer мы увидим примерно следующую картину
Шаг 2. Добавляем Drag’nDrop

Теперь нам нужно добавить в этот грид возможность перетаскивания картинок.

Для упрощения задачи отключим возможность прокрутки GridView. Можно обойтись и без этого (используя долгое нажатие вместо обычного нажатия для D’n’D и манипулируя свойством interactive (которое отвечает за то, будет ли прокручиваться GridView) в соответствующих коллбеках MouseArea), но это усложнит пример.

Также добавим элемент MouseArea размером во весь GridView, который и будет отлавливать нажатие мыши при начале драга, а также перемещать элемент на нужную позицию в модели при отпускании мыши. Плюс к этому, в GridView поместим еще дополнительный элемент dndContainer, о котором поговорим позже

Последним штрихом добавим в наш GridView свойство для хранения текущего перемещаемого элемента (а точнее, его индекса в модели).

property int draggedItemIndex: -1
interactive: false
Item {
    id: dndContainer
    anchors.fill: parent
}

MouseArea {
    id: coords
    anchors.fill: parent
    onReleased: {
        if (dndGrid.draggedItemIndex != -1) {
            var draggedIndex = dndGrid.draggedItemIndex
            dndGrid.draggedItemIndex = -1
            dndModel.move(draggedIndex,dndGrid.indexAt(mouseX, mouseY),1)
        }
    }
    onPressed: {
        dndGrid.draggedItemIndex = dndGrid.indexAt(mouseX, mouseY)
    }
}

В делегат добавим состояние inDrag, которое будет активироваться, когда данный элемент является перемещаемым. Вот тут нам и понадобится dndContainer. К нему мы будем цеплять (а если быть более точным, то менять родителя на этот контейнер) наш перемещаемый элемент. Кроме смены родителя, мы также отвязываем якоря у элемента (чтобы он мог перемещаться) и выставляем x и y соответственно координатам мышки (при чем, благодаря биндингу, положение отвязанной картинки будет меняться с перемещением курсора мыши). Когда состояние станет неактивным, все эти изменения откатятся.
states: [ State { name: "inDrag" when: index == dndGrid.draggedItemIndex PropertyChanges { target: itemImage; parent: dndContainer } PropertyChanges { target: itemImage; anchors.centerIn: undefined } PropertyChanges { target: itemImage; x: coords.mouseX - itemImage.width / 2 } PropertyChanges { target: itemImage; y: coords.mouseY - itemImage.height / 2 } } ]

Запустив, увидим примерно вот такую картину. Теперь, мы в нашем гриде можем спокойно перемещать элементы.
Шаг 3. Визуализируем перемещаемый элемент

Ок, мы научились делать то, ради чего была написана эта статья (все просто, не правда ли?). Но перемещаемый элемент почти не заметен, надо его немного выделить на фоне остальных. Добавим белую рамку вокруг перетаскиваемой картинки.
Вставим вот такой код в наш itemImage.
Rectangle {
    id: imageBorder
    anchors.fill: parent
    radius: 5
    color: "transparent"
    border.color: "#ffffff"
    border.width: 6
    opacity: 0
}

Плюс к рамочке неплохо бы как-то помечать место, откуда был взят перетаскиваемый элемент. Добавим белый кружок в центре этого места. Этот код помещается рядом с нашим itemImage
Rectangle {
    id: circlePlaceholder
    width: 30; height: 30; radius: 30
    smooth: true
    anchors.centerIn: parent
    color: "#cecece"
    opacity: 0
}

Ну и добавим их отображение при начале перетаскивания в состояние inDrag делегата.
State {
    name: "inDrag"
    when: index == dndGrid.draggedItemIndex
    PropertyChanges { target: circlePlaceholder; opacity: 1 }
    PropertyChanges { target: imageBorder; opacity: 1 }
    PropertyChanges { target: itemImage; parent: dndContainer }
    PropertyChanges { target: itemImage; anchors.centerIn: undefined }
    PropertyChanges { target: itemImage; x: coords.mouseX - itemImage.width / 2 }
    PropertyChanges { target: itemImage; y: coords.mouseY - itemImage.height / 2 }
}

Теперь наш пример выглядит уже вот так.
Шаг 4. Добавляем анимацию

Ну, основа нашего грида с Drag’n’Drop-ом готова. Добавим свистелок. А если более конкретно, то добавим анимацию.

Для начала в наш многострадальный itemImage добавим два состояния:

  • greyedOut — затеняет картинку. Используется когда drag’n’drop активен, но не для данного элемента
  • inactive — используется либо когда drag’n’drop неактивен, либо для перетаскиваемого элемента

Таким образом, мы слегка затеняем все элементы, кроме перетаскиваемого, что дает нам большую видимость последнего на фоне остальных.

Также добавим анимированные изменения для прозрачности, ширины и высоты картинки.

state: "inactive"
states: [
    State {
        name: "greyedOut"
        when: (dndGrid.draggedItemIndex != -1) && (dndGrid.draggedItemIndex != index)
        PropertyChanges { target: itemImage; opacity: 0.8}
    },
    State {
        name: "inactive"
        when: (dndGrid.draggedItemIndex == -1) || (dndGrid.draggedItemIndex == index)
        PropertyChanges { target: itemImage; opacity: 1.0}
    }
]

Behavior on width { NumberAnimation { duration: 300; easing.type: Easing.InOutQuad } }
Behavior on height { NumberAnimation { duration: 300; easing.type: Easing.InOutQuad } }
Behavior on opacity {NumberAnimation { duration: 300; easing.type: Easing.InOutQuad } }

В состояние inDrag добавим еще изменение высоты и ширины картинки и переход из этого состояния в любое другое (то есть переход из активного drag’n’drop в обычный режим). В этом переходе сделаем анимацию масштаба.
states: [
    State {
        name: "inDrag"
        when: index == dndGrid.draggedItemIndex
        PropertyChanges { target: circlePlaceholder; opacity: 1 }
        PropertyChanges { target: imageBorder; opacity: 1 }
        PropertyChanges { target: itemImage; parent: dndContainer }
        PropertyChanges { target: itemImage; width: 80 }
        PropertyChanges { target: itemImage; height: 80 }
        PropertyChanges { target: itemImage; anchors.centerIn: undefined }
        PropertyChanges { target: itemImage; x: coords.mouseX - itemImage.width / 2 }
        PropertyChanges { target: itemImage; y: coords.mouseY - itemImage.height / 2 }
    }
]
transitions: [
    Transition {
        from: "inDrag"
        to: "*"
        PropertyAnimation {
            target: itemImage
            properties: "scale, opacity"
            easing.overshoot: 1.5
            easing.type: "OutBack"
            from: 0.0
            to: 1.0
            duration: 750
        }
    }
]

Также добавим анимации изменения прозрачности к рамке вокруг перетаскиваемого элемента и к кружку на пустом месте.
Behavior on opacity { NumberAnimation { duration: 300; easing.type: Easing.InOutQuad } }

В итоге получилась уже вот такая картинка.

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

Шаг 5. Последний штрих

И, в качестве завершения, добавим индикатор позиции, куда будет перемещен элемент. Отобразим его в виде вертикальной полоски слева от этого элемента.

Родителем этого элемента будет наш GridView, все действия с ним будут происходить там же.

Для начала добавим в GridView три новых свойства: индекс целевого элемента (possibleDropIndex) и текущие координаты мыши (xCoordinateInPossibleDrop и yCoordinateInPossibleDrop).

Плюс добавим сам элемент индикатора. Это обычная картинка 6×1 пикселей с градиентом, растиражированная по вертикали. У индикатора есть два состояния: невидим (по умолчанию) и shown. Во втором состоянии элемент индикатора помещается в промежуток между двумя картинками, слева от цели. Положение элемента рассчитывается на основе двух последних свойств, а не по индексу в модели, тем самым мы не зависим от текущего количества столбцов в таблице.

property int possibleDropIndex: -1
property int xCoordinateInPossibleDrop: -1
property int yCoordinateInPossibleDrop: -1

Item {
    id: dropPosIndicator
    visible: false
    height: dndGrid.cellHeight
    width: 10

    Image {
        visible: parent.visible
        anchors.centerIn: parent
        height: parent.height-10
        source: "drop-indicator.png"
    }

    states: [
        State {
            name: "shown"
            when: dndGrid.possibleDropIndex != -1
            PropertyChanges {
                target: dropPosIndicator
                visible: true
                x: Math.floor(dndGrid.xCoordinateInPossibleDrop/dndGrid.cellWidth) *
                    dndGrid.cellWidth - 5
                y: Math.floor(dndGrid.yCoordinateInPossibleDrop/dndGrid.cellHeight) *
                    dndGrid.cellHeight
            }
        }
    ]
}

Также добавим еще один обработчик в MouseArea. Тут нам понадобится свойство с индексом места дропа, чтобы не обновлять каждый раз координаты мышки, а менять их только при смене целевого элемента.

onPositionChanged: {
    var newPos = dndGrid.indexAt(mouseX, mouseY)
    if (newPos != dndGrid.possibleDropIndex) {
        dndGrid.possibleDropIndex = newPos
        dndGrid.xCoordinateInPossibleDrop = mouseX
        dndGrid.yCoordinateInPossibleDrop = mouseY
    }
}

В итоге, получим вот такое приложение. Такое же, как на видео в начале поста 🙂

Ну и да, скачать полные исходники (с отдельными .qml файлами для каждого шага) можно здесь

Drag and Drop (Перетаскивание и Отпускание)

Drag and drop — это основная технология непосредственного управления, которая упрощает взаимодействие пользователей со своим содержимым. Пользователи ожидают, что смогут перетащить любой выбранный элемент, такой как параграф текста, файл, изображение или иконку, и расположить его в новом месте.

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

  • Доступен ли жест drag and drop для элемента (определяется обратной связью перетаскивания)
  • Каким будет результат операции drag-and-drop (определяется обратной связью места назначения)
  • Прошла ли операция drag-and-drop успешно (определяется обратной связью отпускания)

Следующие указания помогут вам предоставить опыт drag-and-drop, который оценят пользователи.

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

Определите, должна ли операция draganddrop привести к перемещению или копированию. Как правило, если источник и место назначения находятся в одном вместилище, таком как один том или окно, операция drag-and-drop интерпретируется как переместить, то есть, вырезать и вставить. Если источник и место назначения находятся в разных вместилищах, операция drag-and-drop интерпретируется как копировать, то есть, копировать и вставить.

Насколько возможно, вы также должны продумать структуру базовых данных содержимого во вместилище места назначения. Например, если ваше приложение позволяет двум окнам отображать один документ (несколько видов одних данных), операция drag-and-drop между этими двумя окнами должна привести к перемещению.

ПРИМЕЧАНИЕ

Пользователи могут привести в действие операцию drag-and-drop внутри одного вместилища в качестве копирования посредством нажатия клавиши Option во время перетаскивания. Если пользователи нажимают клавишу Option во время перетаскивания содержимого между двумя разными вместилищами, никакого результата не будет. То есть, операция drag-and-drop все еще будет интерпретирована в качестве копирования, так как источник и место назначения не идентичны.

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

Проверьте клавишу Option в момент отпускания. Это поведение предоставляет пользователю гибкость в принятии решения “переместить или копировать” в более поздний момент в последовательности drag-and-drop. Нажатие клавиши Option во время последовательности drag-and-drop не должно “закрывать” остаток этой последовательности.

В надлежащем случае, предоставьте возможность выделять и перетаскивать одним жестом. Используя мышь или сенсорную панель пользователи могут перетащить элемент посредством его выделения и немедленного перетаскивания, вместо выделения элемента, остановки, а затем перетаскивания. (Автоматическое выделение элемента, которое может произойти в такой ситуации, называется неявное выделение.) Стоит отметить, что выделение и перетаскивание при помощи одного жеста не является возможным, когда пользователь выделяет несколько элементов посредством перетаскивания или клика на отдельные элементы, удерживая при этом клавишу Command, так как множественное выделение не может быть неявным.

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

В частности, осуществите поддержку выделения заднего плана для элементов, которые пользователи могут выделить по области распространения, например, текст или группа иконок. Если вы не осуществите поддержку выделения заднего плана для элементов определенной области, пользователь может возобновить окно и заново выбрать элементы перед тем, как их перетащить. Поддержка выделения заднего плана не требуется, если элемент, который пользователь хочет перетащить, является отдельным, например, иконка или графический объект, так как, если отдельный элемент подвергается перетаскиванию, может произойти неявное выделение. Стоит отметить, что когда неактивное окно становится ключевым, внешний вид выделения заднего плана меняется на внешний вид стандартного выделения. Чтобы узнать больше о разных состояниях окна, см. Главные, Ключевые и Неактивные Окна.

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

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

Если нужно, измените изображение перетаскивания, чтобы показать форму опускаемого элемента. Если это поможет пользователям понять, как ваше приложение может управлять элементом, вы можете изменить изображение перетаскивания, когда оно достигнет места назначения в вашем приложении. Например, когда пользователь перетаскивает файл изображения с рабочего стола в документ Текстового Редактора, это изображение разворачивается, чтобы показать, как оно будет выглядеть после того, как пользователь отпустит его в документе.

Не смотря на то, что изменение изображения перетаскивания может предоставить значимую обратную связь, вам нужно избегать создания отвлекающего опыта drag-and-drop, при котором изображения перетаскивания постоянно (и радикально) меняют форму.

Используйте соответствующий указатель, чтобы определить, что произойдет, когда пользователь отпустит элемент. Например, когда пользователи перетаскивают иконку на панель инструментов, появляется указатель копирования, чтобы определить, что, если они отпустят там элемент, он будет добавлен в панель инструментов. Остальные указатели, которые предоставляют полезную обратную связь места назначения, включают в себя alias, poof и not allowed. (Чтобы получить больше информации об указателях, предоставленных системой, см. Указатели.)

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

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

Не выделяйте область места назначения, если вся операция draganddrop происходит внутри этой области. Например, в процессе перемещения иконки документа в другое место в одном окне папки, это окно папки не выделяется, так как это могло бы ввести пользователя в заблуждение. Выделяйте область места назначения, если пользователь перетаскивает элемент, который находится за пределами этой области, а затем снова перетаскивает этот же элемент обратно в эту же область.

В тексте используйте вертикальный индикатор вставки, чтобы показать, куда перенесенный элемент был вставлен. Стоит отметить, что индикатор вставки отличается от указателя. Указатель определяет, применимо ли перетаскивание и будет ли оно интерпретировано в качестве копирования.

В списке используйте горизонтальный индикатор вставки, чтобы показать, куда элемент будет вставлен. Например, когда пользователь перетаскивает файл в навигатор Xcode, появляется горизонтальный индикатор вставки.

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

Выделите перенесенный текст в месте назначения. Если место назначение поддерживает оформленный стилем текст, в перенесенном тексте должны быть сохранены свойства шрифта, начертания и размера. Если место назначения не поддерживает оформленного стилем текста, перенесенный текст должен приобрести свойства шрифта, начертания и размера, определенные точкой вставки места назначения.

Предоставьте дополнительную обратную связь, если перетаскивание инициирует какой-либо процесс. Например, если пользователь отпускает элемент на иконку, которая представляет задачу (например, печать), покажите, что выполнение этой задачи началось, и информируйте пользователя о процессе этой задачи.

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

Место назначения должно принимать количество перетаскиваемых элементов, которое имеет смысл. В вашем приложении место назначения должно извлекать релевантную информацию из элемента, который отпустил пользователь. Например, если пользователь перетаскивает запись из приложения Контакты в текстовое поле приложения Почта “Кому”, принят может быть только адрес электронной почты, но не остальная часть контактной информации.

Отобразите соответствующее состояние выделенного фрагмента после того, как он был отпущен. После успешной операции drag-and-drop, которая произошла в пределах одного окна, состояние выделенного фрагмента должно быть сохранено в новом местоположении. Такое поведение показывает местоположение опущенного элемента и позволяет пользователю изменить положение этого элемента без необходимости снова его выделять. Также:

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

При необходимости автоматически прокручивайте окно места назначения. Когда происходит перетаскивание элемента, ваше приложение должно определить, нужно ли прокручивать содержимое или позволить элементу “сбежать” из окна. Если ваше приложение позволяет перенести элемент за пределы окна, вы должны выделить область автоматического прокручивания. Прокручивайте окно места назначения автоматически только в том случае, если это окно также является окном источника, а также основным. Не прокручивайте автоматически неактивные окна.

Отобразите диалог подтверждения, когда операцию draganddrop нельзя отменить. Хотя лучше всего осуществить в вашем приложении отмену операций drag-and-drop, это не всегда является возможным. Например, если пользователь намеревается опустить иконку в групповое окно общедоступного диска, которое подходит только для записей, это действие нельзя отменить, так как у пользователя нет полномочий открыть групповое окно и изменить процесс перетаскивания. В таких случаях, важно использовать диалог подтверждения, чтобы сообщить пользователю, что эта операция drag-and-drop не может быть изменена.

Создайте клиппинг или другой элемент, чтобы включить содержимое, которое пользователи переносят из вашего приложения в Корзину. Клиппинг представляет собой промежуточную форму содержимого, которое подверглось перетаскиванию из начального местоположения, но еще не было опущено в конечное место назначения. Например, OS X позволяет перетаскивать содержимое в окно finder (или на рабочий стол), а затем, перенести это содержимое в другое место. (Стоит отметить, что клиппинг ничем не связан с Clipboard: Копирование в Clipboard и создание клиппингов drag-and-drop не противоречат друг другу.)

Клавиши Быстрого Доступа

OS X сохранил несколько комбинаций клавиш для использования с локализованными версиями системного ПО, клавиатуры, расположения клавиш на клавиатуре и способов ввода. Эти комбинации клавиш (показаны в Таблице 68-1) не связаны с командами меню напрямую.

Комбинация клавиш Действие
Command–Space bar Поворачивает доступные системы шрифта
Option–Command–Space bar Поворачивает расположение клавиш на клавиатуре и способы ввода в рамках шрифта
modifier key–Command–Space bar Ограничено Apple
Command–Right Arrow Изменяет расположение клавиш клавиатуры на текущее расположение шрифта Roman
Command–Left Arrow Меняет расположение клавиш клавиатуры на текущее расположение системного шрифта
Таблица 68-1 Комбинации клавиш, предназначенные для международных систем

как не запутать пользователя? / Хабр

Уверен, всем приходилось работать с интерфейсами drag-and-drop, а многим — разрабатывать ПО с таковыми. В большинстве случаев факт drop’а объекта-draggable на объект-target устанавливается по факту попадания координат курсора мыши в bounding box объекта-target в обработчке событий типа mouseUp, dragStop и прочих.

Так работают почти все примеры, которые мне встречались. Но некоторое время назад, при реализации модуля интерактивного задания для образовательного ресурса, я столкнулся с тем, что такой подход не очень удобен. Основная причина — объекты-target существенно меньше объектов-draggable. Поэтому целится мышью неудбоно и утомительно. Таща крупный объектами-draggable, пользователь полностью перекрывает объект-target и не видит куда объект падает.

Соответственно было принято решение обрабатывать так:

  • если имеется контакт мыши с объектом-target, тогда drop будет строго на него
  • если нет, тогда ориентируемся на контакт bounding box объекта-draggable с bounding box объектов-target
    • если имеется контакт только с одним объектом-draggable — всё ясно, drop на него
    • а вот контакт с двумя и более — неоднозначная ситуация, куда делать drop — неясно

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

Подсветка.

Также мы решили в случае однозначности подсвечивать контактирующий объект-target (условно) зеленым цветом, а в случае неоднозначности все контактирующие объекты-target — желтым. Таким образом мы даем пользователю подсказку — почему у него в одном случае drop происходит нормально, а в другом — нет.

Однако! Напомню, что речь идет об учебном задании. Есть мнение, что такая подсветка может восприниматься как подсказка о правильности или неправильности попытки решения, а не о самом факте допустимости drop’а. При этом, позже к заданию добавили режим подсветки правильных ответов после вызова процедуры проверки. Если drop был на правильный объект-target, тогда объект-draggable подсвечивается зеленым, если нет — красным. И это стало сильно резонировать с подсветкой в процессе самого выполнения задания. Мы поменяли там цвета и стили подсветки, но насколько понятен такой интерфейс — неясно.

Есть идея исключить ситуацию неоднозначности, перейти к оценке контактов областей не одномоментно, а с учётом их возникновения во времени. И показывать только последний возникший. Но и тут возможна неоднозначность, в зависимости от того, сколько областей будет контактировать при каждом вызове обработчика событий.

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

UPD: Изначально идея об использовании пересечений по областям пришла при разработке приложений для интерактивных досок — чтобы меньше тянуться и метаться у интерактивной доски. Можно взять блок объекта-draggable и легко дотянуться его уголком до области объекта-target. Если же ориентироваться на мышь — может потребоваться лишний раз перейти вдоль доски, а значит лишний раз отбросить тень (экономят, не берут ультракороткофокусные проекторы).

n-drop — это… Что такое Drag-n-drop?

  • Drag and drop — 〈[ dræg ənd drɔ̣p] n.; ; unz.; EDV〉 das Anklicken eines Objektes, das auf dem Computerbildschirm (in eine andere Datei bzw. an eine andere Stelle) verschoben u. dort wieder losgelassen wird [<engl. drag „ziehen“ + and „und“ + drop „fallen… …   Universal-Lexikon

  • DRAG-AND-DROP — Форма выполнения каких либо действий в графических интерфейсах пользователя, подразумевающая использование компьютерной мыши. В переводе с английского означает буквально: тащи и бросай. Действие выполняется путем оперирования видимыми на экране… …   Словарь бизнес-терминов

  • drag and drop — ► IT to move something from one area of a computer screen to another using the mouse: »The software allows you to drag and drop elements for the page images, text, etc. anywhere you want. Main Entry: ↑drag …   Financial and business terms

  • drag and drop — (computing) To move an icon, file, etc across the screen using a mouse and release it in a different place (dragˈ and dropˈ adjective) • • • Main Entry: ↑drag …   Useful english dictionary

  • Drag and drop — 〈[dræg ənd drɔ̣p] n.; Gen.: ; Pl.: unz.; EDV〉 das Anklicken eines Objektes, das auf dem Computerbildschirm (in eine andere Datei bzw. an eine andere Stelle) verschoben u. dort wieder losgelassen wird [Etym.: <engl. drag »ziehen« + and »und« +… …   Lexikalische Deutsches Wörterbuch

  • drag-and-drop — UK US verb [transitive] [present tense I/you/we/they drag and drop he/she/it drags and drops present participle dragging and dropping past tense …   Useful english dictionary

  • drag-and-drop — verb transitive COMPUTING to move something across a computer screen using the MOUSE and place it where you want it to be …   Usage of the words and phrases in modern English

  • Drag’n’drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischen… …   Deutsch Wikipedia

  • Drag-and-Drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischen… …   Deutsch Wikipedia

  • Drag-and-drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischen… …   Deutsch Wikipedia

  • Drag and Drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischer… …   Deutsch Wikipedia

  • Drag and Drop — это… Что такое Drag and Drop?

  • Drag and drop — 〈[ dræg ənd drɔ̣p] n.; ; unz.; EDV〉 das Anklicken eines Objektes, das auf dem Computerbildschirm (in eine andere Datei bzw. an eine andere Stelle) verschoben u. dort wieder losgelassen wird [<engl. drag „ziehen“ + and „und“ + drop „fallen… …   Universal-Lexikon

  • DRAG-AND-DROP — Форма выполнения каких либо действий в графических интерфейсах пользователя, подразумевающая использование компьютерной мыши. В переводе с английского означает буквально: тащи и бросай. Действие выполняется путем оперирования видимыми на экране… …   Словарь бизнес-терминов

  • drag and drop — (computing) To move an icon, file, etc across the screen using a mouse and release it in a different place (dragˈ and dropˈ adjective) • • • Main Entry: ↑drag …   Useful english dictionary

  • drag and drop — ► IT to move something from one area of a computer screen to another using the mouse: »The software allows you to drag and drop elements for the page images, text, etc. anywhere you want. Main Entry: ↑drag …   Financial and business terms

  • drag-and-drop — UK US verb [transitive] [present tense I/you/we/they drag and drop he/she/it drags and drops present participle dragging and dropping past tense …   Useful english dictionary

  • Drag and drop — 〈[dræg ənd drɔ̣p] n.; Gen.: ; Pl.: unz.; EDV〉 das Anklicken eines Objektes, das auf dem Computerbildschirm (in eine andere Datei bzw. an eine andere Stelle) verschoben u. dort wieder losgelassen wird [Etym.: <engl. drag »ziehen« + and »und« +… …   Lexikalische Deutsches Wörterbuch

  • drag-and-drop — verb transitive COMPUTING to move something across a computer screen using the MOUSE and place it where you want it to be …   Usage of the words and phrases in modern English

  • Drag-and-Drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischen… …   Deutsch Wikipedia

  • Drag-and-drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischen… …   Deutsch Wikipedia

  • Drag and Drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischer… …   Deutsch Wikipedia

  • Drag and drop — typische Drag and Drop Aktion: Dateien werden mit der Maus zwischen Verzeichnissen verschoben Drag and Drop, oft auch Drag Drop oder Drag n Drop, deutsch „Ziehen und Fallenlassen“, kurz D D, ist eine Methode zur Bedienung grafischen… …   Deutsch Wikipedia

  • Пример использования WxPython для создания нодового интерфейса. Часть 4: Реализуем Drag&Drop / Хабр

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

    В этой части мы добавим поддерку Drag&Drop к нашему приложению и научим его таким образом создавать новые ноды.

    Часть 1: Учимся рисовать
    Часть 2: Обработка событий мыши
    Часть 3: Продолжаем добавлять фичи + обработка клавиатуры
    Часть 4: Реализуем Drag&Drop
    Часть 5: Соединяем ноды

    Кому интересно, добро пожаловать под кат…

    9. Добавляем поддержку Drag&Drop

    Поддержка Drag&Drop — штука полезная и популярная, но тут мы ее будем использовать не совсем по назначению. Мы таким образом будем создавать новые ноды. Работает это дело достаточно просто. Требуется создать объект класса «wx.TextDropTarget» и передать его в метод «SetDropTarget» класса «wx.Window» от которого наследуется наш канвас. Соответственно, в момент дропа будет вызван метод «wx.TextDropTarget.OnDropText», который нам и надо будет реализовать. Для теста, реализация этого класса будет выглядеть так:
    class TextDropTarget(wx.TextDropTarget):
        def __init__(self):
            wx.TextDropTarget.__init__(self)
        
        def OnDropText(self, x, y, data):
            print x, y, data
    

    Теперь при бросании текста в окно, в консоле будет печататься сообщение с позицией и самим текстом. Как вы могли догататься, для принятия файлов, существует похожий класс «wx.FileDropTarget», который работает аналогичным образом, ну или класс «wx.PyDropTarget», который умеет принимать все и вся.
    10. Создаем ноды с Drag&Drop

    Просто печатать текст не очень полезно, поэтому мы используем полученный текст, чтобы создавать ноды с ним. Но для начала надо немного изменить архитектуру и добавить фабрику нод (это пригодится на будущее). На данный момент — это будет очень простая фабрика:
    class NodesFactory(object):
        def __init__(self):
            pass
        
        def CreateNodeFromDescription(self, nodeDescription):
            return SimpleTextBoxNode(text=nodeDescription)
    

    которая просто создает экземплят «SimpleTextBoxNode», который является слегда продвинутым наследником «SimpleBoxNode»:
    class SimpleTextBoxNode(SimpleBoxNode):
        def __init__(self, **kwargs):
            super(SimpleTextBoxNode, self).__init__(**kwargs)
            self.text = kwargs.get("text", "No text")
            
        def Render(self, gc):
            super(SimpleTextBoxNode, self).Render(gc)
    
            gc.DrawText(self.text, self.position[0]+10, self.position[1]+10)
    

    который в свою очередь рендерит заданный текст поверх прямоугольной ноды.
    Осталось к канвасу добавить метод, позволяющий добавлять новые ноды из описания:
        def CreateNodeFromDescriptionAtPosition(self, nodeDescription, pos):
            node = self._nodesFactory.CreateNodeFromDescription(nodeDescription)
            if node:
                node.position = pos
                self._canvasObjects.append(node)
                self.Render()
    

    И немного модернизировать TextDropTarget, чтобы он вызывал этот метод при поступлении текста:
    class TextDropTarget(wx.TextDropTarget):
        def __init__(self, canvas):
            wx.TextDropTarget.__init__(self)
            self._canvas = canvas
        
        def OnDropText(self, x, y, data):
            print x, y, data
            self._canvas.CreateNodeFromDescriptionAtPosition(data, [x, y])
    

    И теперь мы можем создавать новые текстовые ноды, просто бросая фрагменты текста на канвас.
    Выглядит все это вот так:

    Код, как и всегда, можно найти в соответствующем коммите на GitHub’е.
    11. Клонируем ноды с Drag&Drop

    Но кроме создания нод, с помощью Drag&Drop можно также организовать и копирование нод, причем очень легко. Если пользователь в момент начала перетаскивания ноды зажмет Ctrl, нам надо просто инициировать начало Drag&Drop’а и отдать описание ноды. А код создания ноды сделает для нас всю оставшуюся работу. Для инициации Drag&Drop’а мы добавим следующий код в обработчик нажатия левой кнопки мыши:
            if evt.ControlDown() and self._objectUnderCursor.clonable:
                text = self._objectUnderCursor.GetCloningNodeDescription()
                data = wx.TextDataObject(text)
                dropSource = wx.DropSource(self)
                dropSource.SetData(data)
                dropSource.DoDragDrop(wx.Drag_AllowMove)
    

    Тут мы создаем источник Drag&Drop’а и отдаем ему описание, которое мы получили от ноды. Осталось реализовать метод «GetCloningNodeDescription» у ноды и все будет готово. Но сначала реализуем интерфейс:
    class ClonableObject(CanvasObject):
        def __init__(self, **kwargs):
            super(ClonableObject, self).__init__(**kwargs)
            self.clonable = True
    
        def GetCloningNodeDescription(self):
            """
            GetNodeDescription should return a dictionary that contains 
            all information required for cloning this node at another position
            """
            raise NotImplementedError()
    

    А теперь уже реализацию метода у ноды:
        def GetCloningNodeDescription(self):
            return self.text
    

    которая просто отдает ее текст.
    Текущая версия кода живет тут.
    12. Масштабирубщиеся ноды

    Ну и перед завершением 4ой части, добавим последнюю маленькую рюшечку. Сделаем так, чтобы ноды масштабировались под размер текста. Для этого мы немного изменим метод рендеринга текстовой ноды:
        def Render(self, gc):
            textDimensions = gc.GetTextExtent(self.text)
            self.boundingBoxDimensions = [textDimensions[0]+20, textDimensions[1]+20] 
            super(SimpleTextBoxNode, self).Render(gc)
    
            gc.DrawText(self.text, self.position[0]+10, self.position[1]+10)
    

    Метод «GetTextExtent» в данном случае возвращает размер прямоугольника, который занимает текст. Соответственно перед рендерингом ноды, мы обновляем ее размеры так, чтобы она была на 10 пикселей больше текста с каждой стороны. Вот так теперь выглядит весь этот процесс:

    Код живет в этом коммите на GitHub’е.

    PS: Об опечатках пишите в личку.

    Drag-n-Drop DHTMLX Документы

    dhtmlxTree обладает расширенной функциональностью перетаскивания. С помощью этой функции можно изменять порядок элементов в дереве и перетаскивать элементы между деревьями. Чтобы включить перетаскивание, вы должны определить режим перетаскивания.

      
     var source = new dhx.Tree ("tree-source", {dragMode: "source", dropBehaviour: "сложный"});
    var target = new dhx.Tree ("tree-target", {dragMode: "target", dropBehaviour: "сложный"}); 

    Режим перетаскивания

    В дереве доступны три режима перетаскивания:

    • «цель» — дерево берет предметы из других деревьев, при этом его предметы нельзя вытащить из него
    • «источник» — дерево позволяет перетаскивать свои элементы и не может брать предметы из других деревьев.
    • «оба» — дерево одновременно берет элементы из других деревьев и позволяет также перетаскивать свои элементы.

    Установив режим перетаскивания, вы автоматически активируете функцию перетаскивания.

      
     var tree = new dhx.Tree ("tree_container", {
        dragMode: "источник"
    }); 

    Связанный образец: Дерево. Режимы перетаскивания

    Обратите внимание, что перетаскивание внутри дерева работает, если оно имеет значение dragMode: «both» в его объекте конфигурации.

    Поведение при падении

    Вы можете указать поведение перетаскивания элементов дерева с помощью dropBehaviour в объекте конфигурации дерева.

    Существует три режима поведения перетаскиваемого элемента дерева:

    • «дочерний» — перетаскиваемый элемент становится дочерним по отношению к элементу, на который он перетаскивается.

    • «sibling» — перетаскиваемый элемент становится родственником элемента, на который он перетаскивается.

    • «сложный» — перетаскиваемый элемент может стать как дочерним, так и родственным по отношению к целевому элементу, в зависимости от позиции, указанной путем выделения (проверьте изображения выше)

    Копирование перетаскиваемого объекта

    Вместо того, чтобы перемещать перетаскиваемый элемент в новое место в том же или другом дереве, вы можете скопировать его.Используйте опцию dragCopy в объекте конфигурации дерева.

      
     var treeSource = new dhx.Tree ("tree-source", {dragMode: "source", dragCopy: true});
    var treeTarget = new dhx.Tree ("tree-target", {dragMode: "target", dragCopy: true}); 

    Связанный образец: Дерево. Копировать перетаскиваемый элемент

    Вернуться наверх .

    новейших вопросов с перетаскиванием — Qaru

    Переполнение стека
    1. Около
    2. Продукты
    3. Для команд
    1. Переполнение стека Общественные вопросы и ответы
    2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
    3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
    4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
    5. Реклама Обратитесь к разработчикам и технологам со всего мира
    6. О компании
    .

    gwt: перетащите дерево

    Переполнение стека
    1. Около
    2. Продукты
    3. Для команд
    1. Переполнение стека Общественные вопросы и ответы
    2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
    3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
    4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
    5. Реклама Обратитесь к разработчикам и технологам со всего мира
    6. О компании

    Загрузка…

    .

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *