171QQuickSelectionRectanglePrivate::QQuickSelectionRectanglePrivate()
172 : QQuickControlPrivate()
174 m_tapHandler =
new QQuickTapHandler();
175 m_dragHandler =
new QQuickDragHandler();
176 m_dragHandler->setTarget(
nullptr);
181 QObject::connect(&m_scrollTimer, &QTimer::timeout, &m_scrollTimer, [&]{
182 if (m_topLeftHandle && m_draggedHandle == m_topLeftHandle.data())
183 m_selectable->setSelectionStartPos(m_scrollToPoint);
185 m_selectable->setSelectionEndPos(m_scrollToPoint);
187 const QSizeF dist = m_selectable->scrollTowardsPoint(m_scrollToPoint, m_scrollSpeed);
188 m_scrollToPoint.rx() += dist.width() > 0 ? m_scrollSpeed.width() : -m_scrollSpeed.width();
189 m_scrollToPoint.ry() += dist.height() > 0 ? m_scrollSpeed.height() : -m_scrollSpeed.height();
190 m_scrollSpeed = QSizeF(qAbs(dist.width() * 0.007), qAbs(dist.height() * 0.007));
193 QObject::connect(m_tapHandler, &QQuickTapHandler::pressedChanged, m_tapHandler, [
this]() {
194 Q_Q(QQuickSelectionRectangle);
196 if (!m_tapHandler->isPressed()) {
199 if (q->active() && !m_selectable->hasSelection())
200 updateActiveState(
false);
203 if (m_effectiveSelectionMode != QQuickSelectionRectangle::Drag)
206 const QPointF pos = m_tapHandler->point().pressPosition();
207 const auto modifiers = m_tapHandler->point().modifiers();
208 if (modifiers & ~(Qt::ControlModifier | Qt::ShiftModifier))
212 const auto isSelectionRectValid = [](
const QRectF &selectionRect) ->
bool {
213 return ((selectionRect.width() != 0) || (selectionRect.height() != 0));
216 if (modifiers & Qt::ShiftModifier) {
221 if (!m_selectable->startSelection(pos, modifiers))
223 m_selectable->setSelectionStartPos(QPoint{-1, -1});
225 m_selectable->setSelectionEndPos(pos);
228 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
231 updateActiveState(
true);
232 }
else if (modifiers & Qt::ControlModifier) {
236 if (handleUnderPos(pos) !=
nullptr) {
242 if (!m_selectable->startSelection(pos, modifiers))
244 m_selectable->setSelectionStartPos(pos);
245 m_selectable->setSelectionEndPos(pos);
248 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
251 updateActiveState(
true);
255 QObject::connect(m_tapHandler, &QQuickTapHandler::longPressed, m_tapHandler, [
this]() {
256 if (m_tapHandler->point().device()->type() == QInputDevice::DeviceType::TouchScreen &&
257 m_selectionMode == QQuickSelectionRectangle::Auto) {
258 const QQuickTableView *tableview = qobject_cast<QQuickTableView *>(m_target);
259 if (tableview && !tableview->isInteractive())
262 }
else if (m_effectiveSelectionMode != QQuickSelectionRectangle::PressAndHold) {
266 const QPointF pos = m_tapHandler->point().pressPosition();
267 const auto modifiers = m_tapHandler->point().modifiers();
268 if (handleUnderPos(pos) !=
nullptr) {
275 const auto isSelectionRectValid = [](
const QRectF &selectionRect) ->
bool {
276 return ((selectionRect.width() != 0) || (selectionRect.height() != 0));
279 if (modifiers == Qt::ShiftModifier) {
284 if (!m_selectable->startSelection(pos, modifiers))
286 m_selectable->setSelectionStartPos(QPoint{-1, -1});
288 m_selectable->setSelectionEndPos(pos);
289 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
292 updateActiveState(
true);
296 if (!m_selectable->startSelection(pos, modifiers))
298 m_selectable->setSelectionStartPos(pos);
299 m_selectable->setSelectionEndPos(pos);
300 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
303 updateActiveState(
true);
307 QObject::connect(m_dragHandler, &QQuickDragHandler::activeChanged, m_dragHandler, [
this]() {
308 Q_ASSERT(m_effectiveSelectionMode == QQuickSelectionRectangle::Drag);
309 const QPointF startPos = m_dragHandler->centroid().pressPosition();
310 const QPointF dragPos = m_dragHandler->centroid().position();
311 const auto modifiers = m_dragHandler->centroid().modifiers();
312 if (modifiers & ~(Qt::ControlModifier | Qt::ShiftModifier))
316 const auto isSelectionRectValid = [](
const QRectF &selectionRect) ->
bool {
317 return ((selectionRect.width() != 0) || (selectionRect.height() != 0));
320 if (m_dragHandler->active()) {
324 const bool modifiersHeld = modifiers & (Qt::ControlModifier | Qt::ShiftModifier);
325 if (!m_active || !modifiersHeld) {
326 if (!m_selectable->startSelection(startPos, modifiers))
328 m_selectable->setSelectionStartPos(startPos);
330 m_selectable->setSelectionEndPos(dragPos);
331 m_draggedHandle =
nullptr;
332 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
335 updateActiveState(
true);
336 updateDraggingState(
true);
338 m_scrollTimer.stop();
339 m_selectable->normalizeSelection();
340 updateDraggingState(
false);
344 QObject::connect(m_dragHandler, &QQuickDragHandler::centroidChanged, m_dragHandler, [
this]() {
347 const QPointF pos = m_dragHandler->centroid().position();
348 m_selectable->setSelectionEndPos(pos);
350 scrollTowardsPos(pos);
415 Q_Q(QQuickSelectionRectangle);
418 QObject *obj = delegate->beginCreate(QQmlEngine::contextForObject(q));
419 QQuickItem *handleItem = qobject_cast<QQuickItem*>(obj);
420 const auto handlerTarget =
m_selectable->selectionPointerHandlerTarget();
421 handleItem->setParentItem(handlerTarget);
422 if (
auto attached = getAttachedObject(handleItem))
423 attached->setControl(q);
424 delegate->completeCreate();
425 if (handleItem->z() == 0)
426 handleItem->setZ(100);
429 QQuickDragHandler *dragHandler =
new QQuickDragHandler();
430 dragHandler->setTarget(
nullptr);
431 dragHandler->setParentItem(handleItem);
432 dragHandler->setGrabPermissions(QQuickPointerHandler::CanTakeOverFromAnything);
434 QQuickHoverHandler *hoverHandler =
new QQuickHoverHandler();
435 hoverHandler->setTarget(
nullptr);
436 hoverHandler->setParentItem(handleItem);
438 hoverHandler->setCursorShape(Qt::SizeFDiagCursor);
440 hoverHandler->setBlocking(
true);
444 QQuickTapHandler *tapHandler =
new QQuickTapHandler();
445 tapHandler->setTarget(
nullptr);
446 tapHandler->setParentItem(handleItem);
449 tapHandler->setGesturePolicy(QQuickTapHandler::DragWithinBounds);
451 QObject::connect(dragHandler, &QQuickDragHandler::activeChanged, q,
452 [
this, corner, handleItem, dragHandler]() {
453 if (dragHandler->active()) {
454 const QPointF localPos = dragHandler->centroid().position();
455 const QPointF pos = handleItem->mapToItem(handleItem->parentItem(), localPos);
456 if (corner == Qt::TopLeftCorner)
457 m_selectable->setSelectionStartPos(pos);
459 m_selectable->setSelectionEndPos(pos);
461 m_draggedHandle = handleItem;
463 updateDraggingState(
true);
465 QGuiApplication::setOverrideCursor(Qt::SizeFDiagCursor);
468 m_scrollTimer.stop();
469 m_selectable->normalizeSelection();
470 updateDraggingState(
false);
472 QGuiApplication::restoreOverrideCursor();
477 QObject::connect(dragHandler, &QQuickDragHandler::centroidChanged, q,
478 [
this, corner, handleItem, dragHandler]() {
482 const QPointF localPos = dragHandler->centroid().position();
483 const QPointF pos = handleItem->mapToItem(handleItem->parentItem(), localPos);
484 if (corner == Qt::TopLeftCorner)
485 m_selectable->setSelectionStartPos(pos);
487 m_selectable->setSelectionEndPos(pos);
490 scrollTowardsPos(pos);
547 Q_Q(QQuickSelectionRectangle);
549 const bool enabled = q->isEnabled();
550 m_tapHandler->setEnabled(enabled);
552 if (m_selectionMode == QQuickSelectionRectangle::Auto) {
553 if (m_target && qobject_cast<QQuickScrollView *>(m_target->parentItem())) {
556 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
557 m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::Mouse);
558 m_dragHandler->setEnabled(enabled);
559 }
else if (
const auto flickable = qobject_cast<QQuickFlickable *>(m_target)) {
563 if (enabled && (!flickable->isInteractive() ||
564 !flickable->acceptedMouseButtons().testFlag(Qt::LeftButton))) {
565 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
566 m_dragHandler->setAcceptedDevices(flickable->isInteractive()
567 ? QInputDevice::DeviceType::Mouse
568 : QInputDevice::DeviceType::AllDevices);
569 m_dragHandler->setEnabled(
true);
571 m_effectiveSelectionMode = QQuickSelectionRectangle::PressAndHold;
572 m_dragHandler->setEnabled(
false);
575 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
576 m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::Mouse);
577 m_dragHandler->setEnabled(enabled);
579 }
else if (m_selectionMode == QQuickSelectionRectangle::Drag) {
580 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
581 m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::AllDevices);
582 m_dragHandler->setEnabled(enabled);
584 m_effectiveSelectionMode = QQuickSelectionRectangle::PressAndHold;
585 m_dragHandler->setEnabled(
false);