188 lines
7.3 KiB
C++
188 lines
7.3 KiB
C++
|
/****************************************************************************
|
||
|
**
|
||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||
|
** Contact: https://www.qt.io/licensing/
|
||
|
**
|
||
|
** This file is part of the examples of the Qt Toolkit.
|
||
|
**
|
||
|
** $QT_BEGIN_LICENSE:BSD$
|
||
|
** Commercial License Usage
|
||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||
|
** accordance with the commercial license agreement provided with the
|
||
|
** Software or, alternatively, in accordance with the terms contained in
|
||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||
|
**
|
||
|
** BSD License Usage
|
||
|
** Alternatively, you may use this file under the terms of the BSD license
|
||
|
** as follows:
|
||
|
**
|
||
|
** "Redistribution and use in source and binary forms, with or without
|
||
|
** modification, are permitted provided that the following conditions are
|
||
|
** met:
|
||
|
** * Redistributions of source code must retain the above copyright
|
||
|
** notice, this list of conditions and the following disclaimer.
|
||
|
** * Redistributions in binary form must reproduce the above copyright
|
||
|
** notice, this list of conditions and the following disclaimer in
|
||
|
** the documentation and/or other materials provided with the
|
||
|
** distribution.
|
||
|
** * Neither the name of The Qt Company Ltd nor the names of its
|
||
|
** contributors may be used to endorse or promote products derived
|
||
|
** from this software without specific prior written permission.
|
||
|
**
|
||
|
**
|
||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||
|
**
|
||
|
** $QT_END_LICENSE$
|
||
|
**
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include "mainwindow.h"
|
||
|
|
||
|
#include <QApplication>
|
||
|
#include <QMenuBar>
|
||
|
#include <QGroupBox>
|
||
|
#include <QSlider>
|
||
|
#include <QLabel>
|
||
|
#include <QCheckBox>
|
||
|
#include <QRandomGenerator>
|
||
|
#include <QSpinBox>
|
||
|
#include <QScrollArea>
|
||
|
|
||
|
#include "glwidget.h"
|
||
|
|
||
|
MainWindow::MainWindow()
|
||
|
: m_nextX(1), m_nextY(1)
|
||
|
{
|
||
|
GLWidget *glwidget = new GLWidget(this, true, qRgb(20, 20, 50));
|
||
|
m_glWidgets << glwidget;
|
||
|
QLabel *label = new QLabel(this);
|
||
|
m_timer = new QTimer(this);
|
||
|
QSlider *slider = new QSlider(this);
|
||
|
slider->setOrientation(Qt::Horizontal);
|
||
|
|
||
|
QLabel *updateLabel = new QLabel("Update interval");
|
||
|
QSpinBox *updateInterval = new QSpinBox(this);
|
||
|
updateInterval->setSuffix(" ms");
|
||
|
updateInterval->setValue(10);
|
||
|
updateInterval->setToolTip("Interval for the timer that calls update().\n"
|
||
|
"Note that on most systems the swap will block to wait for vsync\n"
|
||
|
"and therefore an interval < 16 ms will likely lead to a 60 FPS update rate.");
|
||
|
QGroupBox *updateGroupBox = new QGroupBox(this);
|
||
|
QCheckBox *timerBased = new QCheckBox("Use timer", this);
|
||
|
timerBased->setChecked(false);
|
||
|
timerBased->setToolTip("Toggles using a timer to trigger update().\n"
|
||
|
"When not set, each paintGL() schedules the next update immediately,\n"
|
||
|
"expecting the blocking swap to throttle the thread.\n"
|
||
|
"This shows how unnecessary the timer is in most cases.");
|
||
|
QCheckBox *transparent = new QCheckBox("Transparent background", this);
|
||
|
transparent->setToolTip("Toggles Qt::WA_AlwaysStackOnTop and transparent clear color for glClear().\n"
|
||
|
"Note how the button on top stacks incorrectly when enabling this.");
|
||
|
QHBoxLayout *updateLayout = new QHBoxLayout;
|
||
|
updateLayout->addWidget(updateLabel);
|
||
|
updateLayout->addWidget(updateInterval);
|
||
|
updateLayout->addWidget(timerBased);
|
||
|
updateLayout->addWidget(transparent);
|
||
|
updateGroupBox->setLayout(updateLayout);
|
||
|
|
||
|
slider->setRange(0, 50);
|
||
|
slider->setSliderPosition(30);
|
||
|
m_timer->setInterval(10);
|
||
|
label->setText("A scrollable QOpenGLWidget");
|
||
|
label->setAlignment(Qt::AlignHCenter);
|
||
|
|
||
|
QGroupBox * groupBox = new QGroupBox(this);
|
||
|
setCentralWidget(groupBox);
|
||
|
groupBox->setTitle("QOpenGLWidget Example");
|
||
|
|
||
|
m_layout = new QGridLayout(groupBox);
|
||
|
|
||
|
QScrollArea *scrollArea = new QScrollArea;
|
||
|
scrollArea->setWidget(glwidget);
|
||
|
|
||
|
m_layout->addWidget(scrollArea,1,0,8,1);
|
||
|
m_layout->addWidget(label,9,0,1,1);
|
||
|
m_layout->addWidget(updateGroupBox, 10, 0, 1, 1);
|
||
|
m_layout->addWidget(slider, 11,0,1,1);
|
||
|
|
||
|
groupBox->setLayout(m_layout);
|
||
|
|
||
|
|
||
|
QMenu *fileMenu = menuBar()->addMenu("&File");
|
||
|
fileMenu->addAction("E&xit", this, &QWidget::close);
|
||
|
QMenu *showMenu = menuBar()->addMenu("&Show");
|
||
|
showMenu->addAction("Show 3D Logo", glwidget, &GLWidget::setLogo);
|
||
|
showMenu->addAction("Show 2D Texture", glwidget, &GLWidget::setTexture);
|
||
|
QAction *showBubbles = showMenu->addAction("Show bubbles", glwidget, &GLWidget::setShowBubbles);
|
||
|
showBubbles->setCheckable(true);
|
||
|
showBubbles->setChecked(true);
|
||
|
QMenu *helpMenu = menuBar()->addMenu("&Help");
|
||
|
helpMenu->addAction("About Qt", qApp, &QApplication::aboutQt);
|
||
|
|
||
|
connect(m_timer, &QTimer::timeout, glwidget, QOverload<>::of(&QWidget::update));
|
||
|
|
||
|
connect(slider, &QAbstractSlider::valueChanged, glwidget, &GLWidget::setScaling);
|
||
|
connect(transparent, &QCheckBox::toggled, glwidget, &GLWidget::setTransparent);
|
||
|
connect(updateInterval, QOverload<int>::of(&QSpinBox::valueChanged),
|
||
|
this, &MainWindow::updateIntervalChanged);
|
||
|
connect(timerBased, &QCheckBox::toggled, this, &MainWindow::timerUsageChanged);
|
||
|
connect(timerBased, &QCheckBox::toggled, updateInterval, &QWidget::setEnabled);
|
||
|
|
||
|
if (timerBased->isChecked())
|
||
|
m_timer->start();
|
||
|
else
|
||
|
updateInterval->setEnabled(false);
|
||
|
}
|
||
|
|
||
|
void MainWindow::updateIntervalChanged(int value)
|
||
|
{
|
||
|
m_timer->setInterval(value);
|
||
|
if (m_timer->isActive())
|
||
|
m_timer->start();
|
||
|
}
|
||
|
|
||
|
void MainWindow::addNew()
|
||
|
{
|
||
|
if (m_nextY == 4)
|
||
|
return;
|
||
|
GLWidget *w = new GLWidget(this, false, qRgb(QRandomGenerator::global()->bounded(256),
|
||
|
QRandomGenerator::global()->bounded(256),
|
||
|
QRandomGenerator::global()->bounded(256)));
|
||
|
m_glWidgets << w;
|
||
|
connect(m_timer, &QTimer::timeout, w, QOverload<>::of(&QWidget::update));
|
||
|
m_layout->addWidget(w, m_nextY, m_nextX, 1, 1);
|
||
|
if (m_nextX == 3) {
|
||
|
m_nextX = 1;
|
||
|
++m_nextY;
|
||
|
} else {
|
||
|
++m_nextX;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainWindow::timerUsageChanged(bool enabled)
|
||
|
{
|
||
|
if (enabled) {
|
||
|
m_timer->start();
|
||
|
} else {
|
||
|
m_timer->stop();
|
||
|
for (QOpenGLWidget *w : qAsConst(m_glWidgets))
|
||
|
w->update();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MainWindow::resizeEvent(QResizeEvent *)
|
||
|
{
|
||
|
m_glWidgets[0]->setMinimumSize(size() + QSize(128, 128));
|
||
|
}
|