summaryrefslogtreecommitdiffstats
path: root/examples/widgets/rhi/cuberhiwidget/main.cpp
blob: 95a29feee598dcce85f74102114f272eb942f399 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

#include <QApplication>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSlider>
#include <QTextEdit>
#include <QPushButton>
#include <QLabel>
#include <QCheckBox>
#include <QFileDialog>
#include <QFontInfo>
#include <QMouseEvent>
#include <QDrag>
#include <QMimeData>
#include "examplewidget.h"

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QVBoxLayout *layout = new QVBoxLayout;

    ExampleRhiWidget *rhiWidget = new ExampleRhiWidget;
    QLabel *overlayLabel = new QLabel(rhiWidget);
    overlayLabel->setText(QObject::tr("This is a\nsemi-transparent\n overlay widget\n"
                                      "placed on top of\nthe QRhiWidget."));
    overlayLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    overlayLabel->setAutoFillBackground(true);
    QPalette semiTransparent(QColor(255, 0, 0, 64));
    semiTransparent.setBrush(QPalette::Text, Qt::white);
    semiTransparent.setBrush(QPalette::WindowText, Qt::white);
    overlayLabel->setPalette(semiTransparent);
    QFont f = overlayLabel->font();
    f.setPixelSize(QFontInfo(f).pixelSize() * 2);
    f.setWeight(QFont::Bold);
    overlayLabel->setFont(f);
    overlayLabel->resize(320, 320);
    overlayLabel->hide();
    QObject::connect(rhiWidget, &ExampleRhiWidget::resized, rhiWidget, [rhiWidget, overlayLabel] {
        const int w = overlayLabel->width();
        const int h = overlayLabel->height();
        overlayLabel->setGeometry(rhiWidget->width() / 2 - w / 2, rhiWidget->height() / 2 - h / 2, w, h);
    });

    QTextEdit *edit = new QTextEdit(QObject::tr("QRhiWidget!<br><br>"
                                                "The cube is textured with QPainter-generated content.<br><br>"
                                                "Regular, non-native widgets on top work just fine."));
    QObject::connect(edit, &QTextEdit::textChanged, edit, [edit, rhiWidget] {
        rhiWidget->setCubeTextureText(edit->toPlainText());
    });
    edit->setMaximumHeight(100);
    layout->addWidget(edit);

    QSlider *slider = new QSlider(Qt::Horizontal);
    slider->setMinimum(0);
    slider->setMaximum(360);
    QObject::connect(slider, &QSlider::valueChanged, slider, [slider, rhiWidget] {
        rhiWidget->setCubeRotation(slider->value());
    });

    QHBoxLayout *sliderLayout = new QHBoxLayout;
    sliderLayout->addWidget(new QLabel(QObject::tr("Cube rotation")));
    sliderLayout->addWidget(slider);
    layout->addLayout(sliderLayout);

    QHBoxLayout *btnLayout = new QHBoxLayout;

    QLabel *apiLabel = new QLabel;
    btnLayout->addWidget(apiLabel);
    QObject::connect(rhiWidget, &ExampleRhiWidget::rhiChanged, rhiWidget, [apiLabel](const QString &apiName) {
        apiLabel->setText(QObject::tr("Using QRhi on ") + apiName);
    });

    QPushButton *btnMakeWindow = new QPushButton(QObject::tr("Make top-level window"));
    QObject::connect(btnMakeWindow, &QPushButton::clicked, btnMakeWindow, [rhiWidget, btnMakeWindow, layout] {
        if (rhiWidget->parentWidget()) {
            rhiWidget->setParent(nullptr);
            rhiWidget->setAttribute(Qt::WA_DeleteOnClose, true);
            rhiWidget->show();
            btnMakeWindow->setText(QObject::tr("Make child widget"));
        } else {
            rhiWidget->setAttribute(Qt::WA_DeleteOnClose, false);
            layout->addWidget(rhiWidget);
            btnMakeWindow->setText(QObject::tr("Make top-level window"));
        }
    });
    btnLayout->addWidget(btnMakeWindow);

    QPushButton *btn = new QPushButton(QObject::tr("Grab to image"));
    QObject::connect(btn, &QPushButton::clicked, btn, [rhiWidget] {
        QImage image = rhiWidget->grabFramebuffer();
        qDebug() << "Got image" << image;
        if (!image.isNull()) {
            QFileDialog fd(rhiWidget->parentWidget());
            fd.setAcceptMode(QFileDialog::AcceptSave);
            fd.setDefaultSuffix("png");
            fd.selectFile("test.png");
            if (fd.exec() == QDialog::Accepted)
                image.save(fd.selectedFiles().first());
        }
    });
    btnLayout->addWidget(btn);

    QCheckBox *cbMsaa = new QCheckBox(QObject::tr("Use 4x MSAA"));
    QObject::connect(cbMsaa, &QCheckBox::stateChanged, cbMsaa, [cbMsaa, rhiWidget] {
        if (cbMsaa->isChecked())
            rhiWidget->setSampleCount(4);
        else
            rhiWidget->setSampleCount(1);
    });
    btnLayout->addWidget(cbMsaa);

    QCheckBox *cbOvberlay = new QCheckBox(QObject::tr("Show overlay widget"));
    QObject::connect(cbOvberlay, &QCheckBox::stateChanged, cbOvberlay, [cbOvberlay, overlayLabel] {
        if (cbOvberlay->isChecked())
            overlayLabel->setVisible(true);
        else
            overlayLabel->setVisible(false);
    });
    btnLayout->addWidget(cbOvberlay);

    QCheckBox *cbFlip = new QCheckBox(QObject::tr("Flip"));
    QObject::connect(cbFlip, &QCheckBox::stateChanged, cbOvberlay, [cbFlip, rhiWidget] {
        rhiWidget->setMirrorVertically(cbFlip->isChecked());
    });
    btnLayout->addWidget(cbFlip);

    QCheckBox *cbFixedSize = new QCheckBox(QObject::tr("Use fixed color buffer size"));
    btnLayout->addWidget(cbFixedSize);
    QSlider *fixedSizeSlider = new QSlider(Qt::Horizontal);
    fixedSizeSlider->setMinimum(16);
    fixedSizeSlider->setMaximum(512);
    btnLayout->addWidget(fixedSizeSlider);

    QObject::connect(cbFixedSize, &QCheckBox::stateChanged, cbFixedSize, [cbFixedSize, fixedSizeSlider, rhiWidget] {
        if (cbFixedSize->isChecked())
            rhiWidget->setFixedColorBufferSize(QSize(fixedSizeSlider->value(), fixedSizeSlider->value()));
        else
            rhiWidget->setFixedColorBufferSize(QSize());
    });
    QObject::connect(fixedSizeSlider, &QSlider::valueChanged, fixedSizeSlider, [fixedSizeSlider, cbFixedSize, rhiWidget] {
        if (cbFixedSize->isChecked())
            rhiWidget->setFixedColorBufferSize(QSize(fixedSizeSlider->value(), fixedSizeSlider->value()));
    });

    // Exit when the detached window is closed; there is not much we can do
    // with the controls in the main window then.
    QObject::connect(rhiWidget, &QObject::destroyed, rhiWidget, [rhiWidget] {
        if (!rhiWidget->parentWidget())
            qGuiApp->quit();
    });

    layout->addLayout(btnLayout);
    layout->addWidget(rhiWidget);

    rhiWidget->setCubeTextureText(edit->toPlainText());

    QWidget w;
    w.setLayout(layout);
    w.resize(1280, 720);
    w.show();

    return app.exec();
}