mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-02 15:26:00 +08:00
qt 6.5.1 original
This commit is contained in:
37
examples/embedded/flickable/CMakeLists.txt
Normal file
37
examples/embedded/flickable/CMakeLists.txt
Normal file
@ -0,0 +1,37 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(flickable LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/flickable")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(flickable
|
||||
flickable.cpp flickable.h
|
||||
main.cpp
|
||||
)
|
||||
|
||||
set_target_properties(flickable PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(flickable PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
install(TARGETS flickable
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
246
examples/embedded/flickable/flickable.cpp
Normal file
246
examples/embedded/flickable/flickable.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "flickable.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtWidgets>
|
||||
|
||||
class FlickableTicker: QObject
|
||||
{
|
||||
public:
|
||||
FlickableTicker(Flickable *scroller) {
|
||||
m_scroller = scroller;
|
||||
}
|
||||
|
||||
void start(int interval) {
|
||||
if (!m_timer.isActive())
|
||||
m_timer.start(interval, this);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) {
|
||||
Q_UNUSED(event);
|
||||
m_scroller->tick();
|
||||
}
|
||||
|
||||
private:
|
||||
Flickable *m_scroller;
|
||||
QBasicTimer m_timer;
|
||||
};
|
||||
|
||||
class FlickablePrivate
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
Steady,
|
||||
Pressed,
|
||||
ManualScroll,
|
||||
AutoScroll,
|
||||
Stop
|
||||
} State;
|
||||
|
||||
State state;
|
||||
int threshold;
|
||||
QPoint pressPos;
|
||||
QPoint offset;
|
||||
QPoint delta;
|
||||
QPoint speed;
|
||||
FlickableTicker *ticker;
|
||||
QElapsedTimer timeStamp;
|
||||
QWidget *target;
|
||||
QList<QEvent*> ignoreList;
|
||||
};
|
||||
|
||||
Flickable::Flickable()
|
||||
{
|
||||
d = new FlickablePrivate;
|
||||
d->state = FlickablePrivate::Steady;
|
||||
d->threshold = 10;
|
||||
d->ticker = new FlickableTicker(this);
|
||||
d->timeStamp.start();
|
||||
d->target = 0;
|
||||
}
|
||||
|
||||
Flickable::~Flickable()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void Flickable::setThreshold(int th)
|
||||
{
|
||||
if (th >= 0)
|
||||
d->threshold = th;
|
||||
}
|
||||
|
||||
int Flickable::threshold() const
|
||||
{
|
||||
return d->threshold;
|
||||
}
|
||||
|
||||
void Flickable::setAcceptMouseClick(QWidget *target)
|
||||
{
|
||||
d->target = target;
|
||||
}
|
||||
|
||||
static QPoint deaccelerate(const QPoint &speed, int a = 1, int max = 64)
|
||||
{
|
||||
int x = qBound(-max, speed.x(), max);
|
||||
int y = qBound(-max, speed.y(), max);
|
||||
x = (x == 0) ? x : (x > 0) ? qMax(0, x - a) : qMin(0, x + a);
|
||||
y = (y == 0) ? y : (y > 0) ? qMax(0, y - a) : qMin(0, y + a);
|
||||
return QPoint(x, y);
|
||||
}
|
||||
|
||||
void Flickable::handleMousePress(QMouseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
if (d->ignoreList.removeAll(event))
|
||||
return;
|
||||
|
||||
switch (d->state) {
|
||||
|
||||
case FlickablePrivate::Steady:
|
||||
event->accept();
|
||||
d->state = FlickablePrivate::Pressed;
|
||||
d->pressPos = event->position().toPoint();
|
||||
break;
|
||||
|
||||
case FlickablePrivate::AutoScroll:
|
||||
event->accept();
|
||||
d->state = FlickablePrivate::Stop;
|
||||
d->speed = QPoint(0, 0);
|
||||
d->pressPos = event->position().toPoint();
|
||||
d->offset = scrollOffset();
|
||||
d->ticker->stop();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Flickable::handleMouseRelease(QMouseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
if (event->button() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
if (d->ignoreList.removeAll(event))
|
||||
return;
|
||||
|
||||
QPoint delta;
|
||||
|
||||
switch (d->state) {
|
||||
|
||||
case FlickablePrivate::Pressed:
|
||||
event->accept();
|
||||
d->state = FlickablePrivate::Steady;
|
||||
if (d->target) {
|
||||
QMouseEvent *event1 = new QMouseEvent(QEvent::MouseButtonPress,
|
||||
d->pressPos, Qt::LeftButton,
|
||||
Qt::LeftButton, Qt::NoModifier);
|
||||
QMouseEvent *event2 = event->clone();
|
||||
d->ignoreList << event1;
|
||||
d->ignoreList << event2;
|
||||
QApplication::postEvent(d->target, event1);
|
||||
QApplication::postEvent(d->target, event2);
|
||||
}
|
||||
break;
|
||||
|
||||
case FlickablePrivate::ManualScroll:
|
||||
event->accept();
|
||||
delta = event->position().toPoint() - d->pressPos;
|
||||
if (d->timeStamp.elapsed() > 100) {
|
||||
d->timeStamp.start();
|
||||
d->speed = delta - d->delta;
|
||||
d->delta = delta;
|
||||
}
|
||||
d->offset = scrollOffset();
|
||||
d->pressPos = event->position().toPoint();
|
||||
if (d->speed == QPoint(0, 0)) {
|
||||
d->state = FlickablePrivate::Steady;
|
||||
} else {
|
||||
d->speed /= 4;
|
||||
d->state = FlickablePrivate::AutoScroll;
|
||||
d->ticker->start(20);
|
||||
}
|
||||
break;
|
||||
|
||||
case FlickablePrivate::Stop:
|
||||
event->accept();
|
||||
d->state = FlickablePrivate::Steady;
|
||||
d->offset = scrollOffset();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Flickable::handleMouseMove(QMouseEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
return;
|
||||
|
||||
if (d->ignoreList.removeAll(event))
|
||||
return;
|
||||
|
||||
QPoint delta;
|
||||
|
||||
switch (d->state) {
|
||||
|
||||
case FlickablePrivate::Pressed:
|
||||
case FlickablePrivate::Stop:
|
||||
delta = event->position().toPoint() - d->pressPos;
|
||||
if (delta.x() > d->threshold || delta.x() < -d->threshold ||
|
||||
delta.y() > d->threshold || delta.y() < -d->threshold) {
|
||||
d->timeStamp.start();
|
||||
d->state = FlickablePrivate::ManualScroll;
|
||||
d->delta = QPoint(0, 0);
|
||||
d->pressPos = event->position().toPoint();
|
||||
event->accept();
|
||||
}
|
||||
break;
|
||||
|
||||
case FlickablePrivate::ManualScroll:
|
||||
event->accept();
|
||||
delta = event->position().toPoint() - d->pressPos;
|
||||
setScrollOffset(d->offset - delta);
|
||||
if (d->timeStamp.elapsed() > 100) {
|
||||
d->timeStamp.start();
|
||||
d->speed = delta - d->delta;
|
||||
d->delta = delta;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Flickable::tick()
|
||||
{
|
||||
if (d->state == FlickablePrivate:: AutoScroll) {
|
||||
d->speed = deaccelerate(d->speed);
|
||||
setScrollOffset(d->offset - d->speed);
|
||||
d->offset = scrollOffset();
|
||||
if (d->speed == QPoint(0, 0)) {
|
||||
d->state = FlickablePrivate::Steady;
|
||||
d->ticker->stop();
|
||||
}
|
||||
} else {
|
||||
d->ticker->stop();
|
||||
}
|
||||
}
|
40
examples/embedded/flickable/flickable.h
Normal file
40
examples/embedded/flickable/flickable.h
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef FLICKABLE_H
|
||||
#define FLICKABLE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class FlickableTicker;
|
||||
class FlickablePrivate;
|
||||
|
||||
class Flickable
|
||||
{
|
||||
public:
|
||||
|
||||
Flickable();
|
||||
virtual ~Flickable();
|
||||
|
||||
void setThreshold(int threshold);
|
||||
int threshold() const;
|
||||
|
||||
void setAcceptMouseClick(QWidget *target);
|
||||
|
||||
void handleMousePress(QMouseEvent *event);
|
||||
void handleMouseMove(QMouseEvent *event);
|
||||
void handleMouseRelease(QMouseEvent *event);
|
||||
|
||||
protected:
|
||||
virtual QPoint scrollOffset() const = 0;
|
||||
virtual void setScrollOffset(const QPoint &offset) = 0;
|
||||
|
||||
private:
|
||||
void tick();
|
||||
|
||||
private:
|
||||
FlickablePrivate *d;
|
||||
friend class FlickableTicker;
|
||||
};
|
||||
|
||||
#endif // FLICKABLE_H
|
7
examples/embedded/flickable/flickable.pro
Normal file
7
examples/embedded/flickable/flickable.pro
Normal file
@ -0,0 +1,7 @@
|
||||
QT += widgets
|
||||
|
||||
SOURCES = flickable.cpp main.cpp
|
||||
HEADERS = flickable.h
|
||||
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/embedded/flickable
|
||||
INSTALLS += target
|
190
examples/embedded/flickable/main.cpp
Normal file
190
examples/embedded/flickable/main.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "flickable.h"
|
||||
|
||||
// Returns a list of two-word color names
|
||||
static QStringList colorPairs(int max)
|
||||
{
|
||||
// capitalize the first letter
|
||||
QStringList colors = QColor::colorNames();
|
||||
colors.removeAll("transparent");
|
||||
int num = colors.count();
|
||||
for (int c = 0; c < num; ++c)
|
||||
colors[c] = colors[c][0].toUpper() + colors[c].mid(1);
|
||||
|
||||
// combine two colors, e.g. "lime skyblue"
|
||||
QStringList combinedColors;
|
||||
for (int i = 0; i < num; ++i)
|
||||
for (int j = 0; j < num; ++j)
|
||||
combinedColors << QString("%1 %2").arg(colors[i]).arg(colors[j]);
|
||||
|
||||
// randomize it
|
||||
colors.clear();
|
||||
while (combinedColors.count()) {
|
||||
int i = QRandomGenerator::global()->bounded(combinedColors.count());
|
||||
colors << combinedColors[i];
|
||||
combinedColors.removeAt(i);
|
||||
if (colors.count() == max)
|
||||
break;
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
class ColorList : public QWidget, public Flickable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ColorList(QWidget *parent = nullptr)
|
||||
: QWidget(parent) {
|
||||
m_offset = 0;
|
||||
m_height = QFontMetrics(font()).height() + 5;
|
||||
m_highlight = -1;
|
||||
m_selected = -1;
|
||||
|
||||
QStringList colors = colorPairs(999);
|
||||
for (int i = 0; i < colors.count(); ++i) {
|
||||
const QString c = colors[i];
|
||||
const QString str = QString::asprintf("%4d", i + 1);
|
||||
m_colorNames << (str + " " + c);
|
||||
|
||||
QStringList duet = c.split(' ');
|
||||
m_firstColor << QColor::fromString(duet[0]);
|
||||
m_secondColor << QColor::fromString(duet[1]);
|
||||
}
|
||||
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
|
||||
setMouseTracking(true);
|
||||
Flickable::setAcceptMouseClick(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
// reimplement from Flickable
|
||||
virtual QPoint scrollOffset() const {
|
||||
return QPoint(0, m_offset);
|
||||
}
|
||||
|
||||
// reimplement from Flickable
|
||||
virtual void setScrollOffset(const QPoint &offset) {
|
||||
int yy = offset.y();
|
||||
if (yy != m_offset) {
|
||||
m_offset = qBound(0, yy, m_height * m_colorNames.count() - height());
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
p.fillRect(event->rect(), Qt::white);
|
||||
int start = m_offset / m_height;
|
||||
int y = start * m_height - m_offset;
|
||||
if (m_offset <= 0) {
|
||||
start = 0;
|
||||
y = -m_offset;
|
||||
}
|
||||
int end = start + height() / m_height + 1;
|
||||
if (end > m_colorNames.count() - 1)
|
||||
end = m_colorNames.count() - 1;
|
||||
for (int i = start; i <= end; ++i, y += m_height) {
|
||||
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.setPen(Qt::black);
|
||||
if (i == m_highlight) {
|
||||
p.fillRect(0, y, width(), m_height, QColor(0, 64, 128));
|
||||
p.setPen(Qt::white);
|
||||
}
|
||||
if (i == m_selected) {
|
||||
p.fillRect(0, y, width(), m_height, QColor(0, 128, 240));
|
||||
p.setPen(Qt::white);
|
||||
}
|
||||
|
||||
p.drawText(m_height + 2, y, width(), m_height, Qt::AlignVCenter, m_colorNames[i]);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(m_firstColor[i]);
|
||||
p.drawRect(1, y + 1, m_height - 2, m_height - 2);
|
||||
p.setBrush(m_secondColor[i]);
|
||||
p.drawRect(5, y + 5, m_height - 11, m_height - 11);
|
||||
}
|
||||
p.end();
|
||||
}
|
||||
|
||||
void keyReleaseEvent(QKeyEvent *event) {
|
||||
if (event->key() == Qt::Key_Down) {
|
||||
m_offset += 20;
|
||||
event->accept();
|
||||
update();
|
||||
return;
|
||||
}
|
||||
if (event->key() == Qt::Key_Up) {
|
||||
m_offset -= 20;
|
||||
event->accept();
|
||||
update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) {
|
||||
Flickable::handleMousePress(event);
|
||||
if (event->isAccepted())
|
||||
return;
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
int y = event->position().toPoint().y() + m_offset;
|
||||
int i = y / m_height;
|
||||
if (i != m_highlight) {
|
||||
m_highlight = i;
|
||||
m_selected = -1;
|
||||
update();
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event) {
|
||||
Flickable::handleMouseMove(event);
|
||||
}
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent *event) {
|
||||
Flickable::handleMouseRelease(event);
|
||||
if (event->isAccepted())
|
||||
return;
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
m_selected = m_highlight;
|
||||
event->accept();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int m_offset;
|
||||
int m_height;
|
||||
int m_highlight;
|
||||
int m_selected;
|
||||
QStringList m_colorNames;
|
||||
QList<QColor> m_firstColor;
|
||||
QList<QColor> m_secondColor;
|
||||
};
|
||||
|
||||
#include "main.moc"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
ColorList list;
|
||||
list.setWindowTitle("Kinetic Scrolling");
|
||||
list.resize(320, 320);
|
||||
list.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
Reference in New Issue
Block a user