Remove undocumented embedded examples
Task-number: QTBUG-119117 Change-Id: I7fd104742771e2ce6d4ad7afd66e2beca3b4f672 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
4bb230f65e
commit
4c36bb854c
@ -6,7 +6,6 @@ qt_examples_build_begin(EXTERNAL_BUILD)
|
|||||||
add_compile_definitions(QT_NO_CONTEXTLESS_CONNECT)
|
add_compile_definitions(QT_NO_CONTEXTLESS_CONNECT)
|
||||||
|
|
||||||
add_subdirectory(corelib)
|
add_subdirectory(corelib)
|
||||||
add_subdirectory(embedded)
|
|
||||||
if(TARGET Qt6::DBus)
|
if(TARGET Qt6::DBus)
|
||||||
add_subdirectory(dbus)
|
add_subdirectory(dbus)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
if(NOT TARGET Qt6::Gui OR (NOT embedded AND NOT x11))
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
qt_internal_add_example(styleexample)
|
|
||||||
qt_internal_add_example(raycasting)
|
|
||||||
qt_internal_add_example(flickable)
|
|
||||||
qt_internal_add_example(digiflip)
|
|
||||||
qt_internal_add_example(lightmaps)
|
|
||||||
qt_internal_add_example(flightinfo)
|
|
@ -1,36 +0,0 @@
|
|||||||
# Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(digiflip LANGUAGES CXX)
|
|
||||||
|
|
||||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
|
||||||
set(INSTALL_EXAMPLESDIR "examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/digiflip")
|
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
|
||||||
|
|
||||||
qt_standard_project_setup()
|
|
||||||
|
|
||||||
qt_add_executable(digiflip
|
|
||||||
digiflip.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(digiflip PROPERTIES
|
|
||||||
WIN32_EXECUTABLE TRUE
|
|
||||||
MACOSX_BUNDLE TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(digiflip PRIVATE
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Gui
|
|
||||||
Qt6::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS digiflip
|
|
||||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
)
|
|
@ -1,372 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
#include <QtWidgets>
|
|
||||||
|
|
||||||
class Digits: public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum {
|
|
||||||
Slide,
|
|
||||||
Flip,
|
|
||||||
Rotate
|
|
||||||
};
|
|
||||||
|
|
||||||
Digits(QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, m_number(0)
|
|
||||||
, m_transition(Slide)
|
|
||||||
{
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
|
||||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
|
||||||
connect(&m_animator, &QTimeLine::frameChanged,
|
|
||||||
this, qOverload<>(&Digits::update));
|
|
||||||
m_animator.setFrameRange(0, 100);
|
|
||||||
m_animator.setDuration(600);
|
|
||||||
m_animator.setEasingCurve(QEasingCurve::InOutSine);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTransition(int tr) {
|
|
||||||
m_transition = tr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int transition() const {
|
|
||||||
return m_transition;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setNumber(int n) {
|
|
||||||
if (m_number != n) {
|
|
||||||
m_number = qBound(0, n, 99);
|
|
||||||
preparePixmap();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void flipTo(int n) {
|
|
||||||
if (m_number != n) {
|
|
||||||
m_number = qBound(0, n, 99);
|
|
||||||
m_lastPixmap = m_pixmap;
|
|
||||||
preparePixmap();
|
|
||||||
m_animator.stop();
|
|
||||||
m_animator.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void drawFrame(QPainter *p, const QRect &rect) {
|
|
||||||
p->setPen(Qt::NoPen);
|
|
||||||
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
|
|
||||||
gradient.setColorAt(0.00, QColor(245, 245, 245));
|
|
||||||
gradient.setColorAt(0.49, QColor(192, 192, 192));
|
|
||||||
gradient.setColorAt(0.51, QColor(245, 245, 245));
|
|
||||||
gradient.setColorAt(1.00, QColor(192, 192, 192));
|
|
||||||
p->setBrush(gradient);
|
|
||||||
QRect r = rect;
|
|
||||||
p->drawRoundedRect(r, 15, 15, Qt::RelativeSize);
|
|
||||||
r.adjust(1, 4, -1, -4);
|
|
||||||
p->setPen(QColor(181, 181, 181));
|
|
||||||
p->setBrush(Qt::NoBrush);
|
|
||||||
p->drawRoundedRect(r, 15, 15, Qt::RelativeSize);
|
|
||||||
p->setPen(QColor(159, 159, 159));
|
|
||||||
int y = rect.top() + rect.height() / 2 - 1;
|
|
||||||
p->drawLine(rect.left(), y, rect.right(), y);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap drawDigits(int n, const QRect &rect) {
|
|
||||||
|
|
||||||
int scaleFactor = 2;
|
|
||||||
|
|
||||||
QString str = QString::number(n);
|
|
||||||
if (str.length() == 1)
|
|
||||||
str.prepend('0');
|
|
||||||
|
|
||||||
QFont font;
|
|
||||||
font.setFamily("Helvetica");
|
|
||||||
int fontHeight = scaleFactor * 0.55 * rect.height();
|
|
||||||
font.setPixelSize(fontHeight);
|
|
||||||
font.setBold(true);
|
|
||||||
|
|
||||||
QPixmap pixmap(rect.size() * scaleFactor);
|
|
||||||
pixmap.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QLinearGradient gradient(QPoint(0, 0), QPoint(0, pixmap.height()));
|
|
||||||
gradient.setColorAt(0.00, QColor(128, 128, 128));
|
|
||||||
gradient.setColorAt(0.49, QColor(64, 64, 64));
|
|
||||||
gradient.setColorAt(0.51, QColor(128, 128, 128));
|
|
||||||
gradient.setColorAt(1.00, QColor(16, 16, 16));
|
|
||||||
|
|
||||||
QPainter p;
|
|
||||||
p.begin(&pixmap);
|
|
||||||
p.setFont(font);
|
|
||||||
QPen pen;
|
|
||||||
pen.setBrush(QBrush(gradient));
|
|
||||||
p.setPen(pen);
|
|
||||||
p.drawText(pixmap.rect(), Qt::AlignCenter, str);
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
return pixmap.scaledToWidth(width(), Qt::SmoothTransformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void preparePixmap() {
|
|
||||||
m_pixmap = QPixmap(size());
|
|
||||||
m_pixmap.fill(Qt::transparent);
|
|
||||||
QPainter p;
|
|
||||||
p.begin(&m_pixmap);
|
|
||||||
p.drawPixmap(0, 0, drawDigits(m_number, rect()));
|
|
||||||
p.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent*) {
|
|
||||||
preparePixmap();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintStatic() {
|
|
||||||
QPainter p(this);
|
|
||||||
p.fillRect(rect(), Qt::black);
|
|
||||||
|
|
||||||
int pad = width() / 10;
|
|
||||||
drawFrame(&p, rect().adjusted(pad, pad, -pad, -pad));
|
|
||||||
p.drawPixmap(0, 0, m_pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintSlide() {
|
|
||||||
QPainter p(this);
|
|
||||||
p.fillRect(rect(), Qt::black);
|
|
||||||
|
|
||||||
int pad = width() / 10;
|
|
||||||
QRect fr = rect().adjusted(pad, pad, -pad, -pad);
|
|
||||||
drawFrame(&p, fr);
|
|
||||||
p.setClipRect(fr);
|
|
||||||
|
|
||||||
int y = height() * m_animator.currentFrame() / 100;
|
|
||||||
p.drawPixmap(0, y, m_lastPixmap);
|
|
||||||
p.drawPixmap(0, y - height(), m_pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintFlip() {
|
|
||||||
QPainter p(this);
|
|
||||||
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
||||||
p.setRenderHint(QPainter::Antialiasing, true);
|
|
||||||
p.fillRect(rect(), Qt::black);
|
|
||||||
|
|
||||||
int hw = width() / 2;
|
|
||||||
int hh = height() / 2;
|
|
||||||
|
|
||||||
// behind is the new pixmap
|
|
||||||
int pad = width() / 10;
|
|
||||||
QRect fr = rect().adjusted(pad, pad, -pad, -pad);
|
|
||||||
drawFrame(&p, fr);
|
|
||||||
p.drawPixmap(0, 0, m_pixmap);
|
|
||||||
|
|
||||||
int index = m_animator.currentFrame();
|
|
||||||
|
|
||||||
if (index <= 50) {
|
|
||||||
|
|
||||||
// the top part of the old pixmap is flipping
|
|
||||||
int angle = -180 * index / 100;
|
|
||||||
QTransform transform;
|
|
||||||
transform.translate(hw, hh);
|
|
||||||
transform.rotate(angle, Qt::XAxis);
|
|
||||||
p.setTransform(transform);
|
|
||||||
drawFrame(&p, fr.adjusted(-hw, -hh, -hw, -hh));
|
|
||||||
p.drawPixmap(-hw, -hh, m_lastPixmap);
|
|
||||||
|
|
||||||
// the bottom part is still the old pixmap
|
|
||||||
p.resetTransform();
|
|
||||||
p.setClipRect(0, hh, width(), hh);
|
|
||||||
drawFrame(&p, fr);
|
|
||||||
p.drawPixmap(0, 0, m_lastPixmap);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
p.setClipRect(0, hh, width(), hh);
|
|
||||||
|
|
||||||
// the bottom part is still the old pixmap
|
|
||||||
drawFrame(&p, fr);
|
|
||||||
p.drawPixmap(0, 0, m_lastPixmap);
|
|
||||||
|
|
||||||
// the bottom part of the new pixmap is flipping
|
|
||||||
int angle = 180 - 180 * m_animator.currentFrame() / 100;
|
|
||||||
QTransform transform;
|
|
||||||
transform.translate(hw, hh);
|
|
||||||
transform.rotate(angle, Qt::XAxis);
|
|
||||||
p.setTransform(transform);
|
|
||||||
drawFrame(&p, fr.adjusted(-hw, -hh, -hw, -hh));
|
|
||||||
p.drawPixmap(-hw, -hh, m_pixmap);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintRotate() {
|
|
||||||
QPainter p(this);
|
|
||||||
|
|
||||||
int pad = width() / 10;
|
|
||||||
QRect fr = rect().adjusted(pad, pad, -pad, -pad);
|
|
||||||
drawFrame(&p, fr);
|
|
||||||
p.setClipRect(fr);
|
|
||||||
|
|
||||||
int angle1 = -180 * m_animator.currentFrame() / 100;
|
|
||||||
int angle2 = 180 - 180 * m_animator.currentFrame() / 100;
|
|
||||||
int angle = (m_animator.currentFrame() <= 50) ? angle1 : angle2;
|
|
||||||
QPixmap pix = (m_animator.currentFrame() <= 50) ? m_lastPixmap : m_pixmap;
|
|
||||||
|
|
||||||
QTransform transform;
|
|
||||||
transform.translate(width() / 2, height() / 2);
|
|
||||||
transform.rotate(angle, Qt::XAxis);
|
|
||||||
|
|
||||||
p.setTransform(transform);
|
|
||||||
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
||||||
p.drawPixmap(-width() / 2, -height() / 2, pix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *event) {
|
|
||||||
Q_UNUSED(event);
|
|
||||||
if (m_animator.state() == QTimeLine::Running) {
|
|
||||||
if (m_transition == Slide)
|
|
||||||
paintSlide();
|
|
||||||
if (m_transition == Flip)
|
|
||||||
paintFlip();
|
|
||||||
if (m_transition == Rotate)
|
|
||||||
paintRotate();
|
|
||||||
} else {
|
|
||||||
paintStatic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_number;
|
|
||||||
int m_transition;
|
|
||||||
QPixmap m_pixmap;
|
|
||||||
QPixmap m_lastPixmap;
|
|
||||||
QTimeLine m_animator;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DigiFlip : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
DigiFlip(QWidget *parent = nullptr)
|
|
||||||
: QMainWindow(parent)
|
|
||||||
{
|
|
||||||
m_hour = new Digits(this);
|
|
||||||
m_hour->show();
|
|
||||||
m_minute = new Digits(this);
|
|
||||||
m_minute->show();
|
|
||||||
|
|
||||||
QPalette pal = palette();
|
|
||||||
pal.setColor(QPalette::Window, Qt::black);
|
|
||||||
setPalette(pal);
|
|
||||||
|
|
||||||
m_ticker.start(1000, this);
|
|
||||||
QTime t = QTime::currentTime();
|
|
||||||
m_hour->setNumber(t.hour());
|
|
||||||
m_minute->setNumber(t.minute());
|
|
||||||
updateTime();
|
|
||||||
|
|
||||||
QAction *slideAction = new QAction("&Slide", this);
|
|
||||||
QAction *flipAction = new QAction("&Flip", this);
|
|
||||||
QAction *rotateAction = new QAction("&Rotate", this);
|
|
||||||
connect(slideAction, &QAction::triggered, this, &DigiFlip::chooseSlide);
|
|
||||||
connect(flipAction, &QAction::triggered, this, &DigiFlip::chooseFlip);
|
|
||||||
connect(rotateAction, &QAction::triggered, this, &DigiFlip::chooseRotate);
|
|
||||||
addAction(slideAction);
|
|
||||||
addAction(flipAction);
|
|
||||||
addAction(rotateAction);
|
|
||||||
setContextMenuPolicy(Qt::ActionsContextMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateTime() {
|
|
||||||
QTime t = QTime::currentTime();
|
|
||||||
m_hour->flipTo(t.hour());
|
|
||||||
m_minute->flipTo(t.minute());
|
|
||||||
QString str = t.toString("hh:mm:ss");
|
|
||||||
str.prepend(": ");
|
|
||||||
if (m_hour->transition() == Digits::Slide)
|
|
||||||
str.prepend("Slide");
|
|
||||||
if (m_hour->transition() == Digits::Flip)
|
|
||||||
str.prepend("Flip");
|
|
||||||
if (m_hour->transition() == Digits::Rotate)
|
|
||||||
str.prepend("Rotate");
|
|
||||||
setWindowTitle(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void switchTransition(int delta) {
|
|
||||||
int i = (m_hour->transition() + delta + 3) % 3;
|
|
||||||
m_hour->setTransition(i);
|
|
||||||
m_minute->setTransition(i);
|
|
||||||
updateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void resizeEvent(QResizeEvent*) {
|
|
||||||
int digitsWidth = width() / 2;
|
|
||||||
int digitsHeight = digitsWidth * 1.2;
|
|
||||||
|
|
||||||
int y = (height() - digitsHeight) / 3;
|
|
||||||
|
|
||||||
m_hour->resize(digitsWidth, digitsHeight);
|
|
||||||
m_hour->move(0, y);
|
|
||||||
|
|
||||||
m_minute->resize(digitsWidth, digitsHeight);
|
|
||||||
m_minute->move(width() / 2, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void timerEvent(QTimerEvent*) {
|
|
||||||
updateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent *event) {
|
|
||||||
if (event->key() == Qt::Key_Right) {
|
|
||||||
switchTransition(1);
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
if (event->key() == Qt::Key_Left) {
|
|
||||||
switchTransition(-1);
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void chooseSlide() {
|
|
||||||
m_hour->setTransition(0);
|
|
||||||
m_minute->setTransition(0);
|
|
||||||
updateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
void chooseFlip() {
|
|
||||||
m_hour->setTransition(1);
|
|
||||||
m_minute->setTransition(1);
|
|
||||||
updateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
void chooseRotate() {
|
|
||||||
m_hour->setTransition(2);
|
|
||||||
m_minute->setTransition(2);
|
|
||||||
updateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QBasicTimer m_ticker;
|
|
||||||
Digits *m_hour;
|
|
||||||
Digits *m_minute;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "digiflip.moc"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
DigiFlip time;
|
|
||||||
time.resize(320, 240);
|
|
||||||
time.show();
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
QT += widgets
|
|
||||||
|
|
||||||
SOURCES = digiflip.cpp
|
|
||||||
|
|
||||||
target.path = $$[QT_INSTALL_EXAMPLES]/embedded/digiflip
|
|
||||||
INSTALLS += target
|
|
@ -1,7 +0,0 @@
|
|||||||
requires(if(embedded|x11):qtHaveModule(gui))
|
|
||||||
|
|
||||||
TEMPLATE = subdirs
|
|
||||||
SUBDIRS = styleexample raycasting flickable digiflip
|
|
||||||
|
|
||||||
SUBDIRS += lightmaps
|
|
||||||
SUBDIRS += flightinfo
|
|
@ -1,37 +0,0 @@
|
|||||||
# 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}"
|
|
||||||
)
|
|
@ -1,246 +0,0 @@
|
|||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
// 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
|
|
@ -1,7 +0,0 @@
|
|||||||
QT += widgets
|
|
||||||
|
|
||||||
SOURCES = flickable.cpp main.cpp
|
|
||||||
HEADERS = flickable.h
|
|
||||||
|
|
||||||
target.path = $$[QT_INSTALL_EXAMPLES]/embedded/flickable
|
|
||||||
INSTALLS += target
|
|
@ -1,190 +0,0 @@
|
|||||||
// 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();
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
# Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(flightinfo LANGUAGES CXX)
|
|
||||||
|
|
||||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
|
||||||
set(INSTALL_EXAMPLESDIR "examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/flightinfo")
|
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
|
|
||||||
|
|
||||||
qt_standard_project_setup()
|
|
||||||
|
|
||||||
qt_add_executable(flightinfo
|
|
||||||
flightinfo.cpp
|
|
||||||
form.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(flightinfo PROPERTIES
|
|
||||||
WIN32_EXECUTABLE TRUE
|
|
||||||
MACOSX_BUNDLE TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(flightinfo PRIVATE
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Gui
|
|
||||||
Qt6::Network
|
|
||||||
Qt6::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
# Resources:
|
|
||||||
set(flightinfo_resource_files
|
|
||||||
"aircraft.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_add_resources(flightinfo "flightinfo"
|
|
||||||
PREFIX
|
|
||||||
"/"
|
|
||||||
FILES
|
|
||||||
${flightinfo_resource_files}
|
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS flightinfo
|
|
||||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
)
|
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
@ -1,352 +0,0 @@
|
|||||||
// Copyright (C) 2020 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include <QtNetwork>
|
|
||||||
|
|
||||||
#include "ui_form.h"
|
|
||||||
|
|
||||||
#define FLIGHTVIEW_URL "http://mobile.flightview.com/TrackByFlight.aspx"
|
|
||||||
#define FLIGHTVIEW_RANDOM "http://mobile.flightview.com/TrackSampleFlight.aspx"
|
|
||||||
|
|
||||||
// strips all invalid constructs that might trip QXmlStreamReader
|
|
||||||
static QString sanitized(const QString &xml)
|
|
||||||
{
|
|
||||||
QString data = xml;
|
|
||||||
|
|
||||||
// anything up to the html tag
|
|
||||||
int i = data.indexOf("<html");
|
|
||||||
if (i > 0)
|
|
||||||
data.remove(0, i - 1);
|
|
||||||
|
|
||||||
// everything inside the head tag
|
|
||||||
i = data.indexOf("<head");
|
|
||||||
if (i > 0)
|
|
||||||
data.remove(i, data.indexOf("</head>") - i + 7);
|
|
||||||
|
|
||||||
// invalid link for JavaScript code
|
|
||||||
while (true) {
|
|
||||||
i = data.indexOf("onclick=\"gotoUrl(");
|
|
||||||
if (i < 0)
|
|
||||||
break;
|
|
||||||
data.remove(i, data.indexOf('\"', i + 9) - i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// all inline frames
|
|
||||||
while (true) {
|
|
||||||
i = data.indexOf("<iframe");
|
|
||||||
if (i < 0)
|
|
||||||
break;
|
|
||||||
data.remove(i, data.indexOf("</iframe>") - i + 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// entities
|
|
||||||
data.remove(" ");
|
|
||||||
data.remove("©");
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FlightInfo : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Ui_Form ui;
|
|
||||||
QUrl m_url;
|
|
||||||
QDate m_searchDate;
|
|
||||||
QPixmap m_map;
|
|
||||||
QNetworkAccessManager m_manager;
|
|
||||||
QList<QNetworkReply *> mapReplies;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
FlightInfo(QMainWindow *parent = nullptr): QMainWindow(parent) {
|
|
||||||
|
|
||||||
QWidget *w = new QWidget(this);
|
|
||||||
ui.setupUi(w);
|
|
||||||
setCentralWidget(w);
|
|
||||||
|
|
||||||
ui.searchBar->hide();
|
|
||||||
ui.infoBox->hide();
|
|
||||||
connect(ui.searchButton, &QPushButton::clicked, this, &FlightInfo::startSearch);
|
|
||||||
connect(ui.flightEdit, &QLineEdit::returnPressed, this, &FlightInfo::startSearch);
|
|
||||||
|
|
||||||
setWindowTitle("Flight Info");
|
|
||||||
|
|
||||||
// Rendered from the public-domain vectorized aircraft
|
|
||||||
// http://openclipart.org/media/people/Jarno
|
|
||||||
m_map = QPixmap(":/aircraft.png");
|
|
||||||
|
|
||||||
QAction *searchTodayAction = new QAction("Today's Flight", this);
|
|
||||||
QAction *searchYesterdayAction = new QAction("Yesterday's Flight", this);
|
|
||||||
QAction *randomAction = new QAction("Random Flight", this);
|
|
||||||
connect(searchTodayAction, &QAction::triggered, this, &FlightInfo::today);
|
|
||||||
connect(searchYesterdayAction, &QAction::triggered, this, &FlightInfo::yesterday);
|
|
||||||
connect(randomAction, &QAction::triggered, this, &FlightInfo::randomFlight);
|
|
||||||
connect(&m_manager, &QNetworkAccessManager::finished,
|
|
||||||
this, &FlightInfo::handleNetworkData);
|
|
||||||
addAction(searchTodayAction);
|
|
||||||
addAction(searchYesterdayAction);
|
|
||||||
addAction(randomAction);
|
|
||||||
setContextMenuPolicy(Qt::ActionsContextMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
|
|
||||||
void handleNetworkData(QNetworkReply *networkReply) {
|
|
||||||
if (!networkReply->error()) {
|
|
||||||
if (!mapReplies.contains(networkReply)) {
|
|
||||||
// Assume UTF-8 encoded
|
|
||||||
QByteArray data = networkReply->readAll();
|
|
||||||
QString xml = QString::fromUtf8(data);
|
|
||||||
digest(xml);
|
|
||||||
} else {
|
|
||||||
mapReplies.removeOne(networkReply);
|
|
||||||
m_map.loadFromData(networkReply->readAll());
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
networkReply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
void today() {
|
|
||||||
QDateTime timestamp = QDateTime::currentDateTime();
|
|
||||||
m_searchDate = timestamp.date();
|
|
||||||
searchFlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
void yesterday() {
|
|
||||||
QDateTime timestamp = QDateTime::currentDateTime();
|
|
||||||
timestamp = timestamp.addDays(-1);
|
|
||||||
m_searchDate = timestamp.date();
|
|
||||||
searchFlight();
|
|
||||||
}
|
|
||||||
|
|
||||||
void searchFlight() {
|
|
||||||
ui.searchBar->show();
|
|
||||||
ui.infoBox->hide();
|
|
||||||
ui.flightStatus->hide();
|
|
||||||
ui.flightName->setText("Enter flight number");
|
|
||||||
ui.flightEdit->setFocus();
|
|
||||||
#ifdef QT_KEYPAD_NAVIGATION
|
|
||||||
ui.flightEdit->setEditFocus(true);
|
|
||||||
#endif
|
|
||||||
m_map = QPixmap();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void startSearch() {
|
|
||||||
ui.searchBar->hide();
|
|
||||||
QString flight = ui.flightEdit->text().simplified();
|
|
||||||
if (!flight.isEmpty())
|
|
||||||
request(flight, m_searchDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void randomFlight() {
|
|
||||||
request(QString(), QDate::currentDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
void request(const QString &flightCode, QDate date) {
|
|
||||||
|
|
||||||
setWindowTitle("Loading...");
|
|
||||||
|
|
||||||
QString code = flightCode.simplified();
|
|
||||||
QString airlineCode = code.left(2).toUpper();
|
|
||||||
QString flightNumber = code.mid(2, code.length());
|
|
||||||
|
|
||||||
ui.flightName->setText("Searching for " + code);
|
|
||||||
|
|
||||||
QUrlQuery query;
|
|
||||||
query.addQueryItem("view", "detail");
|
|
||||||
query.addQueryItem("al", airlineCode);
|
|
||||||
query.addQueryItem("fn", flightNumber);
|
|
||||||
query.addQueryItem("dpdat", date.toString("yyyyMMdd"));
|
|
||||||
m_url = QUrl(FLIGHTVIEW_URL);
|
|
||||||
m_url.setQuery(query);
|
|
||||||
|
|
||||||
if (code.isEmpty()) {
|
|
||||||
// random flight as sample
|
|
||||||
m_url = QUrl(FLIGHTVIEW_RANDOM);
|
|
||||||
ui.flightName->setText("Getting a random flight...");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_manager.get(QNetworkRequest(m_url));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void digest(const QString &content) {
|
|
||||||
|
|
||||||
setWindowTitle("Flight Info");
|
|
||||||
QString data = sanitized(content);
|
|
||||||
|
|
||||||
// do we only get the flight list?
|
|
||||||
// we grab the first leg in the flight list
|
|
||||||
// then fetch another URL for the real flight info
|
|
||||||
int i = data.indexOf("a href=\"?view=detail");
|
|
||||||
if (i > 0) {
|
|
||||||
QString href = data.mid(i, data.indexOf('\"', i + 8) - i + 1);
|
|
||||||
QRegularExpression regex("dpap=([A-Za-z0-9]+)");
|
|
||||||
QRegularExpressionMatch match = regex.match(href);
|
|
||||||
QString airport = match.captured(1);
|
|
||||||
QUrlQuery query(m_url);
|
|
||||||
query.addQueryItem("dpap", airport);
|
|
||||||
m_url.setQuery(query);
|
|
||||||
m_manager.get(QNetworkRequest(m_url));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmlStreamReader xml(data);
|
|
||||||
bool inFlightName = false;
|
|
||||||
bool inFlightStatus = false;
|
|
||||||
bool inFlightMap = false;
|
|
||||||
bool inFieldName = false;
|
|
||||||
bool inFieldValue = false;
|
|
||||||
|
|
||||||
QString flightName;
|
|
||||||
QString flightStatus;
|
|
||||||
QStringList fieldNames;
|
|
||||||
QStringList fieldValues;
|
|
||||||
|
|
||||||
while (!xml.atEnd()) {
|
|
||||||
xml.readNext();
|
|
||||||
|
|
||||||
if (xml.tokenType() == QXmlStreamReader::StartElement) {
|
|
||||||
auto className = xml.attributes().value("class");
|
|
||||||
inFlightName |= xml.name() == u"h1";
|
|
||||||
inFlightStatus |= className == u"FlightDetailHeaderStatus";
|
|
||||||
inFlightMap |= className == u"flightMap";
|
|
||||||
if (xml.name() == u"td" && !className.isEmpty()) {
|
|
||||||
if (className.contains(u"fieldTitle")) {
|
|
||||||
inFieldName = true;
|
|
||||||
fieldNames += QString();
|
|
||||||
fieldValues += QString();
|
|
||||||
}
|
|
||||||
if (className.contains(u"fieldValue"))
|
|
||||||
inFieldValue = true;
|
|
||||||
}
|
|
||||||
if (xml.name() == u"img" && inFlightMap) {
|
|
||||||
const QByteArray encoded
|
|
||||||
= ("http://mobile.flightview.com/" % xml.attributes().value("src")).toLatin1();
|
|
||||||
QUrl url = QUrl::fromPercentEncoding(encoded);
|
|
||||||
mapReplies.append(m_manager.get(QNetworkRequest(url)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml.tokenType() == QXmlStreamReader::EndElement) {
|
|
||||||
inFlightName &= xml.name() != u"h1";
|
|
||||||
inFlightStatus &= xml.name() != u"div";
|
|
||||||
inFlightMap &= xml.name() != u"div";
|
|
||||||
inFieldName &= xml.name() != u"td";
|
|
||||||
inFieldValue &= xml.name() != u"td";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xml.tokenType() == QXmlStreamReader::Characters) {
|
|
||||||
if (inFlightName)
|
|
||||||
flightName += xml.text();
|
|
||||||
if (inFlightStatus)
|
|
||||||
flightStatus += xml.text();
|
|
||||||
if (inFieldName)
|
|
||||||
fieldNames.last() += xml.text();
|
|
||||||
if (inFieldValue)
|
|
||||||
fieldValues.last() += xml.text();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldNames.isEmpty()) {
|
|
||||||
QString code = ui.flightEdit->text().simplified().left(10);
|
|
||||||
QString msg = QString("Flight %1 is not found").arg(code);
|
|
||||||
ui.flightName->setText(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.flightName->setText(flightName);
|
|
||||||
flightStatus.remove("Status: ");
|
|
||||||
ui.flightStatus->setText(flightStatus);
|
|
||||||
ui.flightStatus->show();
|
|
||||||
|
|
||||||
QStringList whiteList;
|
|
||||||
whiteList << "Departure";
|
|
||||||
whiteList << "Arrival";
|
|
||||||
whiteList << "Scheduled";
|
|
||||||
whiteList << "Takeoff";
|
|
||||||
whiteList << "Estimated";
|
|
||||||
whiteList << "Term-Gate";
|
|
||||||
|
|
||||||
QString text;
|
|
||||||
text = QString("<table width=%1>").arg(width() - 25);
|
|
||||||
for (int i = 0; i < fieldNames.count(); i++) {
|
|
||||||
QString fn = fieldNames[i].simplified();
|
|
||||||
if (fn.endsWith(':'))
|
|
||||||
fn = fn.left(fn.length() - 1);
|
|
||||||
if (!whiteList.contains(fn))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
QString fv = fieldValues[i].simplified();
|
|
||||||
bool special = false;
|
|
||||||
special |= fn.startsWith("Departure");
|
|
||||||
special |= fn.startsWith("Arrival");
|
|
||||||
text += "<tr>";
|
|
||||||
if (special) {
|
|
||||||
text += "<td align=center colspan=2>";
|
|
||||||
text += "<b><font size=+1>" + fv + "</font></b>";
|
|
||||||
text += "</td>";
|
|
||||||
} else {
|
|
||||||
text += "<td align=right>";
|
|
||||||
text += fn;
|
|
||||||
text += " : ";
|
|
||||||
text += " ";
|
|
||||||
text += "</td>";
|
|
||||||
text += "<td>";
|
|
||||||
text += fv;
|
|
||||||
text += "</td>";
|
|
||||||
}
|
|
||||||
text += "</tr>";
|
|
||||||
}
|
|
||||||
text += "</table>";
|
|
||||||
ui.detailedInfo->setText(text);
|
|
||||||
ui.infoBox->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *event) {
|
|
||||||
Q_UNUSED(event);
|
|
||||||
ui.detailedInfo->setMaximumWidth(width() - 25);
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *event) {
|
|
||||||
QMainWindow::paintEvent(event);
|
|
||||||
QPainter p(this);
|
|
||||||
p.fillRect(rect(), QColor(131, 171, 210));
|
|
||||||
if (!m_map.isNull()) {
|
|
||||||
int x = (width() - m_map.width()) / 2;
|
|
||||||
int space = ui.infoBox->pos().y();
|
|
||||||
if (!ui.infoBox->isVisible())
|
|
||||||
space = height();
|
|
||||||
int top = ui.titleBox->height();
|
|
||||||
int y = qMax(top, (space - m_map.height()) / 2);
|
|
||||||
p.drawPixmap(x, y, m_map);
|
|
||||||
}
|
|
||||||
p.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#include "flightinfo.moc"
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
FlightInfo w;
|
|
||||||
w.resize(360, 504);
|
|
||||||
w.show();
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
TEMPLATE = app
|
|
||||||
TARGET = flightinfo
|
|
||||||
SOURCES = flightinfo.cpp
|
|
||||||
FORMS += form.ui
|
|
||||||
RESOURCES = flightinfo.qrc
|
|
||||||
QT += network widgets
|
|
||||||
|
|
||||||
target.path = $$[QT_INSTALL_EXAMPLES]/embedded/flightinfo
|
|
||||||
INSTALLS += target
|
|
@ -1,5 +0,0 @@
|
|||||||
<RCC>
|
|
||||||
<qresource prefix="/" >
|
|
||||||
<file>aircraft.png</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
@ -1,226 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>Form</class>
|
|
||||||
<widget class="QWidget" name="Form">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>220</width>
|
|
||||||
<height>171</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QFrame" name="titleBox">
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string>QFrame {
|
|
||||||
background-color: #45629a;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel {
|
|
||||||
color: white;
|
|
||||||
}</string>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Raised</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="flightName">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Powered by FlightView</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="flightStatus">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string>background-color: white;
|
|
||||||
color: #45629a;</string>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Ready</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QFrame" name="searchBar">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Raised</enum>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<property name="margin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="flightEdit">
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string>color: black;
|
|
||||||
border: 1px solid black;
|
|
||||||
background: white;
|
|
||||||
selection-background-color: lightgray;</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="searchButton">
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string>color: rgb(255, 255, 255);
|
|
||||||
background-color: rgb(85, 85, 255);
|
|
||||||
padding: 2px;
|
|
||||||
border: 2px solid rgb(0, 0, 127);</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Search</string>
|
|
||||||
</property>
|
|
||||||
<property name="toolButtonStyle">
|
|
||||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>58</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QFrame" name="infoBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string>QFrame { border: 2px solid white;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin: 5px;
|
|
||||||
background-color: rgba(69, 98, 154, 192); }</string>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Raised</enum>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="detailedInfo">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string>color: white;
|
|
||||||
border: none;
|
|
||||||
background-color: none;</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::RichText</enum>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::NoTextInteraction</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
@ -1,40 +0,0 @@
|
|||||||
# Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(lightmaps LANGUAGES CXX)
|
|
||||||
|
|
||||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
|
||||||
set(INSTALL_EXAMPLESDIR "examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/lightmaps")
|
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
|
|
||||||
|
|
||||||
qt_standard_project_setup()
|
|
||||||
|
|
||||||
qt_add_executable(lightmaps
|
|
||||||
lightmaps.cpp lightmaps.h
|
|
||||||
main.cpp
|
|
||||||
mapzoom.cpp mapzoom.h
|
|
||||||
slippymap.cpp slippymap.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(lightmaps PROPERTIES
|
|
||||||
WIN32_EXECUTABLE TRUE
|
|
||||||
MACOSX_BUNDLE TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(lightmaps PRIVATE
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Gui
|
|
||||||
Qt6::Network
|
|
||||||
Qt6::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS lightmaps
|
|
||||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
)
|
|
@ -1,238 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include <QtNetwork>
|
|
||||||
|
|
||||||
#include "lightmaps.h"
|
|
||||||
#include "slippymap.h"
|
|
||||||
|
|
||||||
// how long (milliseconds) the user need to hold (after a tap on the screen)
|
|
||||||
// before triggering the magnifying glass feature
|
|
||||||
// 701, a prime number, is the sum of 229, 233, 239
|
|
||||||
// (all three are also prime numbers, consecutive!)
|
|
||||||
#define HOLD_TIME 701
|
|
||||||
|
|
||||||
// maximum size of the magnifier
|
|
||||||
// Hint: see above to find why I picked this one :)
|
|
||||||
#define MAX_MAGNIFIER 229
|
|
||||||
|
|
||||||
LightMaps::LightMaps(QWidget *parent)
|
|
||||||
: QWidget(parent), pressed(false), snapped(false), zoomed(false),
|
|
||||||
invert(false)
|
|
||||||
{
|
|
||||||
m_normalMap = new SlippyMap(this);
|
|
||||||
m_largeMap = new SlippyMap(this);
|
|
||||||
connect(m_normalMap, &SlippyMap::updated, this, &LightMaps::updateMap);
|
|
||||||
connect(m_largeMap, &SlippyMap::updated, this, &LightMaps::updateMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::setCenter(qreal lat, qreal lng)
|
|
||||||
{
|
|
||||||
m_normalMap->latitude = lat;
|
|
||||||
m_normalMap->longitude = lng;
|
|
||||||
m_normalMap->invalidate();
|
|
||||||
m_largeMap->latitude = lat;
|
|
||||||
m_largeMap->longitude = lng;
|
|
||||||
m_largeMap->invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::toggleNightMode()
|
|
||||||
{
|
|
||||||
invert = !invert;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::updateMap(const QRect &r)
|
|
||||||
{
|
|
||||||
update(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::activateZoom()
|
|
||||||
{
|
|
||||||
zoomed = true;
|
|
||||||
tapTimer.stop();
|
|
||||||
m_largeMap->zoom = m_normalMap->zoom + 1;
|
|
||||||
m_largeMap->width = m_normalMap->width * 2;
|
|
||||||
m_largeMap->height = m_normalMap->height * 2;
|
|
||||||
m_largeMap->latitude = m_normalMap->latitude;
|
|
||||||
m_largeMap->longitude = m_normalMap->longitude;
|
|
||||||
m_largeMap->invalidate();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::resizeEvent(QResizeEvent *)
|
|
||||||
{
|
|
||||||
m_normalMap->width = width();
|
|
||||||
m_normalMap->height = height();
|
|
||||||
m_normalMap->invalidate();
|
|
||||||
m_largeMap->width = m_normalMap->width * 2;
|
|
||||||
m_largeMap->height = m_normalMap->height * 2;
|
|
||||||
m_largeMap->invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::paintEvent(QPaintEvent *event)
|
|
||||||
{
|
|
||||||
QPainter p;
|
|
||||||
p.begin(this);
|
|
||||||
m_normalMap->render(&p, event->rect());
|
|
||||||
p.setPen(Qt::black);
|
|
||||||
p.drawText(rect(), Qt::AlignBottom | Qt::TextWordWrap,
|
|
||||||
"Map data CCBYSA 2009 OpenStreetMap.org contributors");
|
|
||||||
p.end();
|
|
||||||
|
|
||||||
if (zoomed) {
|
|
||||||
int dim = qMin(width(), height());
|
|
||||||
int magnifierSize = qMin(MAX_MAGNIFIER, dim * 2 / 3);
|
|
||||||
int radius = magnifierSize / 2;
|
|
||||||
int ring = radius - 15;
|
|
||||||
QSize box = QSize(magnifierSize, magnifierSize);
|
|
||||||
|
|
||||||
// reupdate our mask
|
|
||||||
if (maskPixmap.size() != box) {
|
|
||||||
maskPixmap = QPixmap(box);
|
|
||||||
maskPixmap.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QRadialGradient g;
|
|
||||||
g.setCenter(radius, radius);
|
|
||||||
g.setFocalPoint(radius, radius);
|
|
||||||
g.setRadius(radius);
|
|
||||||
g.setColorAt(1.0, QColor(255, 255, 255, 0));
|
|
||||||
g.setColorAt(0.5, QColor(128, 128, 128, 255));
|
|
||||||
|
|
||||||
QPainter mask(&maskPixmap);
|
|
||||||
mask.setRenderHint(QPainter::Antialiasing);
|
|
||||||
mask.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
mask.setBrush(g);
|
|
||||||
mask.setPen(Qt::NoPen);
|
|
||||||
mask.drawRect(maskPixmap.rect());
|
|
||||||
mask.setBrush(QColor(Qt::transparent));
|
|
||||||
mask.drawEllipse(g.center(), ring, ring);
|
|
||||||
mask.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint center = dragPos - QPoint(0, radius);
|
|
||||||
center = center + QPoint(0, radius / 2);
|
|
||||||
QPoint corner = center - QPoint(radius, radius);
|
|
||||||
|
|
||||||
QPoint xy = center * 2 - QPoint(radius, radius);
|
|
||||||
|
|
||||||
// only set the dimension to the magnified portion
|
|
||||||
if (zoomPixmap.size() != box) {
|
|
||||||
zoomPixmap = QPixmap(box);
|
|
||||||
zoomPixmap.fill(Qt::lightGray);
|
|
||||||
}
|
|
||||||
if (true) {
|
|
||||||
QPainter p(&zoomPixmap);
|
|
||||||
p.translate(-xy);
|
|
||||||
m_largeMap->render(&p, QRect(xy, box));
|
|
||||||
p.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
QPainterPath clipPath;
|
|
||||||
clipPath.addEllipse(center, ring, ring);
|
|
||||||
|
|
||||||
QPainter p(this);
|
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
|
||||||
p.setClipPath(clipPath);
|
|
||||||
p.drawPixmap(corner, zoomPixmap);
|
|
||||||
p.setClipping(false);
|
|
||||||
p.drawPixmap(corner, maskPixmap);
|
|
||||||
p.setPen(Qt::gray);
|
|
||||||
p.drawPath(clipPath);
|
|
||||||
}
|
|
||||||
if (invert) {
|
|
||||||
QPainter p(this);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Difference);
|
|
||||||
p.fillRect(event->rect(), Qt::white);
|
|
||||||
p.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::timerEvent(QTimerEvent *)
|
|
||||||
{
|
|
||||||
if (!zoomed)
|
|
||||||
activateZoom();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::mousePressEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
if (event->buttons() != Qt::LeftButton)
|
|
||||||
return;
|
|
||||||
pressed = snapped = true;
|
|
||||||
pressPos = dragPos = event->position().toPoint();
|
|
||||||
tapTimer.stop();
|
|
||||||
tapTimer.start(HOLD_TIME, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::mouseMoveEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
if (!event->buttons())
|
|
||||||
return;
|
|
||||||
if (!zoomed) {
|
|
||||||
if (!pressed || !snapped) {
|
|
||||||
QPoint delta = event->position().toPoint() - pressPos;
|
|
||||||
pressPos = event->position().toPoint();
|
|
||||||
m_normalMap->pan(delta);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
const int threshold = 10;
|
|
||||||
QPoint delta = event->position().toPoint() - pressPos;
|
|
||||||
if (snapped) {
|
|
||||||
snapped &= delta.x() < threshold;
|
|
||||||
snapped &= delta.y() < threshold;
|
|
||||||
snapped &= delta.x() > -threshold;
|
|
||||||
snapped &= delta.y() > -threshold;
|
|
||||||
}
|
|
||||||
if (!snapped)
|
|
||||||
tapTimer.stop();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dragPos = event->position().toPoint();
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::mouseReleaseEvent(QMouseEvent *)
|
|
||||||
{
|
|
||||||
zoomed = false;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LightMaps::keyPressEvent(QKeyEvent *event)
|
|
||||||
{
|
|
||||||
if (!zoomed) {
|
|
||||||
if (event->key() == Qt::Key_Left)
|
|
||||||
m_normalMap->pan(QPoint(20, 0));
|
|
||||||
if (event->key() == Qt::Key_Right)
|
|
||||||
m_normalMap->pan(QPoint(-20, 0));
|
|
||||||
if (event->key() == Qt::Key_Up)
|
|
||||||
m_normalMap->pan(QPoint(0, 20));
|
|
||||||
if (event->key() == Qt::Key_Down)
|
|
||||||
m_normalMap->pan(QPoint(0, -20));
|
|
||||||
if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) {
|
|
||||||
dragPos = QPoint(width() / 2, height() / 2);
|
|
||||||
activateZoom();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) {
|
|
||||||
zoomed = false;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
QPoint delta(0, 0);
|
|
||||||
if (event->key() == Qt::Key_Left)
|
|
||||||
delta = QPoint(-15, 0);
|
|
||||||
if (event->key() == Qt::Key_Right)
|
|
||||||
delta = QPoint(15, 0);
|
|
||||||
if (event->key() == Qt::Key_Up)
|
|
||||||
delta = QPoint(0, -15);
|
|
||||||
if (event->key() == Qt::Key_Down)
|
|
||||||
delta = QPoint(0, 15);
|
|
||||||
if (delta != QPoint(0, 0)) {
|
|
||||||
dragPos += delta;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#ifndef LIGHTMAPS_H
|
|
||||||
#define LIGHTMAPS_H
|
|
||||||
|
|
||||||
#include <QBasicTimer>
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
class SlippyMap;
|
|
||||||
|
|
||||||
class LightMaps: public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
LightMaps(QWidget *parent = nullptr);
|
|
||||||
void setCenter(qreal lat, qreal lng);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void toggleNightMode();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void activateZoom();
|
|
||||||
void resizeEvent(QResizeEvent *);
|
|
||||||
void paintEvent(QPaintEvent *event);
|
|
||||||
void timerEvent(QTimerEvent *);
|
|
||||||
void mousePressEvent(QMouseEvent *event);
|
|
||||||
void mouseMoveEvent(QMouseEvent *event);
|
|
||||||
void mouseReleaseEvent(QMouseEvent *);
|
|
||||||
void keyPressEvent(QKeyEvent *event);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateMap(const QRect &r);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SlippyMap *m_normalMap;
|
|
||||||
SlippyMap *m_largeMap;
|
|
||||||
bool pressed;
|
|
||||||
bool snapped;
|
|
||||||
QPoint pressPos;
|
|
||||||
QPoint dragPos;
|
|
||||||
QBasicTimer tapTimer;
|
|
||||||
bool zoomed;
|
|
||||||
QPixmap zoomPixmap;
|
|
||||||
QPixmap maskPixmap;
|
|
||||||
bool invert;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||||||
TEMPLATE = app
|
|
||||||
HEADERS = lightmaps.h \
|
|
||||||
mapzoom.h \
|
|
||||||
slippymap.h
|
|
||||||
SOURCES = lightmaps.cpp \
|
|
||||||
main.cpp \
|
|
||||||
mapzoom.cpp \
|
|
||||||
slippymap.cpp
|
|
||||||
QT += network widgets
|
|
||||||
|
|
||||||
target.path = $$[QT_INSTALL_EXAMPLES]/embedded/lightmaps
|
|
||||||
INSTALLS += target
|
|
@ -1,18 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include "mapzoom.h"
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
app.setApplicationName("LightMaps");
|
|
||||||
|
|
||||||
MapZoom w;
|
|
||||||
w.resize(600, 450);
|
|
||||||
w.show();
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include <QtNetwork>
|
|
||||||
#include "lightmaps.h"
|
|
||||||
#include "mapzoom.h"
|
|
||||||
|
|
||||||
MapZoom::MapZoom()
|
|
||||||
: QMainWindow(0)
|
|
||||||
{
|
|
||||||
map = new LightMaps(this);
|
|
||||||
setCentralWidget(map);
|
|
||||||
map->setFocus();
|
|
||||||
|
|
||||||
QAction *osloAction = new QAction(tr("&Oslo"), this);
|
|
||||||
QAction *berlinAction = new QAction(tr("&Berlin"), this);
|
|
||||||
QAction *jakartaAction = new QAction(tr("&Jakarta"), this);
|
|
||||||
QAction *nightModeAction = new QAction(tr("Night Mode"), this);
|
|
||||||
nightModeAction->setCheckable(true);
|
|
||||||
nightModeAction->setChecked(false);
|
|
||||||
QAction *osmAction = new QAction(tr("About OpenStreetMap"), this);
|
|
||||||
connect(osloAction, SIGNAL(triggered()), SLOT(chooseOslo()));
|
|
||||||
connect(berlinAction, SIGNAL(triggered()), SLOT(chooseBerlin()));
|
|
||||||
connect(jakartaAction, SIGNAL(triggered()), SLOT(chooseJakarta()));
|
|
||||||
connect(nightModeAction, SIGNAL(triggered()), map, SLOT(toggleNightMode()));
|
|
||||||
connect(osmAction, SIGNAL(triggered()), SLOT(aboutOsm()));
|
|
||||||
|
|
||||||
QMenu *menu = menuBar()->addMenu(tr("&Options"));
|
|
||||||
menu->addAction(osloAction);
|
|
||||||
menu->addAction(berlinAction);
|
|
||||||
menu->addAction(jakartaAction);
|
|
||||||
menu->addSeparator();
|
|
||||||
menu->addAction(nightModeAction);
|
|
||||||
menu->addAction(osmAction);
|
|
||||||
|
|
||||||
setWindowTitle(tr("Light Maps"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapZoom::chooseOslo()
|
|
||||||
{
|
|
||||||
map->setCenter(59.9138204, 10.7387413);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapZoom::chooseBerlin()
|
|
||||||
{
|
|
||||||
map->setCenter(52.52958999943302, 13.383053541183472);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapZoom::chooseJakarta()
|
|
||||||
{
|
|
||||||
map->setCenter(-6.211544, 106.845172);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapZoom::aboutOsm()
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl(QUrl("http://www.openstreetmap.org"));
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#ifndef MAPZOOM_H
|
|
||||||
#define MAPZOOM_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
|
|
||||||
class LightMaps;
|
|
||||||
|
|
||||||
class MapZoom : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MapZoom();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void chooseOslo();
|
|
||||||
void chooseBerlin();
|
|
||||||
void chooseJakarta();
|
|
||||||
void aboutOsm();
|
|
||||||
|
|
||||||
private:
|
|
||||||
LightMaps *map;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,164 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include <QtNetwork>
|
|
||||||
#include "slippymap.h"
|
|
||||||
#include "qmath.h"
|
|
||||||
|
|
||||||
// tile size in pixels
|
|
||||||
const int tdim = 256;
|
|
||||||
|
|
||||||
QPointF tileForCoordinate(qreal lat, qreal lng, int zoom)
|
|
||||||
{
|
|
||||||
qreal radianLat = qDegreesToRadians(lat);
|
|
||||||
qreal zn = static_cast<qreal>(1 << zoom);
|
|
||||||
qreal tx = (lng + 180.0) / 360.0;
|
|
||||||
qreal ty = 0.5 - log(tan(radianLat) + 1.0 / cos(radianLat)) / M_PI / 2.0;
|
|
||||||
return QPointF(tx * zn, ty * zn);
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal longitudeFromTile(qreal tx, int zoom)
|
|
||||||
{
|
|
||||||
qreal zn = static_cast<qreal>(1 << zoom);
|
|
||||||
qreal lat = tx / zn * 360.0 - 180.0;
|
|
||||||
return lat;
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal latitudeFromTile(qreal ty, int zoom)
|
|
||||||
{
|
|
||||||
qreal zn = static_cast<qreal>(1 << zoom);
|
|
||||||
qreal n = M_PI - 2 * M_PI * ty / zn;
|
|
||||||
return qRadiansToDegrees(atan(sinh(n)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SlippyMap::SlippyMap(QObject *parent)
|
|
||||||
: QObject(parent), width(400), height(300), zoom(15),
|
|
||||||
latitude(59.9138204), longitude(10.7387413)
|
|
||||||
{
|
|
||||||
m_emptyTile = QPixmap(tdim, tdim);
|
|
||||||
m_emptyTile.fill(Qt::lightGray);
|
|
||||||
|
|
||||||
QNetworkDiskCache *cache = new QNetworkDiskCache;
|
|
||||||
cache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
|
|
||||||
m_manager.setCache(cache);
|
|
||||||
connect(&m_manager, SIGNAL(finished(QNetworkReply*)),
|
|
||||||
this, SLOT(handleNetworkData(QNetworkReply*)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SlippyMap::invalidate()
|
|
||||||
{
|
|
||||||
if (width <= 0 || height <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QPointF ct = tileForCoordinate(latitude, longitude, zoom);
|
|
||||||
qreal tx = ct.x();
|
|
||||||
qreal ty = ct.y();
|
|
||||||
|
|
||||||
// top-left corner of the center tile
|
|
||||||
int xp = width / 2 - (tx - floor(tx)) * tdim;
|
|
||||||
int yp = height / 2 - (ty - floor(ty)) * tdim;
|
|
||||||
|
|
||||||
// first tile vertical and horizontal
|
|
||||||
int xa = (xp + tdim - 1) / tdim;
|
|
||||||
int ya = (yp + tdim - 1) / tdim;
|
|
||||||
int xs = static_cast<int>(tx) - xa;
|
|
||||||
int ys = static_cast<int>(ty) - ya;
|
|
||||||
|
|
||||||
// offset for top-left tile
|
|
||||||
m_offset = QPoint(xp - xa * tdim, yp - ya * tdim);
|
|
||||||
|
|
||||||
// last tile vertical and horizontal
|
|
||||||
int xe = static_cast<int>(tx) + (width - xp - 1) / tdim;
|
|
||||||
int ye = static_cast<int>(ty) + (height - yp - 1) / tdim;
|
|
||||||
|
|
||||||
// build a rect
|
|
||||||
m_tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1);
|
|
||||||
|
|
||||||
if (m_url.isEmpty())
|
|
||||||
download();
|
|
||||||
|
|
||||||
emit updated(QRect(0, 0, width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SlippyMap::render(QPainter *p, const QRect &rect)
|
|
||||||
{
|
|
||||||
for (int x = 0; x <= m_tilesRect.width(); ++x)
|
|
||||||
for (int y = 0; y <= m_tilesRect.height(); ++y) {
|
|
||||||
QPoint tp(x + m_tilesRect.left(), y + m_tilesRect.top());
|
|
||||||
QRect box = tileRect(tp);
|
|
||||||
if (rect.intersects(box)) {
|
|
||||||
if (m_tilePixmaps.contains(tp))
|
|
||||||
p->drawPixmap(box, m_tilePixmaps.value(tp));
|
|
||||||
else
|
|
||||||
p->drawPixmap(box, m_emptyTile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SlippyMap::pan(const QPoint &delta)
|
|
||||||
{
|
|
||||||
QPointF dx = QPointF(delta) / qreal(tdim);
|
|
||||||
QPointF center = tileForCoordinate(latitude, longitude, zoom) - dx;
|
|
||||||
latitude = latitudeFromTile(center.y(), zoom);
|
|
||||||
longitude = longitudeFromTile(center.x(), zoom);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SlippyMap::handleNetworkData(QNetworkReply *reply)
|
|
||||||
{
|
|
||||||
QImage img;
|
|
||||||
QPoint tp = reply->request().attribute(QNetworkRequest::User).toPoint();
|
|
||||||
if (!reply->error())
|
|
||||||
if (!img.load(reply, 0))
|
|
||||||
img = QImage();
|
|
||||||
reply->deleteLater();
|
|
||||||
m_tilePixmaps[tp] = QPixmap::fromImage(img);
|
|
||||||
if (img.isNull())
|
|
||||||
m_tilePixmaps[tp] = m_emptyTile;
|
|
||||||
emit updated(tileRect(tp));
|
|
||||||
|
|
||||||
// purge unused spaces
|
|
||||||
const QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2);
|
|
||||||
for (auto it = m_tilePixmaps.keyBegin(); it != m_tilePixmaps.keyEnd(); ++it) {
|
|
||||||
const QPoint &tp = *it;
|
|
||||||
if (!bound.contains(tp))
|
|
||||||
m_tilePixmaps.remove(tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
download();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SlippyMap::download()
|
|
||||||
{
|
|
||||||
QPoint grab(0, 0);
|
|
||||||
for (int x = 0; x <= m_tilesRect.width(); ++x)
|
|
||||||
for (int y = 0; y <= m_tilesRect.height(); ++y) {
|
|
||||||
QPoint tp = m_tilesRect.topLeft() + QPoint(x, y);
|
|
||||||
if (!m_tilePixmaps.contains(tp)) {
|
|
||||||
grab = tp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (grab == QPoint(0, 0)) {
|
|
||||||
m_url = QUrl();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path = "http://tile.openstreetmap.org/%1/%2/%3.png";
|
|
||||||
m_url = QUrl(path.arg(zoom).arg(grab.x()).arg(grab.y()));
|
|
||||||
QNetworkRequest request;
|
|
||||||
request.setUrl(m_url);
|
|
||||||
request.setRawHeader("User-Agent", "The Qt Company (Qt) Graphics Dojo 1.0");
|
|
||||||
request.setAttribute(QNetworkRequest::User, QVariant(grab));
|
|
||||||
m_manager.get(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect SlippyMap::tileRect(const QPoint &tp)
|
|
||||||
{
|
|
||||||
QPoint t = tp - m_tilesRect.topLeft();
|
|
||||||
int x = t.x() * tdim + m_offset.x();
|
|
||||||
int y = t.y() * tdim + m_offset.y();
|
|
||||||
return QRect(x, y, tdim, tdim);
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#ifndef SLIPPYMAP_H
|
|
||||||
#define SLIPPYMAP_H
|
|
||||||
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QPixmap>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QNetworkReply;
|
|
||||||
class QPainter;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
class SlippyMap: public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
SlippyMap(QObject *parent = nullptr);
|
|
||||||
void invalidate();
|
|
||||||
void render(QPainter *p, const QRect &rect);
|
|
||||||
void pan(const QPoint &delta);
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int zoom;
|
|
||||||
qreal latitude;
|
|
||||||
qreal longitude;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void updated(const QRect &rect);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleNetworkData(QNetworkReply *reply);
|
|
||||||
void download();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QRect tileRect(const QPoint &tp);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QPoint m_offset;
|
|
||||||
QRect m_tilesRect;
|
|
||||||
QPixmap m_emptyTile;
|
|
||||||
QHash<QPoint, QPixmap> m_tilePixmaps;
|
|
||||||
QNetworkAccessManager m_manager;
|
|
||||||
QUrl m_url;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
|||||||
# Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(raycasting LANGUAGES CXX)
|
|
||||||
|
|
||||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
|
||||||
set(INSTALL_EXAMPLESDIR "examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/raycasting")
|
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
|
||||||
|
|
||||||
qt_standard_project_setup()
|
|
||||||
|
|
||||||
qt_add_executable(raycasting
|
|
||||||
raycasting.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(raycasting PROPERTIES
|
|
||||||
WIN32_EXECUTABLE TRUE
|
|
||||||
MACOSX_BUNDLE TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(raycasting PRIVATE
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Gui
|
|
||||||
Qt6::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
# Resources:
|
|
||||||
set(raycasting_resource_files
|
|
||||||
"textures.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_add_resources(raycasting "raycasting"
|
|
||||||
PREFIX
|
|
||||||
"/"
|
|
||||||
FILES
|
|
||||||
${raycasting_resource_files}
|
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS raycasting
|
|
||||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
)
|
|
@ -1,336 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
#include <QtWidgets>
|
|
||||||
#include <qmath.h>
|
|
||||||
|
|
||||||
#define WORLD_SIZE 8
|
|
||||||
int world_map[WORLD_SIZE][WORLD_SIZE] = {
|
|
||||||
{ 1, 1, 1, 1, 6, 1, 1, 1 },
|
|
||||||
{ 1, 0, 0, 1, 0, 0, 0, 7 },
|
|
||||||
{ 1, 1, 0, 1, 0, 1, 1, 1 },
|
|
||||||
{ 6, 0, 0, 0, 0, 0, 0, 3 },
|
|
||||||
{ 1, 8, 8, 0, 8, 0, 8, 1 },
|
|
||||||
{ 2, 2, 0, 0, 8, 8, 7, 1 },
|
|
||||||
{ 3, 0, 0, 0, 0, 0, 0, 5 },
|
|
||||||
{ 2, 2, 2, 2, 7, 4, 4, 4 },
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TEXTURE_SIZE 64
|
|
||||||
#define TEXTURE_BLOCK (TEXTURE_SIZE * TEXTURE_SIZE)
|
|
||||||
|
|
||||||
class Raycasting: public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Raycasting(QWidget *parent = nullptr)
|
|
||||||
: QWidget(parent)
|
|
||||||
, angle(0.5)
|
|
||||||
, playerPos(1.5, 1.5)
|
|
||||||
, angleDelta(0)
|
|
||||||
, moveDelta(0)
|
|
||||||
, touchDevice(false) {
|
|
||||||
|
|
||||||
// http://www.areyep.com/RIPandMCS-TextureLibrary.html
|
|
||||||
textureImg.load(":/textures.png");
|
|
||||||
textureImg = textureImg.convertToFormat(QImage::Format_ARGB32);
|
|
||||||
Q_ASSERT(textureImg.width() == TEXTURE_SIZE * 2);
|
|
||||||
Q_ASSERT(textureImg.bytesPerLine() == 4 * TEXTURE_SIZE * 2);
|
|
||||||
textureCount = textureImg.height() / TEXTURE_SIZE;
|
|
||||||
|
|
||||||
watch.start();
|
|
||||||
ticker.start(25, this);
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
|
||||||
setMouseTracking(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updatePlayer() {
|
|
||||||
int interval = qBound(20ll, watch.elapsed(), 250ll);
|
|
||||||
watch.start();
|
|
||||||
angle += angleDelta * interval / 1000;
|
|
||||||
qreal step = moveDelta * interval / 1000;
|
|
||||||
qreal dx = cos(angle) * step;
|
|
||||||
qreal dy = sin(angle) * step;
|
|
||||||
QPointF pos = playerPos + 3 * QPointF(dx, dy);
|
|
||||||
int xi = static_cast<int>(pos.x());
|
|
||||||
int yi = static_cast<int>(pos.y());
|
|
||||||
if (world_map[yi][xi] == 0)
|
|
||||||
playerPos = playerPos + QPointF(dx, dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void showFps() {
|
|
||||||
static QElapsedTimer frameTick;
|
|
||||||
static int totalFrame = 0;
|
|
||||||
if (!(totalFrame & 31)) {
|
|
||||||
const qint64 elapsed = frameTick.elapsed();
|
|
||||||
frameTick.start();
|
|
||||||
int fps = 32 * 1000 / (1 + elapsed);
|
|
||||||
setWindowTitle(QString("Raycasting (%1 FPS)").arg(fps));
|
|
||||||
}
|
|
||||||
totalFrame++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void render() {
|
|
||||||
|
|
||||||
// setup the screen surface
|
|
||||||
if (buffer.size() != bufferSize)
|
|
||||||
buffer = QImage(bufferSize, QImage::Format_ARGB32);
|
|
||||||
int bufw = buffer.width();
|
|
||||||
int bufh = buffer.height();
|
|
||||||
if (bufw <= 0 || bufh <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// we intentionally cheat here, to avoid detach
|
|
||||||
const uchar *ptr = buffer.bits();
|
|
||||||
QRgb *start = (QRgb*)(ptr);
|
|
||||||
QRgb stride = buffer.bytesPerLine() / 4;
|
|
||||||
QRgb *finish = start + stride * bufh;
|
|
||||||
|
|
||||||
// prepare the texture pointer
|
|
||||||
const uchar *src = textureImg.bits();
|
|
||||||
const QRgb *texsrc = reinterpret_cast<const QRgb*>(src);
|
|
||||||
|
|
||||||
// cast all rays here
|
|
||||||
qreal sina = sin(angle);
|
|
||||||
qreal cosa = cos(angle);
|
|
||||||
qreal u = cosa - sina;
|
|
||||||
qreal v = sina + cosa;
|
|
||||||
qreal du = 2 * sina / bufw;
|
|
||||||
qreal dv = -2 * cosa / bufw;
|
|
||||||
|
|
||||||
for (int ray = 0; ray < bufw; ++ray, u += du, v += dv) {
|
|
||||||
// every time this ray advances 'u' units in x direction,
|
|
||||||
// it also advanced 'v' units in y direction
|
|
||||||
qreal uu = (u < 0) ? -u : u;
|
|
||||||
qreal vv = (v < 0) ? -v : v;
|
|
||||||
qreal duu = 1 / uu;
|
|
||||||
qreal dvv = 1 / vv;
|
|
||||||
int stepx = (u < 0) ? -1 : 1;
|
|
||||||
int stepy = (v < 0) ? -1 : 1;
|
|
||||||
|
|
||||||
// the cell in the map that we need to check
|
|
||||||
qreal px = playerPos.x();
|
|
||||||
qreal py = playerPos.y();
|
|
||||||
int mapx = static_cast<int>(px);
|
|
||||||
int mapy = static_cast<int>(py);
|
|
||||||
|
|
||||||
// the position and texture for the hit
|
|
||||||
int texture = 0;
|
|
||||||
qreal hitdist = 0.1;
|
|
||||||
qreal texofs = 0;
|
|
||||||
bool dark = false;
|
|
||||||
|
|
||||||
// first hit at constant x and constant y lines
|
|
||||||
qreal distx = (u > 0) ? (mapx + 1 - px) * duu : (px - mapx) * duu;
|
|
||||||
qreal disty = (v > 0) ? (mapy + 1 - py) * dvv : (py - mapy) * dvv;
|
|
||||||
|
|
||||||
// loop until we hit something
|
|
||||||
while (texture <= 0) {
|
|
||||||
if (distx > disty) {
|
|
||||||
// shorter distance to a hit in constant y line
|
|
||||||
hitdist = disty;
|
|
||||||
disty += dvv;
|
|
||||||
mapy += stepy;
|
|
||||||
texture = world_map[mapy][mapx];
|
|
||||||
if (texture > 0) {
|
|
||||||
dark = true;
|
|
||||||
if (stepy > 0) {
|
|
||||||
qreal ofs = px + u * (mapy - py) / v;
|
|
||||||
texofs = ofs - floor(ofs);
|
|
||||||
} else {
|
|
||||||
qreal ofs = px + u * (mapy + 1 - py) / v;
|
|
||||||
texofs = ofs - floor(ofs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// shorter distance to a hit in constant x line
|
|
||||||
hitdist = distx;
|
|
||||||
distx += duu;
|
|
||||||
mapx += stepx;
|
|
||||||
texture = world_map[mapy][mapx];
|
|
||||||
if (texture > 0) {
|
|
||||||
if (stepx > 0) {
|
|
||||||
qreal ofs = py + v * (mapx - px) / u;
|
|
||||||
texofs = ofs - floor(ofs);
|
|
||||||
} else {
|
|
||||||
qreal ofs = py + v * (mapx + 1 - px) / u;
|
|
||||||
texofs = ceil(ofs) - ofs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the texture, note that the texture image
|
|
||||||
// has two textures horizontally, "normal" vs "dark"
|
|
||||||
int col = static_cast<int>(texofs * TEXTURE_SIZE);
|
|
||||||
col = qBound(0, col, TEXTURE_SIZE - 1);
|
|
||||||
texture = (texture - 1) % textureCount;
|
|
||||||
const QRgb *tex = texsrc + TEXTURE_BLOCK * texture * 2 +
|
|
||||||
(TEXTURE_SIZE * 2 * col);
|
|
||||||
if (dark)
|
|
||||||
tex += TEXTURE_SIZE;
|
|
||||||
|
|
||||||
// start from the texture center (horizontally)
|
|
||||||
int h = static_cast<int>(bufw / hitdist / 2);
|
|
||||||
int dy = (TEXTURE_SIZE << 12) / h;
|
|
||||||
int p1 = ((TEXTURE_SIZE / 2) << 12) - dy;
|
|
||||||
int p2 = p1 + dy;
|
|
||||||
|
|
||||||
// start from the screen center (vertically)
|
|
||||||
// y1 will go up (decrease), y2 will go down (increase)
|
|
||||||
int y1 = bufh / 2;
|
|
||||||
int y2 = y1 + 1;
|
|
||||||
QRgb *pixel1 = start + y1 * stride + ray;
|
|
||||||
QRgb *pixel2 = pixel1 + stride;
|
|
||||||
|
|
||||||
// map the texture to the sliver
|
|
||||||
while (y1 >= 0 && y2 < bufh && p1 >= 0) {
|
|
||||||
*pixel1 = tex[p1 >> 12];
|
|
||||||
*pixel2 = tex[p2 >> 12];
|
|
||||||
p1 -= dy;
|
|
||||||
p2 += dy;
|
|
||||||
--y1;
|
|
||||||
++y2;
|
|
||||||
pixel1 -= stride;
|
|
||||||
pixel2 += stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ceiling and floor
|
|
||||||
for (; pixel1 > start; pixel1 -= stride)
|
|
||||||
*pixel1 = qRgb(0, 0, 0);
|
|
||||||
for (; pixel2 < finish; pixel2 += stride)
|
|
||||||
*pixel2 = qRgb(96, 96, 96);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(QRect(QPoint(0, 0), bufferSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent*) {
|
|
||||||
touchDevice = false;
|
|
||||||
if (touchDevice) {
|
|
||||||
if (width() < height()) {
|
|
||||||
trackPad = QRect(0, height() / 2, width(), height() / 2);
|
|
||||||
centerPad = QPoint(width() / 2, height() * 3 / 4);
|
|
||||||
bufferSize = QSize(width(), height() / 2);
|
|
||||||
} else {
|
|
||||||
trackPad = QRect(width() / 2, 0, width() / 2, height());
|
|
||||||
centerPad = QPoint(width() * 3 / 4, height() / 2);
|
|
||||||
bufferSize = QSize(width() / 2, height());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
trackPad = QRect();
|
|
||||||
bufferSize = size();
|
|
||||||
}
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void timerEvent(QTimerEvent*) {
|
|
||||||
updatePlayer();
|
|
||||||
render();
|
|
||||||
showFps();
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *event) {
|
|
||||||
QPainter p(this);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
|
|
||||||
p.drawImage(event->rect(), buffer, event->rect());
|
|
||||||
|
|
||||||
if (touchDevice && event->rect().intersects(trackPad)) {
|
|
||||||
p.fillRect(trackPad, Qt::white);
|
|
||||||
p.setPen(QPen(QColor(224, 224, 224), 6));
|
|
||||||
int rad = qMin(trackPad.width(), trackPad.height()) * 0.3;
|
|
||||||
p.drawEllipse(centerPad, rad, rad);
|
|
||||||
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setBrush(Qt::gray);
|
|
||||||
|
|
||||||
QPolygon poly;
|
|
||||||
poly << QPoint(-30, 0);
|
|
||||||
poly << QPoint(0, -40);
|
|
||||||
poly << QPoint(30, 0);
|
|
||||||
|
|
||||||
p.translate(centerPad);
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
p.rotate(90);
|
|
||||||
p.translate(0, 20 - rad);
|
|
||||||
p.drawPolygon(poly);
|
|
||||||
p.translate(0, rad - 20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent *event) {
|
|
||||||
event->accept();
|
|
||||||
if (event->key() == Qt::Key_Left)
|
|
||||||
angleDelta = 1.3 * M_PI;
|
|
||||||
if (event->key() == Qt::Key_Right)
|
|
||||||
angleDelta = -1.3 * M_PI;
|
|
||||||
if (event->key() == Qt::Key_Up)
|
|
||||||
moveDelta = 2.5;
|
|
||||||
if (event->key() == Qt::Key_Down)
|
|
||||||
moveDelta = -2.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyReleaseEvent(QKeyEvent *event) {
|
|
||||||
event->accept();
|
|
||||||
if (event->key() == Qt::Key_Left)
|
|
||||||
angleDelta = (angleDelta > 0) ? 0 : angleDelta;
|
|
||||||
if (event->key() == Qt::Key_Right)
|
|
||||||
angleDelta = (angleDelta < 0) ? 0 : angleDelta;
|
|
||||||
if (event->key() == Qt::Key_Up)
|
|
||||||
moveDelta = (moveDelta > 0) ? 0 : moveDelta;
|
|
||||||
if (event->key() == Qt::Key_Down)
|
|
||||||
moveDelta = (moveDelta < 0) ? 0 : moveDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mousePressEvent(QMouseEvent *event) {
|
|
||||||
qreal dx = centerPad.x() - event->position().toPoint().x();
|
|
||||||
qreal dy = centerPad.y() - event->position().toPoint().y();
|
|
||||||
angleDelta = dx * 2 * M_PI / width();
|
|
||||||
moveDelta = dy * 10 / height();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent *event) {
|
|
||||||
qreal dx = centerPad.x() - event->position().toPoint().x();
|
|
||||||
qreal dy = centerPad.y() - event->position().toPoint().y();
|
|
||||||
angleDelta = dx * 2 * M_PI / width();
|
|
||||||
moveDelta = dy * 10 / height();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseReleaseEvent(QMouseEvent*) {
|
|
||||||
angleDelta = 0;
|
|
||||||
moveDelta = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QElapsedTimer watch;
|
|
||||||
QBasicTimer ticker;
|
|
||||||
QImage buffer;
|
|
||||||
qreal angle;
|
|
||||||
QPointF playerPos;
|
|
||||||
qreal angleDelta;
|
|
||||||
qreal moveDelta;
|
|
||||||
QImage textureImg;
|
|
||||||
int textureCount;
|
|
||||||
bool touchDevice;
|
|
||||||
QRect trackPad;
|
|
||||||
QPoint centerPad;
|
|
||||||
QSize bufferSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
Raycasting w;
|
|
||||||
w.setWindowTitle("Raycasting");
|
|
||||||
w.resize(640, 480);
|
|
||||||
w.show();
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
TEMPLATE = app
|
|
||||||
QT += widgets
|
|
||||||
SOURCES = raycasting.cpp
|
|
||||||
RESOURCES += raycasting.qrc
|
|
||||||
|
|
||||||
target.path = $$[QT_INSTALL_EXAMPLES]/embedded/raycasting
|
|
||||||
INSTALLS += target
|
|
@ -1,5 +0,0 @@
|
|||||||
<RCC>
|
|
||||||
<qresource prefix="/" >
|
|
||||||
<file>textures.png</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
@ -1,56 +0,0 @@
|
|||||||
# Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(styleexample LANGUAGES CXX)
|
|
||||||
|
|
||||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
|
||||||
set(INSTALL_EXAMPLESDIR "examples")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/embedded/styleexample")
|
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
|
||||||
|
|
||||||
qt_standard_project_setup()
|
|
||||||
|
|
||||||
qt_add_executable(styleexample
|
|
||||||
main.cpp
|
|
||||||
stylewidget.cpp stylewidget.h stylewidget.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(styleexample PROPERTIES
|
|
||||||
WIN32_EXECUTABLE TRUE
|
|
||||||
MACOSX_BUNDLE TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(styleexample PRIVATE
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Gui
|
|
||||||
Qt6::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
# Resources:
|
|
||||||
set(styleexample_resource_files
|
|
||||||
"files/add.png"
|
|
||||||
"files/application.qss"
|
|
||||||
"files/blue.qss"
|
|
||||||
"files/khaki.qss"
|
|
||||||
"files/nature_1.jpg"
|
|
||||||
"files/nostyle.qss"
|
|
||||||
"files/remove.png"
|
|
||||||
"files/transparent.qss"
|
|
||||||
)
|
|
||||||
|
|
||||||
qt_add_resources(styleexample "styleexample"
|
|
||||||
PREFIX
|
|
||||||
"/"
|
|
||||||
FILES
|
|
||||||
${styleexample_resource_files}
|
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS styleexample
|
|
||||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
|
||||||
)
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
@ -1,125 +0,0 @@
|
|||||||
QWidget#StyleWidget
|
|
||||||
{
|
|
||||||
background-color: none;
|
|
||||||
background-image: url(icons:nature_1.jpg);
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel, QAbstractButton
|
|
||||||
{
|
|
||||||
font: bold;
|
|
||||||
color: beige;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAbstractButton
|
|
||||||
{
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(173,216,230,60%), stop:1 rgba(0,0,139,60%) );
|
|
||||||
border-color: black;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 3px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAbstractButton:pressed, QAbstractButton:checked
|
|
||||||
{
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox {
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-right: 24px;
|
|
||||||
border-color: darkkhaki;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 5;
|
|
||||||
border-width: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::up-button
|
|
||||||
{
|
|
||||||
subcontrol-origin: padding;
|
|
||||||
subcontrol-position: right; /* position at the top right corner */
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-width: 3px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::up-arrow
|
|
||||||
{
|
|
||||||
image: url(icons:add.png);
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QSpinBox::down-button
|
|
||||||
{
|
|
||||||
subcontrol-origin: border;
|
|
||||||
subcontrol-position: left;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-width: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::down-arrow
|
|
||||||
{
|
|
||||||
image: url(icons:remove.png);
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QScrollBar:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
|
|
||||||
height: 15px;
|
|
||||||
margin: 0px 20px 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::handle:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: rgba(0,0,139,60%);
|
|
||||||
min-width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-line:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: rgba(0,0,139,60%);
|
|
||||||
width: 20px;
|
|
||||||
subcontrol-position: right;
|
|
||||||
subcontrol-origin: margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::sub-line:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: rgba(0,0,139,60%);
|
|
||||||
width: 20px;
|
|
||||||
subcontrol-position: left;
|
|
||||||
subcontrol-origin: margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal
|
|
||||||
{
|
|
||||||
border: none;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar:left-arrow:horizontal
|
|
||||||
{
|
|
||||||
image: url(icons:add.png)
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::right-arrow:horizontal
|
|
||||||
{
|
|
||||||
image: url(icons:remove.png)
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
|
|
||||||
{
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
*
|
|
||||||
{
|
|
||||||
color: beige;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel, QAbstractButton
|
|
||||||
{
|
|
||||||
font: bold;
|
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFrame
|
|
||||||
{
|
|
||||||
background-color: rgba(96,96,255,60%);
|
|
||||||
border-color: rgb(32,32,196);
|
|
||||||
border-width: 3px;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 5;
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAbstractButton
|
|
||||||
{
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
|
||||||
stop:0 lightblue, stop:0.5 darkblue);
|
|
||||||
border-width: 3px;
|
|
||||||
border-color: darkblue;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 5;
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAbstractButton:pressed
|
|
||||||
{
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
|
||||||
stop:0.5 darkblue, stop:1 lightblue);
|
|
||||||
border-color: beige;
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
|
|
||||||
QWidget#StartScreen, QWidget#MainWidget {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget#StartScreen, .QFrame {
|
|
||||||
background-color: beige;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton, QToolButton {
|
|
||||||
background-color: palegoldenrod;
|
|
||||||
border-width: 2px;
|
|
||||||
border-color: darkkhaki;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 5;
|
|
||||||
padding: 3px;
|
|
||||||
/* min-width: 96px; */
|
|
||||||
/* min-height: 48px; */
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton:hover, QToolButton:hover {
|
|
||||||
background-color: khaki;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton:pressed, QToolButton:pressed {
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #d0d67c;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel, QAbstractButton {
|
|
||||||
font: italic "Times New Roman";
|
|
||||||
}
|
|
||||||
|
|
||||||
QFrame, QLabel#title {
|
|
||||||
border-width: 2px;
|
|
||||||
padding: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: darkkhaki;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFrame:focus {
|
|
||||||
border-width: 3px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QLabel {
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel#title {
|
|
||||||
font: 32px bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox {
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-right: 24px;
|
|
||||||
border-color: darkkhaki;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 5;
|
|
||||||
border-width: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::up-button
|
|
||||||
{
|
|
||||||
subcontrol-origin: padding;
|
|
||||||
subcontrol-position: right; /* position at the top right corner */
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-width: 3px;
|
|
||||||
border-image: url(:/files/spindownpng) 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::up-arrow {
|
|
||||||
image: url(:/files/add.png);
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QSpinBox::down-button
|
|
||||||
{
|
|
||||||
subcontrol-origin: border;
|
|
||||||
subcontrol-position: left;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-width: 3px;
|
|
||||||
border-image: url(:/files/spindownpng) 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::down-arrow {
|
|
||||||
image: url(:/files/remove.png);
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 164 KiB |
Binary file not shown.
Before Width: | Height: | Size: 865 B |
@ -1,139 +0,0 @@
|
|||||||
QWidget#StyleWidget
|
|
||||||
{
|
|
||||||
background-color: none;
|
|
||||||
background-image: url(:/files/nature_1.jpg);
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel, QAbstractButton
|
|
||||||
{
|
|
||||||
color: beige;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFrame, QLabel#title {
|
|
||||||
border-width: 2px;
|
|
||||||
padding: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: black;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFrame:focus {
|
|
||||||
border-width: 3px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QAbstractButton
|
|
||||||
{
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(173,216,230,60%), stop:1 rgba(0,0,139,60%) );
|
|
||||||
border-color: black;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 3px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAbstractButton:pressed, QAbstractButton:checked
|
|
||||||
{
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox {
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-right: 24px;
|
|
||||||
border-color: darkkhaki;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: 5;
|
|
||||||
border-width: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::up-button
|
|
||||||
{
|
|
||||||
subcontrol-origin: padding;
|
|
||||||
subcontrol-position: right; /* position at the top right corner */
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-width: 3px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::up-arrow
|
|
||||||
{
|
|
||||||
image: url(:/files/add.png);
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QSpinBox::down-button
|
|
||||||
{
|
|
||||||
subcontrol-origin: border;
|
|
||||||
subcontrol-position: left;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-width: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSpinBox::down-arrow
|
|
||||||
{
|
|
||||||
image: url(:/files/remove.png);
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QScrollBar:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0,0,139,60%), stop:1 rgba(173,216,230,60%) );
|
|
||||||
height: 15px;
|
|
||||||
margin: 0px 20px 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::handle:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: rgba(0,0,139,60%);
|
|
||||||
min-width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-line:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: rgba(0,0,139,60%);
|
|
||||||
width: 20px;
|
|
||||||
subcontrol-position: right;
|
|
||||||
subcontrol-origin: margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::sub-line:horizontal
|
|
||||||
{
|
|
||||||
border: 1px solid black;
|
|
||||||
background: rgba(0,0,139,60%);
|
|
||||||
width: 20px;
|
|
||||||
subcontrol-position: left;
|
|
||||||
subcontrol-origin: margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar:left-arrow:horizontal, QScrollBar::right-arrow:horizontal
|
|
||||||
{
|
|
||||||
border: none;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar:left-arrow:horizontal
|
|
||||||
{
|
|
||||||
image: url(:/files/add.png)
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::right-arrow:horizontal
|
|
||||||
{
|
|
||||||
image: url(:/files/remove.png)
|
|
||||||
}
|
|
||||||
|
|
||||||
QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
|
|
||||||
{
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
#include "stylewidget.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
app.setApplicationName("style");
|
|
||||||
app.setOrganizationName("QtProject");
|
|
||||||
app.setOrganizationDomain("www.qt-project.org");
|
|
||||||
|
|
||||||
StyleWidget widget;
|
|
||||||
widget.showFullScreen();
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
QT += widgets
|
|
||||||
|
|
||||||
HEADERS += stylewidget.h
|
|
||||||
FORMS += stylewidget.ui
|
|
||||||
SOURCES += main.cpp stylewidget.cpp
|
|
||||||
RESOURCES += styleexample.qrc
|
|
||||||
|
|
||||||
target.path = $$[QT_INSTALL_EXAMPLES]/embedded/styleexample
|
|
||||||
INSTALLS += target
|
|
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE RCC><RCC version="1.0">
|
|
||||||
<qresource prefix="/">
|
|
||||||
<file>files/add.png</file>
|
|
||||||
<file>files/blue.qss</file>
|
|
||||||
<file>files/khaki.qss</file>
|
|
||||||
<file>files/nostyle.qss</file>
|
|
||||||
<file>files/transparent.qss</file>
|
|
||||||
<file>files/application.qss</file>
|
|
||||||
<file>files/nature_1.jpg</file>
|
|
||||||
<file>files/remove.png</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QString>
|
|
||||||
#include <QFile>
|
|
||||||
|
|
||||||
#include "stylewidget.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StyleWidget::StyleWidget(QWidget *parent)
|
|
||||||
: QFrame(parent)
|
|
||||||
{
|
|
||||||
m_ui.setupUi(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void StyleWidget::on_close_clicked()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StyleWidget::on_blueStyle_clicked()
|
|
||||||
{
|
|
||||||
QFile styleSheet(":/files/blue.qss");
|
|
||||||
|
|
||||||
if (!styleSheet.open(QIODevice::ReadOnly)) {
|
|
||||||
qWarning("Unable to open :/files/blue.qss");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qApp->setStyleSheet(styleSheet.readAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
void StyleWidget::on_khakiStyle_clicked()
|
|
||||||
{
|
|
||||||
QFile styleSheet(":/files/khaki.qss");
|
|
||||||
|
|
||||||
if (!styleSheet.open(QIODevice::ReadOnly)) {
|
|
||||||
qWarning("Unable to open :/files/khaki.qss");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qApp->setStyleSheet(styleSheet.readAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void StyleWidget::on_noStyle_clicked()
|
|
||||||
{
|
|
||||||
QFile styleSheet(":/files/nostyle.qss");
|
|
||||||
|
|
||||||
if (!styleSheet.open(QIODevice::ReadOnly)) {
|
|
||||||
qWarning("Unable to open :/files/nostyle.qss");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qApp->setStyleSheet(styleSheet.readAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void StyleWidget::on_transparentStyle_clicked()
|
|
||||||
{
|
|
||||||
QFile styleSheet(":/files/transparent.qss");
|
|
||||||
|
|
||||||
if (!styleSheet.open(QIODevice::ReadOnly)) {
|
|
||||||
qWarning("Unable to open :/files/transparent.qss");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qApp->setStyleSheet(styleSheet.readAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
// Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
||||||
#ifndef STYLEWIDGET_H
|
|
||||||
#define STYLEWIDGET_H
|
|
||||||
|
|
||||||
#include <QFrame>
|
|
||||||
|
|
||||||
#include "ui_stylewidget.h"
|
|
||||||
|
|
||||||
class StyleWidget : public QFrame
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
StyleWidget(QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui_StyleWidget m_ui;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void on_close_clicked();
|
|
||||||
void on_blueStyle_clicked();
|
|
||||||
void on_khakiStyle_clicked();
|
|
||||||
void on_noStyle_clicked();
|
|
||||||
void on_transparentStyle_clicked();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,417 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>StyleWidget</class>
|
|
||||||
<widget class="QWidget" name="StyleWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>184</width>
|
|
||||||
<height>245</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0" colspan="2">
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Styles</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<property name="margin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<property name="spacing">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QPushButton" name="transparentStyle">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::StrongFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Transp.</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="autoExclusive">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QPushButton" name="blueStyle">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::StrongFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Blue</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="autoExclusive">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QPushButton" name="khakiStyle">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::StrongFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Khaki</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="autoExclusive">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QPushButton" name="noStyle">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::StrongFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>None</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="autoExclusive">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<spacer name="verticalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="margin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Value:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="spinBox">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::WheelFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="keyboardTracking">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QScrollBar" name="horizontalScrollBar">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>24</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::TabFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QScrollBar" name="horizontalScrollBar_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>24</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::TabFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QPushButton" name="pushButton_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::StrongFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Show</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QPushButton" name="pushButton">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::StrongFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0" colspan="2">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Expanding</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<spacer>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QPushButton" name="close">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::StrongFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Close</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources>
|
|
||||||
<include location="styleexample.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>horizontalScrollBar</sender>
|
|
||||||
<signal>valueChanged(int)</signal>
|
|
||||||
<receiver>horizontalScrollBar_2</receiver>
|
|
||||||
<slot>setValue(int)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>84</x>
|
|
||||||
<y>147</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>166</x>
|
|
||||||
<y>147</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>horizontalScrollBar_2</sender>
|
|
||||||
<signal>valueChanged(int)</signal>
|
|
||||||
<receiver>horizontalScrollBar</receiver>
|
|
||||||
<slot>setValue(int)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>166</x>
|
|
||||||
<y>147</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>84</x>
|
|
||||||
<y>147</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>pushButton</sender>
|
|
||||||
<signal>clicked(bool)</signal>
|
|
||||||
<receiver>horizontalScrollBar_2</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>166</x>
|
|
||||||
<y>175</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>166</x>
|
|
||||||
<y>147</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>pushButton_2</sender>
|
|
||||||
<signal>clicked(bool)</signal>
|
|
||||||
<receiver>horizontalScrollBar</receiver>
|
|
||||||
<slot>setVisible(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>84</x>
|
|
||||||
<y>175</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>84</x>
|
|
||||||
<y>147</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>spinBox</sender>
|
|
||||||
<signal>valueChanged(int)</signal>
|
|
||||||
<receiver>horizontalScrollBar_2</receiver>
|
|
||||||
<slot>setValue(int)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>166</x>
|
|
||||||
<y>115</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>166</x>
|
|
||||||
<y>147</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>horizontalScrollBar_2</sender>
|
|
||||||
<signal>valueChanged(int)</signal>
|
|
||||||
<receiver>spinBox</receiver>
|
|
||||||
<slot>setValue(int)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>132</x>
|
|
||||||
<y>132</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>135</x>
|
|
||||||
<y>110</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
@ -2,8 +2,7 @@ TEMPLATE = subdirs
|
|||||||
CONFIG += no_docs_target
|
CONFIG += no_docs_target
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
corelib \
|
corelib
|
||||||
embedded
|
|
||||||
|
|
||||||
!contains(TEMPLATE, "vc.*") { # QTBUG-91033
|
!contains(TEMPLATE, "vc.*") { # QTBUG-91033
|
||||||
qtHaveModule(dbus): SUBDIRS += dbus
|
qtHaveModule(dbus): SUBDIRS += dbus
|
||||||
|
Loading…
Reference in New Issue
Block a user