1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "edit3dwidget.h"
27 #include "edit3dview.h"
28 #include "edit3dcanvas.h"
29 #include "edit3dactions.h"
30
31 #include "qmldesignerplugin.h"
32 #include "designersettings.h"
33 #include "qmldesignerconstants.h"
34 #include "viewmanager.h"
35
36 #include <coreplugin/actionmanager/actionmanager.h>
37 #include <coreplugin/actionmanager/command.h>
38 #include <coreplugin/icore.h>
39 #include <toolbox.h>
40 #include <utils/utilsicons.h>
41
42 #include <QActionGroup>
43 #include <QVBoxLayout>
44
45 namespace QmlDesigner {
46
Edit3DWidget(Edit3DView * view)47 Edit3DWidget::Edit3DWidget(Edit3DView *view) :
48 m_view(view)
49 {
50 Core::Context context(Constants::C_QMLEDITOR3D);
51 m_context = new Core::IContext(this);
52 m_context->setContext(context);
53 m_context->setWidget(this);
54
55 setMouseTracking(true);
56 setFocusPolicy(Qt::WheelFocus);
57
58 auto fillLayout = new QVBoxLayout(this);
59 fillLayout->setContentsMargins(0, 0, 0, 0);
60 fillLayout->setSpacing(0);
61 setLayout(fillLayout);
62
63 // Initialize toolbar
64 m_toolBox = new ToolBox(this);
65 fillLayout->addWidget(m_toolBox.data());
66
67 // Iterate through view actions. A null action indicates a separator and a second null action
68 // after separator indicates an exclusive group.
69 auto addActionsToToolBox = [this, &context](const QVector<Edit3DAction *> &actions, bool left) {
70 bool previousWasSeparator = true;
71 QActionGroup *group = nullptr;
72 for (auto action : actions) {
73 if (action) {
74 if (group)
75 group->addAction(action->action());
76 addAction(action->action());
77 if (left)
78 m_toolBox->addLeftSideAction(action->action());
79 else
80 m_toolBox->addRightSideAction(action->action());
81 previousWasSeparator = false;
82
83 // Register action as creator command to make it configurable
84 Core::Command *command = Core::ActionManager::registerAction(
85 action->action(), action->menuId().constData(), context);
86 command->setDefaultKeySequence(action->action()->shortcut());
87 command->augmentActionWithShortcutToolTip(action->action());
88 // Clear action shortcut so it doesn't conflict with command's override action
89 action->action()->setShortcut({});
90 } else {
91 if (previousWasSeparator) {
92 group = new QActionGroup(this);
93 previousWasSeparator = false;
94 } else {
95 group = nullptr;
96 auto separator = new QAction(this);
97 separator->setSeparator(true);
98 addAction(separator);
99 m_toolBox->addLeftSideAction(separator);
100 previousWasSeparator = true;
101 }
102 }
103 }
104 };
105 addActionsToToolBox(view->leftActions(), true);
106 addActionsToToolBox(view->rightActions(), false);
107
108 // Onboarding label contains instructions for new users how to get 3D content into the project
109 m_onboardingLabel = new QLabel(this);
110 QString labelText =
111 tr("Your file does not import Qt Quick 3D.<br><br>"
112 "To create a 3D view, add the QtQuick3D module in the Library view. Or click"
113 " <a href=\"#add_import\"><span style=\"text-decoration:none;color:%1\">here</span></a> "
114 "here to add it immediately.<br><br>"
115 "To import 3D assets from another tool, click the \"Add New Assets...\" button in the Assets tab of the Library view.");
116 m_onboardingLabel->setText(labelText.arg(Utils::creatorTheme()->color(Utils::Theme::TextColorLink).name()));
117 m_onboardingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
118 connect(m_onboardingLabel, &QLabel::linkActivated, this, &Edit3DWidget::linkActivated);
119 fillLayout->addWidget(m_onboardingLabel.data());
120
121 // Canvas is used to render the actual edit 3d view
122 m_canvas = new Edit3DCanvas(this);
123 fillLayout->addWidget(m_canvas.data());
124 showCanvas(false);
125 }
126
contextHelp(const Core::IContext::HelpCallback & callback) const127 void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
128 {
129 if (m_view)
130 m_view->contextHelp(callback);
131
132 callback({});
133 }
134
showCanvas(bool show)135 void Edit3DWidget::showCanvas(bool show)
136 {
137 if (!show) {
138 QImage emptyImage;
139 m_canvas->updateRenderImage(emptyImage);
140 }
141 m_canvas->setVisible(show);
142 m_onboardingLabel->setVisible(!show);
143 }
144
linkActivated(const QString & link)145 void Edit3DWidget::linkActivated(const QString &link)
146 {
147 Q_UNUSED(link)
148 if (m_view)
149 m_view->addQuick3DImport();
150 }
151
canvas() const152 Edit3DCanvas *Edit3DWidget::canvas() const
153 {
154 return m_canvas.data();
155 }
156
view() const157 Edit3DView *Edit3DWidget::view() const
158 {
159 return m_view.data();
160 }
161
162 }
163