1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29 
30 #pragma once
31 
32 // appleseed.studio headers.
33 #include "debug/benchmarks/benchmarkwindow.h"
34 #include "debug/tests/testwindow.h"
35 #include "mainwindow/applicationsettingswindow.h"
36 #include "mainwindow/falsecolorswindow.h"
37 #include "mainwindow/project/projectmanager.h"
38 #include "mainwindow/qtlogtarget.h"
39 #include "mainwindow/rendering/renderingmanager.h"
40 #include "mainwindow/rendering/rendertab.h"
41 #include "mainwindow/renderingsettingswindow.h"
42 #include "mainwindow/statusbar.h"
43 
44 // appleseed.renderer headers.
45 #include "renderer/api/utility.h"
46 
47 // Qt headers.
48 #include <QMainWindow>
49 #include <QObject>
50 
51 // OpenColorIO headers.
52 #include <OpenColorIO/OpenColorIO.h>
53 namespace OCIO = OCIO_NAMESPACE;
54 
55 // Standard headers.
56 #include <map>
57 #include <memory>
58 #include <string>
59 #include <vector>
60 
61 // Forward declarations.
62 namespace appleseed { namespace studio { class AttributeEditor; } }
63 namespace appleseed { namespace studio { class LightPathsTab; } }
64 namespace appleseed { namespace studio { class MinimizeButton; } }
65 namespace appleseed { namespace studio { class ProjectExplorer; } }
66 namespace renderer  { class Project; }
67 namespace Ui        { class MainWindow; }
68 class QAction;
69 class QCloseEvent;
70 class QDragEnterEvent;
71 class QDropEvent;
72 class QFileSystemWatcher;
73 class QPoint;
74 class QRect;
75 class QString;
76 class QStringList;
77 class QWidget;
78 
79 namespace appleseed {
80 namespace studio {
81 
82 //
83 // appleseed.studio's main window.
84 //
85 
86 class MainWindow
87   : public QMainWindow
88 {
89     Q_OBJECT
90 
91   public:
92     // Constructor.
93     explicit MainWindow(QWidget* parent = nullptr);
94 
95     // Destructor.
96     ~MainWindow() override;
97 
98     // Project file handling.
99     void new_project();
100     bool open_project(const QString& filepath);
101     void open_project_async(const QString& filepath);
102     void open_and_render_project(const QString& filepath, const QString& configuration);
103     bool save_project(QString filepath);
104     bool pack_project(QString filepath);
105     void close_project();
106 
107     void on_project_change();
108 
109     ProjectManager* get_project_manager();
110     renderer::ParamArray& get_application_settings();
111 
112     QDockWidget* create_dock_widget(const char* dock_name);
113 
114   signals:
115     void signal_refresh_attribute_editor(const foundation::Dictionary& values) const;
116     void signal_application_settings_modified() const;
117 
118   private:
119     enum RenderingMode
120     {
121         NotRendering,
122         InteractiveRendering,
123         FinalRendering
124     };
125 
126     // Not wrapped in std::unique_ptr<> to avoid pulling in the UI definition code.
127     Ui::MainWindow*                             m_ui;
128 
129     QAction*                                    m_action_new_project;
130     QAction*                                    m_action_open_project;
131     QAction*                                    m_action_save_project;
132     QAction*                                    m_action_reload_project;
133     QAction*                                    m_action_monitor_project_file;
134 
135     QAction*                                    m_action_start_interactive_rendering;
136     QAction*                                    m_action_start_final_rendering;
137     QAction*                                    m_action_pause_resume_rendering;
138     QAction*                                    m_action_stop_rendering;
139     QAction*                                    m_action_rendering_settings;
140     QAction*                                    m_action_fullscreen;
141 
142     std::vector<QAction*>                       m_recently_opened;
143     std::vector<MinimizeButton*>                m_minimize_buttons;
144 
145     StatusBar                                   m_status_bar;
146     std::unique_ptr<QtLogTarget>                m_log_target;
147 
148     renderer::ParamArray                        m_application_settings;
149 
150     std::unique_ptr<ApplicationSettingsWindow>  m_application_settings_window;
151     std::unique_ptr<RenderingSettingsWindow>    m_rendering_settings_window;
152     std::unique_ptr<TestWindow>                 m_test_window;
153     std::unique_ptr<BenchmarkWindow>            m_benchmark_window;
154     std::unique_ptr<FalseColorsWindow>          m_false_colors_window;
155 
156     ProjectManager                              m_project_manager;
157     ProjectExplorer*                            m_project_explorer;
158     QFileSystemWatcher*                         m_project_file_watcher;
159     AttributeEditor*                            m_attribute_editor;
160     RenderingManager                            m_rendering_manager;
161 
162     typedef std::map<std::string, RenderTab*> RenderTabCollection;
163     typedef std::map<std::string, RenderTab::State> RenderTabStateCollection;
164 
165     RenderTabCollection                         m_render_tabs;
166     std::map<int, RenderTab*>                   m_tab_index_to_render_tab;
167     LightPathsTab*                              m_light_paths_tab;
168 
169     struct StateBeforeProjectOpen
170     {
171         bool                                    m_is_rendering;
172         RenderTabStateCollection                m_render_tab_states;
173     };
174 
175     std::unique_ptr<StateBeforeProjectOpen>     m_state_before_project_open;
176 
177     bool                                        m_fullscreen;
178     OCIO::ConstConfigRcPtr                      m_ocio_config;
179 
180     // Menus.
181     void build_menus();
182     void build_override_shading_menu_item();
183     void update_override_shading_menu_item();
184     void build_recent_files_menu();
185     void update_recent_files_menu(const QString& filepath);
186     void update_recent_files_menu(const QStringList& files);
187     void update_pause_resume_checkbox(const bool checked);
188 
189     // Other UI elements.
190     void build_status_bar();
191     void build_toolbar();
192     void build_log_panel();
193     void build_python_console_panel();
194     void build_project_explorer();
195     void build_connections();
196 
197     // UI state management.
198     void update_workspace();
199     void update_project_explorer();
200     void update_window_title();
201     void set_file_widgets_enabled(const bool is_enabled, const RenderingMode rendering_mode);
202     void set_project_explorer_enabled(const bool is_enabled);
203     void set_rendering_widgets_enabled(const bool is_enabled, const RenderingMode rendering_mode);
204     void set_diagnostics_widgets_enabled(const bool is_enabled, const RenderingMode rendering_mode);
205     void save_state_before_project_open();
206     void restore_state_after_project_open();
207 
208     // Render tabs.
209     void recreate_render_tabs();
210     void remove_render_tabs();
211     void add_render_tab(const QString& label);
212     void add_light_paths_tab();
213     void remove_light_paths_tab();
214 
215     // Project file handling.
216     renderer::ParamArray get_project_params(const char* configuration_name) const;
217     bool can_close_project();
218 
219     // Project file monitoring.
220     void enable_project_file_monitoring();
221     void disable_project_file_monitoring();
222     void start_monitoring_project_file();
223     void stop_monitoring_project_file();
224 
225     // Drag-and-drop.
226     void dragEnterEvent(QDragEnterEvent* event) override;
227     void dropEvent(QDropEvent* event) override;
228 
229     // Rendering.
230     void start_rendering(const RenderingMode rendering_mode);
231 
232     // Diagnostics.
233     void apply_false_colors_settings();
234     void apply_post_processing_stage(
235         renderer::PostProcessingStage&  stage,
236         renderer::Frame&                working_frame);
237 
238     // Miscellaneous.
239     void initialize_ocio();
240     void closeEvent(QCloseEvent* event) override;
241 
242   private slots:
243     // Project I/O.
244     void slot_new_project();
245     void slot_open_project();
246     void slot_open_recent();
247     void slot_clear_all_recent_project_files();
248     void slot_clear_recent_missing_project_files();
249     void slot_open_cornellbox_builtin_project();
250     void slot_reload_project();
251     void slot_open_project_complete(const QString& filepath, const bool successful);
252     void slot_save_project();
253     void slot_save_project_as();
254     void slot_pack_project_as();
255     void slot_close_project();
256     void slot_project_modified();
257 
258     // Project file monitoring.
259     void slot_toggle_project_file_monitoring(const bool checked);
260     void slot_project_file_changed(const QString& filepath);
261 
262     // Application settings I/O.
263     void slot_load_application_settings();
264     void slot_save_application_settings();
265     void slot_apply_application_settings();
266 
267     // Rendering.
268     void slot_start_interactive_rendering();
269     void slot_start_final_rendering();
270     void slot_start_rendering_once(
271         const QString&  filepath,
272         const QString&  configuration,
273         const bool      successful);
274     void slot_pause_or_resume_rendering(
275         const bool      checked);
276     void slot_rendering_end();
277     void slot_camera_changed();
278 
279     // Diagnostics.
280     void slot_clear_shading_override();
281     void slot_set_shading_override();
282     void slot_show_false_colors_window();
283     void slot_apply_false_colors_settings_changes(foundation::Dictionary values);
284 
285     // Render region.
286     void slot_clear_render_region();
287     void slot_set_render_region(const QRect& rect);
288 
289     // Render widget actions.
290     void slot_render_widget_context_menu(const QPoint& point);
291     void slot_save_frame();
292     void slot_save_frame_and_aovs();
293     void slot_quicksave_frame_and_aovs();
294     void slot_save_render_widget_content();
295     void slot_clear_frame();
296     void slot_reset_zoom();
297 
298     // Project explorer.
299     void slot_filter_text_changed(const QString& pattern);
300     void slot_clear_filter();
301     void slot_frame_modified();
302 
303     // General UI actions.
304     void slot_fullscreen();
305     void slot_check_fullscreen();
306 
307     // Child windows.
308     void slot_show_application_settings_window();
309     void slot_show_rendering_settings_window();
310     void slot_show_test_window();
311     void slot_show_benchmark_window();
312     void slot_show_about_window();
313 };
314 
315 }   // namespace studio
316 }   // namespace appleseed
317