170QQuickSelectionRectanglePrivate::QQuickSelectionRectanglePrivate()
171 : QQuickControlPrivate()
173 m_tapHandler =
new QQuickTapHandler();
174 m_dragHandler =
new QQuickDragHandler();
175 m_dragHandler->setTarget(
nullptr);
177 QObject::connect(&m_scrollTimer, &QTimer::timeout, [&]{
178 if (m_topLeftHandle && m_draggedHandle == m_topLeftHandle.data())
179 m_selectable->setSelectionStartPos(m_scrollToPoint);
181 m_selectable->setSelectionEndPos(m_scrollToPoint);
183 const QSizeF dist = m_selectable->scrollTowardsPoint(m_scrollToPoint, m_scrollSpeed);
184 m_scrollToPoint.rx() += dist.width() > 0 ? m_scrollSpeed.width() : -m_scrollSpeed.width();
185 m_scrollToPoint.ry() += dist.height() > 0 ? m_scrollSpeed.height() : -m_scrollSpeed.height();
186 m_scrollSpeed = QSizeF(qAbs(dist.width() * 0.007), qAbs(dist.height() * 0.007));
189 QObject::connect(m_tapHandler, &QQuickTapHandler::pressedChanged, [
this]() {
190 Q_Q(QQuickSelectionRectangle);
192 if (!m_tapHandler->isPressed()) {
195 if (q->active() && !m_selectable->hasSelection())
196 updateActiveState(
false);
199 if (m_effectiveSelectionMode != QQuickSelectionRectangle::Drag)
202 const QPointF pos = m_tapHandler->point().pressPosition();
203 const auto modifiers = m_tapHandler->point().modifiers();
204 if (modifiers & ~(Qt::ControlModifier | Qt::ShiftModifier))
208 const auto isSelectionRectValid = [](
const QRectF &selectionRect) ->
bool {
209 return ((selectionRect.width() != 0) || (selectionRect.height() != 0));
212 if (modifiers & Qt::ShiftModifier) {
217 if (!m_selectable->startSelection(pos, modifiers))
219 m_selectable->setSelectionStartPos(QPoint{-1, -1});
221 m_selectable->setSelectionEndPos(pos);
224 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
227 updateActiveState(
true);
228 }
else if (modifiers & Qt::ControlModifier) {
232 if (handleUnderPos(pos) !=
nullptr) {
238 if (!m_selectable->startSelection(pos, modifiers))
240 m_selectable->setSelectionStartPos(pos);
241 m_selectable->setSelectionEndPos(pos);
244 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
247 updateActiveState(
true);
251 QObject::connect(m_tapHandler, &QQuickTapHandler::longPressed, [
this]() {
252 if (m_tapHandler->point().device()->type() == QInputDevice::DeviceType::TouchScreen &&
253 m_selectionMode == QQuickSelectionRectangle::Auto) {
254 const QQuickTableView *tableview = qobject_cast<QQuickTableView *>(m_target);
255 if (tableview && !tableview->isInteractive())
258 }
else if (m_effectiveSelectionMode != QQuickSelectionRectangle::PressAndHold) {
262 const QPointF pos = m_tapHandler->point().pressPosition();
263 const auto modifiers = m_tapHandler->point().modifiers();
264 if (handleUnderPos(pos) !=
nullptr) {
271 const auto isSelectionRectValid = [](
const QRectF &selectionRect) ->
bool {
272 return ((selectionRect.width() != 0) || (selectionRect.height() != 0));
275 if (modifiers == Qt::ShiftModifier) {
280 if (!m_selectable->startSelection(pos, modifiers))
282 m_selectable->setSelectionStartPos(QPoint{-1, -1});
284 m_selectable->setSelectionEndPos(pos);
285 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
288 updateActiveState(
true);
292 if (!m_selectable->startSelection(pos, modifiers))
294 m_selectable->setSelectionStartPos(pos);
295 m_selectable->setSelectionEndPos(pos);
296 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
299 updateActiveState(
true);
303 QObject::connect(m_dragHandler, &QQuickDragHandler::activeChanged, [
this]() {
304 Q_ASSERT(m_effectiveSelectionMode == QQuickSelectionRectangle::Drag);
305 const QPointF startPos = m_dragHandler->centroid().pressPosition();
306 const QPointF dragPos = m_dragHandler->centroid().position();
307 const auto modifiers = m_dragHandler->centroid().modifiers();
308 if (modifiers & ~(Qt::ControlModifier | Qt::ShiftModifier))
312 const auto isSelectionRectValid = [](
const QRectF &selectionRect) ->
bool {
313 return ((selectionRect.width() != 0) || (selectionRect.height() != 0));
316 if (m_dragHandler->active()) {
320 const bool modifiersHeld = modifiers & (Qt::ControlModifier | Qt::ShiftModifier);
321 if (!m_active || !modifiersHeld) {
322 if (!m_selectable->startSelection(startPos, modifiers))
324 m_selectable->setSelectionStartPos(startPos);
326 m_selectable->setSelectionEndPos(dragPos);
327 m_draggedHandle =
nullptr;
328 if (!isSelectionRectValid(m_selectable->selectionRectangle()))
331 updateActiveState(
true);
332 updateDraggingState(
true);
334 m_scrollTimer.stop();
335 m_selectable->normalizeSelection();
336 updateDraggingState(
false);
340 QObject::connect(m_dragHandler, &QQuickDragHandler::centroidChanged, [
this]() {
343 const QPointF pos = m_dragHandler->centroid().position();
344 m_selectable->setSelectionEndPos(pos);
346 scrollTowardsPos(pos);
411 Q_Q(QQuickSelectionRectangle);
414 QObject *obj = delegate->beginCreate(QQmlEngine::contextForObject(q));
415 QQuickItem *handleItem = qobject_cast<QQuickItem*>(obj);
416 const auto handlerTarget =
m_selectable->selectionPointerHandlerTarget();
417 handleItem->setParentItem(handlerTarget);
418 if (
auto attached = getAttachedObject(handleItem))
419 attached->setControl(q);
420 delegate->completeCreate();
421 if (handleItem->z() == 0)
422 handleItem->setZ(100);
425 QQuickDragHandler *dragHandler =
new QQuickDragHandler();
426 dragHandler->setTarget(
nullptr);
427 dragHandler->setParentItem(handleItem);
428 dragHandler->setGrabPermissions(QQuickPointerHandler::CanTakeOverFromAnything);
430 QQuickHoverHandler *hoverHandler =
new QQuickHoverHandler();
431 hoverHandler->setTarget(
nullptr);
432 hoverHandler->setParentItem(handleItem);
434 hoverHandler->setCursorShape(Qt::SizeFDiagCursor);
436 hoverHandler->setBlocking(
true);
440 QQuickTapHandler *tapHandler =
new QQuickTapHandler();
441 tapHandler->setTarget(
nullptr);
442 tapHandler->setParentItem(handleItem);
445 tapHandler->setGesturePolicy(QQuickTapHandler::DragWithinBounds);
447 QObject::connect(dragHandler, &QQuickDragHandler::activeChanged, [
this, corner, handleItem, dragHandler]() {
448 if (dragHandler->active()) {
449 const QPointF localPos = dragHandler->centroid().position();
450 const QPointF pos = handleItem->mapToItem(handleItem->parentItem(), localPos);
451 if (corner == Qt::TopLeftCorner)
452 m_selectable->setSelectionStartPos(pos);
454 m_selectable->setSelectionEndPos(pos);
456 m_draggedHandle = handleItem;
458 updateDraggingState(
true);
460 QGuiApplication::setOverrideCursor(Qt::SizeFDiagCursor);
463 m_scrollTimer.stop();
464 m_selectable->normalizeSelection();
465 updateDraggingState(
false);
467 QGuiApplication::restoreOverrideCursor();
472 QObject::connect(dragHandler, &QQuickDragHandler::centroidChanged, [
this, corner, handleItem, dragHandler]() {
476 const QPointF localPos = dragHandler->centroid().position();
477 const QPointF pos = handleItem->mapToItem(handleItem->parentItem(), localPos);
478 if (corner == Qt::TopLeftCorner)
479 m_selectable->setSelectionStartPos(pos);
481 m_selectable->setSelectionEndPos(pos);
484 scrollTowardsPos(pos);
541 Q_Q(QQuickSelectionRectangle);
543 const bool enabled = q->isEnabled();
544 m_tapHandler->setEnabled(enabled);
546 if (m_selectionMode == QQuickSelectionRectangle::Auto) {
547 if (m_target && qobject_cast<QQuickScrollView *>(m_target->parentItem())) {
550 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
551 m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::Mouse);
552 m_dragHandler->setEnabled(enabled);
553 }
else if (
const auto flickable = qobject_cast<QQuickFlickable *>(m_target)) {
557 if (enabled && (!flickable->isInteractive() ||
558 !flickable->acceptedMouseButtons().testFlag(Qt::LeftButton))) {
559 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
560 m_dragHandler->setAcceptedDevices(flickable->isInteractive()
561 ? QInputDevice::DeviceType::Mouse
562 : QInputDevice::DeviceType::AllDevices);
563 m_dragHandler->setEnabled(
true);
565 m_effectiveSelectionMode = QQuickSelectionRectangle::PressAndHold;
566 m_dragHandler->setEnabled(
false);
569 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
570 m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::Mouse);
571 m_dragHandler->setEnabled(enabled);
573 }
else if (m_selectionMode == QQuickSelectionRectangle::Drag) {
574 m_effectiveSelectionMode = QQuickSelectionRectangle::Drag;
575 m_dragHandler->setAcceptedDevices(QInputDevice::DeviceType::AllDevices);
576 m_dragHandler->setEnabled(enabled);
578 m_effectiveSelectionMode = QQuickSelectionRectangle::PressAndHold;
579 m_dragHandler->setEnabled(
false);