diff --git a/src/lib/core/view/FixedTabWidget.cpp b/src/lib/core/view/FixedTabWidget.cpp index fdfe3885ba..bdbafaafca 100644 --- a/src/lib/core/view/FixedTabWidget.cpp +++ b/src/lib/core/view/FixedTabWidget.cpp @@ -18,8 +18,9 @@ namespace score FixedTabWidget::FixedTabWidget() noexcept : m_buttons{new QToolBar} { - m_layout.setContentsMargins(10, 10, 10, 10); - m_layout.setSpacing(6); + setContentsMargins(0, 0, 0, 0); + m_layout.setContentsMargins(0, 0, 0, 0); + m_layout.setSpacing(1); this->setLayout(&m_layout); auto layout = new score::MarginLess; @@ -97,16 +98,43 @@ struct DragOverToolButton final : public QToolButton int m_tm = 0; }; -std::pair FixedTabWidget::addTab(QWidget* widg, const PanelStatus& v) +std::pair +FixedTabWidget::addTab(QWidget* widg, const PanelStatus& v, int index) { - int idx = m_stack.addWidget(widg); + int idx = index >= 0 ? m_stack.insertWidget(index, widg) : m_stack.addWidget(widg); auto bbtn = new DragOverToolButton{}; bbtn->setAutoRaise(true); bbtn->setFocusPolicy(Qt::NoFocus); bbtn->setIconSize(m_buttons->iconSize()); - auto btn = m_buttons->addWidget(bbtn); + QAction* btn{}; + if(index < 0) + { + btn = m_buttons->addWidget(bbtn); + } + else + { + const auto& acts = m_buttons->actions(); + int k = 0; + QAction* before{}; + for(QAction* act : acts) + { + if(k++ == index) + { + before = act; + break; + } + } + if(before) + { + btn = m_buttons->insertWidget(before, bbtn); + } + else + { + btn = m_buttons->addWidget(bbtn); + } + } bbtn->setDefaultAction(btn); btn->setIcon(v.icon); btn->setText(v.prettyName); @@ -121,8 +149,8 @@ std::pair FixedTabWidget::addTab(QWidget* widg, const PanelStatus btn->setWhatsThis(widg->whatsThis()); btn->setStatusTip(widg->statusTip()); - connect(btn, &QAction::triggered, &m_stack, [this, btn, idx](bool checked) { - m_stack.setCurrentIndex(idx); + connect(btn, &QAction::triggered, &m_stack, [this, btn, widg](bool checked) { + m_stack.setCurrentWidget(widg); actionTriggered(btn, checked); }); diff --git a/src/lib/core/view/FixedTabWidget.hpp b/src/lib/core/view/FixedTabWidget.hpp index ae122ebea7..0412f014f3 100644 --- a/src/lib/core/view/FixedTabWidget.hpp +++ b/src/lib/core/view/FixedTabWidget.hpp @@ -14,7 +14,7 @@ class QActionGroup; namespace score { -class FixedTabWidget : public QWidget +class SCORE_LIB_BASE_EXPORT FixedTabWidget : public QWidget { W_OBJECT(FixedTabWidget) public: @@ -25,7 +25,8 @@ class FixedTabWidget : public QWidget QSize sizeHint() const override; void setTab(int index); - std::pair addTab(QWidget* widg, const score::PanelStatus& v); + std::pair + addTab(QWidget* widg, const score::PanelStatus& v, int index = -1); QAction* addAction(QWidget* widg, const PanelStatus& v); QAction* addAction(QAction* act); diff --git a/src/lib/core/view/ScriptPanelDelegate.hpp b/src/lib/core/view/ScriptPanelDelegate.hpp new file mode 100644 index 0000000000..3cc2d3bb94 --- /dev/null +++ b/src/lib/core/view/ScriptPanelDelegate.hpp @@ -0,0 +1,30 @@ +#pragma once +#include + +#include +#include + +namespace score +{ + +class ScriptPanelDelegate : public PanelDelegate +{ +public: + ScriptPanelDelegate(const score::GUIApplicationContext& ctx) + : PanelDelegate{ctx} + { + widg = new QWidget; + } + + QWidget* widget() override { return widg; } + + const PanelStatus& defaultPanelStatus() const override + { + static const PanelStatus stat{ + false, true, Qt::RightDockWidgetArea, -100000, + "Script", "script", QKeySequence("Ctrl+Shift+S")}; + return stat; + } + QWidget* widg{}; +}; +} diff --git a/src/lib/core/view/Window.cpp b/src/lib/core/view/Window.cpp index 511c5d12df..3cc32813af 100644 --- a/src/lib/core/view/Window.cpp +++ b/src/lib/core/view/Window.cpp @@ -154,15 +154,17 @@ View::View(QObject* parent) topleftToolbar = new QWidget; topleftToolbar->setLayout(new score::MarginLess); - auto leftLabel = new TitleBar; - leftTabs = new FixedTabWidget; - connect(leftTabs, &FixedTabWidget::actionTriggered, this, [=](QAction* act, bool b) { - leftLabel->setText(act->iconText()); - }); - ((QVBoxLayout*)leftTabs->layout())->insertWidget(0, topleftToolbar); - ((QVBoxLayout*)leftTabs->layout())->insertWidget(1, leftLabel); - rightSplitter = new RectSplitter{Qt::Vertical}; + { + auto leftLabel = new TitleBar; + leftTabs = new FixedTabWidget; + connect(leftTabs, &FixedTabWidget::actionTriggered, this, [=](QAction* act, bool b) { + leftLabel->setText(act->iconText()); + }); + ((QVBoxLayout*)leftTabs->layout())->insertWidget(0, topleftToolbar); + ((QVBoxLayout*)leftTabs->layout())->insertWidget(1, leftLabel); + } + auto rect = QGuiApplication::primaryScreen()->availableGeometry(); this->resize( static_cast(rect.width() * 0.75), static_cast(rect.height() * 0.75)); @@ -230,7 +232,20 @@ View::View(QObject* parent) } }); } - totalWidg->addWidget(rightSplitter); + + { + auto rightLabel = new TitleBar; + rightTabs = new FixedTabWidget; + + rightSplitter = new RectSplitter{Qt::Vertical}; + rightSplitter->setContentsMargins(0, 0, 0, 0); + + connect( + rightTabs, &FixedTabWidget::actionTriggered, this, + [=](QAction* act, bool b) { rightLabel->setText(act->iconText()); }); + ((QVBoxLayout*)rightTabs->layout())->insertWidget(0, rightLabel); + } + totalWidg->addWidget(rightTabs); setCentralWidget(totalWidg); connect( @@ -302,7 +317,24 @@ void View::setupPanel(PanelDelegate* v) break; } case Qt::RightDockWidgetArea: { - rightSplitter->insertWidget(0, w); + auto status = v->defaultPanelStatus(); + if(status.prettyName == QObject::tr("Inspector")) + { + inspectorPanel = v; + } + else if(status.prettyName == QObject::tr("Objects")) + { + objectPanel = v; + } + else if(status.prettyName == QObject::tr("Info")) + { + infoPanel = v; + } + else + { + auto [idx, act] = rightTabs->addTab(w, v->defaultPanelStatus()); + toggle = act; + } break; } @@ -331,38 +363,57 @@ void View::setupPanel(PanelDelegate* v) void View::allPanelsAdded() { auto splitter = (RectSplitter*)centralWidget(); + std::map inspectorPanels; for(auto& panel : score::GUIAppContext().panels()) { - if(panel.defaultPanelStatus().prettyName == QObject::tr("Inspector")) + // rightTabs->addTab(panel.widget(), panel.defaultPanelStatus()); + //rightSplitter->insertWidget(1, panel.widget()); + + // auto act + // = bottomTabs->addAction(rightSplitter->widget(1), panel.defaultPanelStatus()); + // bottomTabs->actionGroup()->removeAction(act); + // act->setChecked(true); + // connect(act, &QAction::toggled, this, [splitter](bool ok) { + // QList sz = splitter->sizes(); + // if(ok) + // { + // if(sz[2] <= 1) + // { + // sz[2] = 200; + // splitter->setSizes(sz); + // } + // } + // else + // { + // sz[2] = 0; + // splitter->setSizes(sz); + // } + // }); + } + + rightSplitter->addWidget(objectPanel->widget()); + rightSplitter->addWidget(inspectorPanel->widget()); + rightSplitter->addWidget(infoPanel->widget()); + { + auto [idx, toggle] + = rightTabs->addTab(rightSplitter, inspectorPanel->defaultPanelStatus(), 0); + + if(toggle) { - rightSplitter->insertWidget(1, panel.widget()); - - auto act - = bottomTabs->addAction(rightSplitter->widget(1), panel.defaultPanelStatus()); - bottomTabs->actionGroup()->removeAction(act); - act->setChecked(true); - connect(act, &QAction::toggled, this, [splitter](bool ok) { - QList sz = splitter->sizes(); - if(ok) - { - if(sz[2] <= 1) - { - sz[2] = 200; - splitter->setSizes(sz); - } - } - else - { - sz[2] = 0; - splitter->setSizes(sz); - } - }); - break; + auto& mw = inspectorPanel->context().menus.get().at(score::Menus::Windows()); + addAction(toggle); + mw.menu()->addAction(toggle); + + // Maybe show the panel + if(inspectorPanel->defaultPanelStatus().shown) + toggle->toggle(); } } // Show the device explorer first leftTabs->toolbar()->actions().front()->trigger(); + // Show the inspector first + rightTabs->toolbar()->actions().front()->trigger(); QTimer::singleShot(100, this, [=] { int w = splitter->width(); { diff --git a/src/lib/core/view/Window.hpp b/src/lib/core/view/Window.hpp index 20948b92c5..9c2ef0b69b 100644 --- a/src/lib/core/view/Window.hpp +++ b/src/lib/core/view/Window.hpp @@ -72,12 +72,19 @@ class SCORE_LIB_BASE_EXPORT View final : public QMainWindow QWidget* centralDocumentWidget{}; QSplitter* rightSplitter{}; QWidget* topleftToolbar{}; + QWidget* topRightToolbar{}; FixedTabWidget* leftTabs{}; + FixedTabWidget* rightTabs{}; // QTabWidget* rightTabs{}; FixedTabWidget* bottomTabs{}; QTabWidget* centralTabs{}; QWidget* transportBar{}; + PanelDelegate* objectPanel{}; + PanelDelegate* inspectorPanel{}; + PanelDelegate* infoPanel{}; + PanelDelegate* scriptPanel{}; + private: bool event(QEvent* event) override; void changeEvent(QEvent*) override; diff --git a/src/plugins/score-lib-process/Effect/EffectLayer.cpp b/src/plugins/score-lib-process/Effect/EffectLayer.cpp index 7bbd134f6f..16e640fdad 100644 --- a/src/plugins/score-lib-process/Effect/EffectLayer.cpp +++ b/src/plugins/score-lib-process/Effect/EffectLayer.cpp @@ -1,5 +1,10 @@ #include "EffectLayer.hpp" +#include "core/view/FixedTabWidget.hpp" +#include "core/view/Window.hpp" +#include "score/actions/MenuManager.hpp" +#include "score/plugins/panel/PanelDelegate.hpp" + #include #include #include @@ -17,10 +22,12 @@ #include #include +#include #include #include +#include #include W_OBJECT_IMPL(Process::EffectLayerPresenter) @@ -123,14 +130,36 @@ void setupScriptUI( if(auto win = fact.makeScriptUI(proc, ctx, nullptr)) { const_cast(proc.scriptUI) = win; - win->show(); + + if(auto score_view = static_cast(score::GUIAppContext().mainWindow)) + { + auto [idx, toggle] = score_view->rightTabs->addTab( + win, score::PanelStatus{ + false, true, Qt::RightDockWidgetArea, -100000, proc.prettyName(), + "script", QKeySequence{}}); + + auto& mw = ctx.app.menus.get().at(score::Menus::Windows()); + score_view->addAction(toggle); + mw.menu()->addAction(toggle); + toggle->toggle(); + + score_view->rightTabs->toolbar()->actions().back()->trigger(); + + QObject::connect( + win, &QWidget::destroyed, score_view, [&ctx, score_view, toggle] { + auto& mw = ctx.app.menus.get().at(score::Menus::Windows()); + mw.menu()->removeAction(toggle); + score_view->removeAction(toggle); + score_view->rightTabs->toolbar()->removeAction(toggle); + score_view->rightTabs->toolbar()->actions().front()->trigger(); + }); + } } } else { if(auto win = proc.scriptUI) { - win->close(); delete win; const_cast(proc.scriptUI) = nullptr; } diff --git a/src/plugins/score-plugin-gfx/Gfx/Filter/Process.cpp b/src/plugins/score-plugin-gfx/Gfx/Filter/Process.cpp index a1737472bd..5dd85036b5 100644 --- a/src/plugins/score-plugin-gfx/Gfx/Filter/Process.cpp +++ b/src/plugins/score-plugin-gfx/Gfx/Filter/Process.cpp @@ -176,11 +176,6 @@ Process::Preset Model::savePreset() const noexcept return p; } -QString Model::prettyName() const noexcept -{ - return tr("GFX Filter"); -} - Process::Descriptor ProcessFactory::descriptor(QString path) const noexcept { return ISFHelpers::descriptorFromISFFile(path); diff --git a/src/plugins/score-plugin-gfx/Gfx/Filter/Process.hpp b/src/plugins/score-plugin-gfx/Gfx/Filter/Process.hpp index a6e04b48c2..2d34084b84 100644 --- a/src/plugins/score-plugin-gfx/Gfx/Filter/Process.hpp +++ b/src/plugins/score-plugin-gfx/Gfx/Filter/Process.hpp @@ -69,7 +69,6 @@ class Model final : public Process::ProcessModel private: void loadPreset(const Process::Preset& preset) override; Process::Preset savePreset() const noexcept override; - QString prettyName() const noexcept override; ShaderSource m_program; ProcessedProgram m_processedProgram; diff --git a/src/plugins/score-plugin-js/JS/ConsolePanel.cpp b/src/plugins/score-plugin-js/JS/ConsolePanel.cpp index 64daab87bf..73c600b267 100644 --- a/src/plugins/score-plugin-js/JS/ConsolePanel.cpp +++ b/src/plugins/score-plugin-js/JS/ConsolePanel.cpp @@ -209,7 +209,7 @@ const score::PanelStatus& PanelDelegate::defaultPanelStatus() const static const score::PanelStatus status{ false, false, - Qt::BottomDockWidgetArea, + Qt::RightDockWidgetArea, 0, QObject::tr("Console"), "console",