11/*
2- * SPDX-FileCopyrightText: Copyright 2022-2023 Julian Amann <dev@vertexwahn.de>
2+ * SPDX-FileCopyrightText: Copyright 2022-2026 Julian Amann <dev@vertexwahn.de>
33 * SPDX-License-Identifier: Apache-2.0
44 */
55
66#include " okapi/ui/main_window.hpp"
77
8+ #include " okapi/rendering/scene/load_scene.hpp"
9+ #include " okapi/rendering/sensor/sensor.hpp"
10+
11+ #include " core/stl/filesystem.hpp"
12+ #include " core/stl/string.hpp"
13+
814#include " QtCore/QEvent"
915#include " QtCore/QSettings"
1016#include " QtCore/QThread"
1319#include " QtGui/QKeyEvent"
1420#include " QtWidgets/QApplication"
1521#include " QtWidgets/QFileDialog"
22+ #include " QtGui/QSurfaceFormat"
1623
17- MainWindow::MainWindow (CommandLineArguments* cla, QWidget *parent /* = nullptr*/ )
18- : ui_(new Ui::MainWindow), cla_(cla) {
24+ MainWindow::MainWindow (CommandLineArguments *cla, QWidget *parent /* = nullptr*/ )
25+ : ui_(new Ui::MainWindow)
26+ , cla_(cla) {
1927 ui_->setupUi (this );
2028
2129 QHBoxLayout *layout = new QHBoxLayout ();
2230 ui_->scrollAreaWidgetContents ->setLayout (layout);
2331
24- rw_ = new Viewport (*cla);
25- layout->addWidget (rw_);
32+ {
33+ rw_ = new Viewport (*cla);
34+ layout->addWidget (rw_);
2635
27- connect (&rw_->render_scene_thread_ , SIGNAL (update (const QString&)), this , SLOT (update (const QString&)));
36+ connect (&rw_->render_scene_thread_ , SIGNAL (update (const QString&)), this , SLOT (update (const QString&)));
2837
29- rw_->render_scene_thread_ .start ();
30- rw_->render_preview_thread_ .start ();
38+ rw_->render_scene_thread_ .start ();
39+ rw_->render_preview_thread_ .start ();
40+ }
3141
3242 installEventFilter (this );
3343
3444 if (cla_->show_maximized ()) {
3545 this ->showMaximized ();
3646 LOG_INFO_WITH_LOCATION (" Show maximized" );
3747 }
48+
49+ update_scene_explorer ();
50+ }
51+
52+ void MainWindow::update_scene_explorer () {
53+ if (!rw_) { return ; }
3854}
3955
4056bool MainWindow::eventFilter (QObject *target, QEvent *event) {
41- if (event->type () == QEvent::KeyPress)
42- {
43- QKeyEvent *key_event = static_cast <QKeyEvent*>(event);
57+ if (event->type () == QEvent::KeyPress) {
58+ QKeyEvent *key_event = static_cast <QKeyEvent *>(event);
4459
45- if (key_event->key () == Qt::Key_Escape)
46- {
60+ if (key_event->key () == Qt::Key_Escape) {
4761 this ->close ();
48- return QMainWindow::eventFilter (target,event);
62+ return QMainWindow::eventFilter (target, event);
4963 }
5064 }
51- return QMainWindow::eventFilter (target,event);
65+ return QMainWindow::eventFilter (target, event);
5266}
5367
5468void MainWindow::write_position_settings () {
55- QSettings settings ( " devertexwahn" , " okapi" );
69+ QSettings settings (" devertexwahn" , " okapi" );
5670
57- settings.beginGroup ( " mainwindow" );
71+ settings.beginGroup (" mainwindow" );
5872
59- settings.setValue ( " geometry" , saveGeometry () );
60- settings.setValue ( " savestate" , saveState () );
61- settings.setValue ( " maximized" , isMaximized () );
62- if ( !isMaximized () ) {
63- settings.setValue ( " pos" , pos () );
64- settings.setValue ( " size" , size () );
73+ settings.setValue (" geometry" , saveGeometry ());
74+ settings.setValue (" savestate" , saveState ());
75+ settings.setValue (" maximized" , isMaximized ());
76+ if (!isMaximized ()) {
77+ settings.setValue (" pos" , pos ());
78+ settings.setValue (" size" , size ());
6579 }
6680
6781 settings.endGroup ();
6882}
6983
7084void MainWindow::read_position_settings () {
71- QSettings settings ( " devertexwahn" , " okapi" );
85+ QSettings settings (" devertexwahn" , " okapi" );
7286
73- settings.beginGroup ( " mainwindow" );
87+ settings.beginGroup (" mainwindow" );
7488
75- restoreGeometry (settings.value ( " geometry" , saveGeometry () ).toByteArray ());
76- restoreState (settings.value ( " savestate" , saveState () ).toByteArray ());
77- move (settings.value ( " pos" , pos () ).toPoint ());
78- resize (settings.value ( " size" , size () ).toSize ());
79- if ( settings.value ( " maximized" , isMaximized () ).toBool () )
89+ restoreGeometry (settings.value (" geometry" , saveGeometry ()).toByteArray ());
90+ restoreState (settings.value (" savestate" , saveState ()).toByteArray ());
91+ move (settings.value (" pos" , pos ()).toPoint ());
92+ resize (settings.value (" size" , size ()).toSize ());
93+ if (settings.value (" maximized" , isMaximized ()).toBool ())
8094 showMaximized ();
8195
8296 settings.endGroup ();
8397}
8498
85- void MainWindow::moveEvent ( QMoveEvent* ) {
99+ void MainWindow::moveEvent (QMoveEvent * ) {
86100 write_position_settings ();
87101}
88102
89- void MainWindow::resizeEvent ( QResizeEvent* ) {
103+ void MainWindow::resizeEvent (QResizeEvent * ) {
90104 write_position_settings ();
91105}
92106
93- void MainWindow::closeEvent ( QCloseEvent* ) {
94- LOG_INFO_WITH_LOCATION (" Shutting down preview thread" );
95- rw_->render_preview_thread_ .stop_update_ = true ;
96- rw_->render_preview_thread_ .wait ();
107+ void MainWindow::closeEvent (QCloseEvent *) {
108+ if (rw_) {
109+ LOG_INFO_WITH_LOCATION (" Shutting down preview thread" );
110+ rw_->render_preview_thread_ .stop_update_ = true ;
111+ rw_->render_preview_thread_ .wait ();
97112
98- rw_->render_scene_thread_ .render_desc_ .abort = true ;
99- LOG_INFO_WITH_LOCATION (" Waiting for render thread" );
100- rw_->render_scene_thread_ .wait ();
101- LOG_INFO_WITH_LOCATION (" Render thread finished" );
113+ rw_->render_scene_thread_ .render_desc_ .abort = true ;
114+ LOG_INFO_WITH_LOCATION (" Waiting for render thread" );
115+ rw_->render_scene_thread_ .wait ();
116+ LOG_INFO_WITH_LOCATION (" Render thread finished" );
117+ }
102118
103119 write_position_settings ();
104120}
105121
122+ void MainWindow::on_actionScene_Explorer_triggered () {
123+ read_position_settings ();
124+
125+ if (!ui_->dockWidgetSceneExplorer ->isVisible ()) {
126+ ui_->dockWidgetSceneExplorer ->show ();
127+ }
128+ }
129+
106130void MainWindow::on_actionExit_triggered () {
107131 QApplication::quit ();
108132};
109133
110134void MainWindow::on_actionAbout_triggered () {
111- if (!about_dialog_)
135+ if (!about_dialog_)
112136 about_dialog_ = new AboutDialog (this );
113137
114138 about_dialog_->show ();
115139}
116140
117141void MainWindow::on_actionSettings_triggered () {
118- if (!settings_dialog_)
142+ if (!settings_dialog_)
119143 settings_dialog_ = new SettingsDialog (cla_, this );
120144
121145 settings_dialog_->show ();
122146}
123147
124148void MainWindow::on_actionFit_render_output_to_window_triggered () {
125- ui_->scrollArea ->setFixedSize (rw_->render_preview_thread_ .image_ ->size ().x ()+18 , rw_->render_preview_thread_ .image_ ->size ().y ()+18 );
149+ if (!rw_) { return ; }
150+ ui_->scrollArea ->setFixedSize (rw_->render_preview_thread_ .image_ ->size ().x () + 18 ,
151+ rw_->render_preview_thread_ .image_ ->size ().y () + 18 );
126152 this ->adjustSize ();
127153}
128154
129- void MainWindow::on_actionPortable_Pixel_Map_triggered () {
130- QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" Portable Pixel Map (*.ppm)" ));
155+ void MainWindow::on_actionExportPortablePixelMap_triggered () {
156+ if (!rw_) { return ; }
157+ QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (),
158+ tr (" Portable Pixel Map (*.ppm)" ));
131159
132160 if (!filename.isNull ()) {
133161 rw_->save_as_ppm (filename);
134162 }
135163}
136164
137165void MainWindow::on_actionExportPFM_triggered () {
138- QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" Portable FloatMap Image Format (*.pfm)" ));
166+ if (!rw_) { return ; }
167+ QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (),
168+ tr (" Portable FloatMap Image Format (*.pfm)" ));
139169
140170 if (!filename.isNull ()) {
141171 rw_->save_as_pfm (filename);
142172 }
143173}
144174
145175void MainWindow::on_actionExportPNG_triggered () {
146- QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" Portable Network Graphics (*.png)" ));
176+ if (!rw_) { return ; }
177+ QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (),
178+ tr (" Portable Network Graphics (*.png)" ));
147179
148180 if (!filename.isNull ()) {
149181 rw_->save_as_png (filename);
150- }
182+ }
183+ }
184+
185+ void MainWindow::on_actionExportTIFF_triggered () {
186+ if (!rw_) { return ; }
187+ QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (),
188+ tr (" Tagged Image File Format (*.tiff)" ));
189+
190+ if (!filename.isNull ()) {
191+ rw_->save_as_tiff (filename);
192+ }
151193}
152194
153195void MainWindow::on_actionExportWebP_triggered () {
154- QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" WebP (*.webp)" ));
196+ if (!rw_) { return ; }
197+ QString filename =
198+ QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" WebP (*.webp)" ));
155199
156200 if (!filename.isNull ()) {
157201 rw_->save_as_webp (filename);
158202 }
159203}
160204
161- void MainWindow::on_actionOpenEXR_exr_triggered () {
162- QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" OpenEXR (*.exr)" ));
205+ void MainWindow::on_actionExportGIF_triggered () {
206+ if (!rw_) { return ; }
207+ QString filename =
208+ QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" GIF (*.gif)" ));
209+
210+ if (!filename.isNull ()) {
211+ rw_->save_as_gif (filename);
212+ }
213+ }
214+
215+ void MainWindow::on_actionExportOpenEXR_triggered () {
216+ if (!rw_) { return ; }
217+ QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (),
218+ tr (" OpenEXR (*.exr)" ));
163219
164220 if (!filename.isNull ()) {
165221 rw_->save_as_open_exr (filename);
166- }
222+ }
167223}
168224
169- void MainWindow::on_actionJPEG_triggered () {
225+ void MainWindow::on_actionExportJPEG_triggered () {
226+ if (!rw_) { return ; }
170227 QString filename = QFileDialog::getSaveFileName (this , tr (" Save Document" ), QDir::currentPath (), tr (" JPEG (*.jpg)" ));
171228
172229 if (!filename.isNull ()) {
@@ -175,20 +232,30 @@ void MainWindow::on_actionJPEG_triggered() {
175232}
176233
177234void MainWindow::on_actionCopy_triggered () {
235+ if (!rw_) { return ; }
178236 QGuiApplication::clipboard ()->setImage (*rw_->render_preview_thread_ .qimage_ );
179237}
180238
181239void MainWindow::on_checkBoxDenoise_toggled (bool checked) {
182- rw_->render_preview_thread_ .denoise_image_ = checked;
240+ if (!rw_) { return ; }
241+ rw_->render_preview_thread_ .denoise_image_ = checked;
183242}
184243
185244void MainWindow::on_horizontalSliderExposureValue_valueChanged (int position) {
245+ if (!rw_) { return ; }
186246 float value = position / 100 .f ;
187247 float scale = std::pow (2 .f , (value - 0 .5f ) * 20 );
188248
189249 rw_->render_preview_thread_ .scale_ = scale;
190250}
191251
192- void MainWindow::update (const QString& message) {
252+ void MainWindow::update (const QString &message) {
253+ static bool first_time = true ;
254+ if (first_time && message.startsWith (" Progress" )) {
255+ first_time = false ;
256+
257+ update_scene_explorer ();
258+ }
259+
193260 ui_->statusbar ->showMessage (message);
194261}
0 commit comments