diff options
Diffstat (limited to 'tests/manual/examples/widgets/scroller')
5 files changed, 304 insertions, 0 deletions
diff --git a/tests/manual/examples/widgets/scroller/CMakeLists.txt b/tests/manual/examples/widgets/scroller/CMakeLists.txt new file mode 100644 index 0000000000..cd920bd361 --- /dev/null +++ b/tests/manual/examples/widgets/scroller/CMakeLists.txt @@ -0,0 +1,3 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause +qt_internal_add_example(graphicsview) diff --git a/tests/manual/examples/widgets/scroller/graphicsview/CMakeLists.txt b/tests/manual/examples/widgets/scroller/graphicsview/CMakeLists.txt new file mode 100644 index 0000000000..3c50b6d99f --- /dev/null +++ b/tests/manual/examples/widgets/scroller/graphicsview/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(graphicsview LANGUAGES CXX) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/scroller/graphicsview") + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) + +qt_standard_project_setup() + +qt_add_executable(graphicsview + main.cpp +) + +set_target_properties(graphicsview PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(graphicsview PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Widgets +) + +install(TARGETS graphicsview + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/tests/manual/examples/widgets/scroller/graphicsview/graphicsview.pro b/tests/manual/examples/widgets/scroller/graphicsview/graphicsview.pro new file mode 100644 index 0000000000..39bdb2bc2c --- /dev/null +++ b/tests/manual/examples/widgets/scroller/graphicsview/graphicsview.pro @@ -0,0 +1,8 @@ +QT += widgets + +TEMPLATE = app +SOURCES = main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/scroller/graphicsview +INSTALLS += target diff --git a/tests/manual/examples/widgets/scroller/graphicsview/main.cpp b/tests/manual/examples/widgets/scroller/graphicsview/main.cpp new file mode 100644 index 0000000000..b8df2b1b2e --- /dev/null +++ b/tests/manual/examples/widgets/scroller/graphicsview/main.cpp @@ -0,0 +1,255 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QtCore> +#include <QtWidgets> + +#define NUM_ITEMS 100 +#define NUM_LISTS 10 + +/*! + \class RectObject + Note that it needs to be a QGraphicsObject or else the gestures will not work correctly. +*/ +class RectObject : public QGraphicsObject +{ + Q_OBJECT + +public: + + RectObject(const QString &text, qreal x, qreal y, qreal width, qreal height, QBrush brush, QGraphicsItem *parent = nullptr) + : QGraphicsObject(parent) + , m_text(text) + , m_rect(x, y, width, height) + , m_pen(brush.color().lighter(), 3.0) + , m_brush(brush) + { + setFlag(QGraphicsItem::ItemClipsToShape, true); + } + + QRectF boundingRect() const override + { + // here we only want the size of the children and not the size of the children of the children... + qreal halfpw = m_pen.widthF() / 2; + QRectF rect = m_rect; + if (halfpw > 0.0) + rect.adjust(-halfpw, -halfpw, halfpw, halfpw); + + return rect; + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setPen(m_pen); + painter->setBrush(m_brush); + painter->drawRect(m_rect); + + painter->setPen(Qt::black); + QFont f; + f.setPixelSize(m_rect.height()); + painter->setFont(f); + painter->drawText(m_rect, Qt::AlignCenter, m_text); + } + + QString m_text; + QRectF m_rect; + QPen m_pen; + QBrush m_brush; +}; + +class ViewObject : public QGraphicsObject +{ + Q_OBJECT +public: + ViewObject(QGraphicsObject *parent) + : QGraphicsObject(parent) + { } + + QRectF boundingRect() const override + { + QRectF rect; + const auto items = childItems(); + for (const QGraphicsItem *item : items) + rect |= item->boundingRect().translated(item->pos()); + return rect; + } + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override + { } +}; + +class ListObject : public QGraphicsObject +{ + Q_OBJECT + +public: + ListObject(const QSizeF &size, bool useTouch) + { + m_size = size; + setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); + // grab gesture via Touch or Mouse events + QScroller::grabGesture(this, useTouch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); + + // this needs to be QGraphicsOBJECT - otherwise gesture recognition + // will not work for the parent of the viewport (in this case the + // list) + m_viewport = new ViewObject(this); + + } + + QGraphicsObject *viewport() const + { + return m_viewport; + } + + bool event(QEvent *e) override + { + switch (e->type()) { +// ![2] + case QEvent::ScrollPrepare: { + QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e); + se->setViewportSize(m_size); + QRectF br = m_viewport->boundingRect(); + se->setContentPosRange(QRectF(0, 0, + qMax(qreal(0), br.width() - m_size.width()), + qMax(qreal(0), br.height() - m_size.height()))); + se->setContentPos(-m_viewport->pos()); + se->accept(); + return true; + } +// ![1] +// ![2] + case QEvent::Scroll: { + QScrollEvent *se = static_cast<QScrollEvent *>(e); + m_viewport->setPos(-se->contentPos() - se->overshootDistance()); + return true; + } +// ![2] + default: + break; + } + return QGraphicsObject::event(e); + } + + bool sceneEvent(QEvent *e) override + { + switch (e->type()) { + case QEvent::TouchBegin: { + // We need to return true for the TouchBegin here in the + // top-most graphics object - otherwise gestures in our parent + // objects will NOT work at all (the accept() flag is already + // set due to our setAcceptTouchEvents(true) call in the c'tor + return true; + + } + case QEvent::GraphicsSceneMousePress: { + // We need to return true for the MousePress here in the + // top-most graphics object - otherwise gestures in our parent + // objects will NOT work at all (the accept() flag is already + // set to true by Qt) + return true; + + } + default: + break; + } + return QGraphicsObject::sceneEvent(e); + } + + QRectF boundingRect() const override + { + return QRectF(0, 0, m_size.width() + 3, m_size.height()); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setPen(QPen(QColor(100, 100, 100), 3.0)); + painter->drawRect(QRectF(1.5, 1.5, m_size.width() - 3, m_size.height() - 3)); + } + + QSizeF m_size; + ViewObject *m_viewport; +}; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(bool useTouch) + { + m_scene = new QGraphicsScene(); + + // -- make the main list + ListObject *mainList = new ListObject(QSizeF(780, 400), useTouch); + mainList->setObjectName(QLatin1String("MainList")); + m_scene->addItem(mainList); +// ![3] + for (int i=0; i<NUM_LISTS; i++) { + ListObject *childList = new ListObject(QSizeF(mainList->m_size.width()/3, mainList->m_size.height()), useTouch); + childList->setObjectName(QString("ChildList %1").arg(i)); + fillList(childList); + childList->setParentItem(mainList->viewport()); + childList->setPos(i*mainList->m_size.width()/3, 0); + } + mainList->viewport()->setPos(0, 0); + + + /* + list1->setTransformOriginPoint(200, 200); + list1->setRotation(135); + list1->setPos(20 + 200 * .41, 20 + 200 * .41); + */ +// ![3] + + m_view = new QGraphicsView(m_scene); + setCentralWidget(m_view); + setWindowTitle(tr("Gesture example")); + m_scene->setSceneRect(0, 0, m_view->viewport()->width(), m_view->viewport()->height()); + } + + /** + * Fills the list object \a list with RectObjects. + */ + void fillList(ListObject *list) + { + qreal h = list->m_size.height() / 10; + for (int i=0; i<NUM_ITEMS; i++) { + QColor color = QColor(255*i/NUM_ITEMS, 255*(NUM_ITEMS-i)/NUM_ITEMS, 127*(i%2)+64*(i/2%2)); + QString text = QLatin1String("Item #") + QString::number(i); + QGraphicsItem *rect = new RectObject(text, 0, 0, list->m_size.width() - 6, h - 3, QBrush(color), list->viewport()); + rect->setPos(3, h*i+3); + } + list->viewport()->setPos(0, 0); + } + + +protected: + void resizeEvent(QResizeEvent *e) override + { + // resize the scene according to our own size to prevent scrolling + m_scene->setSceneRect(0, 0, m_view->viewport()->width(), m_view->viewport()->height()); + QMainWindow::resizeEvent(e); + } + + QGraphicsScene *m_scene; + QGraphicsView *m_view; +}; + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + bool touch = (a.arguments().contains(QLatin1String("--touch"))); + MainWindow mw(touch); + mw.show(); +#ifdef Q_OS_MAC + mw.raise(); +#endif + return a.exec(); +} + +#include "main.moc" diff --git a/tests/manual/examples/widgets/scroller/scroller.pro b/tests/manual/examples/widgets/scroller/scroller.pro new file mode 100644 index 0000000000..bac3f26554 --- /dev/null +++ b/tests/manual/examples/widgets/scroller/scroller.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS += graphicsview |