refactor: invert the last engine-to-UI dependencies
- NodeFactory's menu creation moves to UI-side widget/menu/factorymenu (the factory only exposes its node library read-only now) - DiskManager's cache-settings dialog is created through a registered std::function handler (registered by Core at startup) - OlivePluginInstance creates progress UIs through a PluginProgressReporter interface (Null fallback headless) and queries the active viewer through a provider callback, both registered by Core - factory.h, diskmanager and pluginSupport no longer reference any widget//dialog//panel//window headers or classes
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/menu/factorymenu.cpp
|
||||
widget/menu/factorymenu.h
|
||||
widget/menu/menu.cpp
|
||||
widget/menu/menu.h
|
||||
widget/menu/menushared.cpp
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "factorymenu.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
Menu *create_node_menu(QWidget *parent, bool create_none_item,
|
||||
Node::CategoryID restrict_to, uint64_t restrict_flags)
|
||||
{
|
||||
const QList<Node *> &library = NodeFactory::get_library();
|
||||
|
||||
Menu *menu = new Menu(parent);
|
||||
menu->setToolTipsVisible(true);
|
||||
|
||||
for (int i = 0; i < library.size(); i++) {
|
||||
Node *n = library.at(i);
|
||||
|
||||
if (restrict_to != Node::k_category_unknown &&
|
||||
!n->category().contains(restrict_to)) {
|
||||
// Skip this node
|
||||
continue;
|
||||
}
|
||||
|
||||
if (restrict_flags && !(n->get_flags() & restrict_flags)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n->get_flags() & Node::k_dont_show_in_create_menu) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure nodes are up-to-date with the current translation
|
||||
n->retranslate();
|
||||
|
||||
QString category_name = Node::get_category_name(
|
||||
n->category().isEmpty() ? Node::k_category_unknown :
|
||||
n->category().first());
|
||||
|
||||
// Find or create top-level category menu
|
||||
Menu *top_menu = nullptr;
|
||||
QList<QAction *> menu_actions = menu->actions();
|
||||
foreach (QAction *action, menu_actions) {
|
||||
if (action->menu() && action->menu()->title() == category_name) {
|
||||
top_menu = static_cast<Menu *>(action->menu());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!top_menu) {
|
||||
top_menu = new Menu(category_name, menu);
|
||||
menu->insert_alphabetically(top_menu);
|
||||
}
|
||||
|
||||
// Determine final destination (support secondary grouping)
|
||||
Menu *destination = top_menu;
|
||||
QString sub = n->sub_category();
|
||||
if (!sub.isEmpty() && n->category().contains(Node::k_category_open_fx)) {
|
||||
QList<QAction *> sub_actions = top_menu->actions();
|
||||
foreach (QAction *action, sub_actions) {
|
||||
if (action->menu() && action->menu()->title() == sub) {
|
||||
destination = static_cast<Menu *>(action->menu());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (destination == top_menu) {
|
||||
destination = new Menu(sub, top_menu);
|
||||
top_menu->insert_alphabetically(destination);
|
||||
}
|
||||
}
|
||||
|
||||
// Add entry to menu
|
||||
QAction *a = destination->insert_alphabetically(n->name());
|
||||
a->setData(i);
|
||||
a->setToolTip(n->description());
|
||||
}
|
||||
|
||||
if (create_none_item) {
|
||||
QAction *none_item = new QAction(
|
||||
QCoreApplication::translate("NodeFactory", "None"), menu);
|
||||
|
||||
none_item->setData(-1);
|
||||
|
||||
if (menu->actions().isEmpty()) {
|
||||
menu->addAction(none_item);
|
||||
} else {
|
||||
QAction *separator = menu->insertSeparator(menu->actions().first());
|
||||
menu->insertAction(separator, none_item);
|
||||
}
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
Node *create_node_from_menu_action(QAction *action)
|
||||
{
|
||||
int index = action->data().toInt();
|
||||
|
||||
if (index == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return NodeFactory::get_library().at(index)->copy();
|
||||
}
|
||||
|
||||
QString get_node_id_from_menu_action(QAction *action)
|
||||
{
|
||||
int index = action->data().toInt();
|
||||
|
||||
if (index == -1) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return NodeFactory::get_library().at(action->data().toInt())->id();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2022 Olive Team
|
||||
Modifications Copyright (C) 2025 mikesolar
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef OAK_FACTORYMENU_H
|
||||
#define OAK_FACTORYMENU_H
|
||||
|
||||
#include <QAction>
|
||||
|
||||
#include "node/factory.h"
|
||||
#include "widget/menu/menu.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Create a menu of all available nodes, grouped by category
|
||||
*
|
||||
* UI-side counterpart of the node library: NodeFactory stays UI-independent
|
||||
* while this builds an olive::Menu from NodeFactory::get_library(). Each
|
||||
* leaf action carries the node's library index in its data, so it can be
|
||||
* resolved back with create_node_from_menu_action() or
|
||||
* get_node_id_from_menu_action().
|
||||
*/
|
||||
Menu *create_node_menu(QWidget *parent, bool create_none_item = false,
|
||||
Node::CategoryID restrict_to = Node::k_category_unknown,
|
||||
uint64_t restrict_flags = 0);
|
||||
|
||||
/**
|
||||
* @brief Create a node from an action of a menu built by create_node_menu()
|
||||
*
|
||||
* Returns nullptr for the "None" item.
|
||||
*/
|
||||
Node *create_node_from_menu_action(QAction *action);
|
||||
|
||||
/**
|
||||
* @brief Get the node ID from an action of a menu built by create_node_menu()
|
||||
*
|
||||
* Returns an empty string for the "None" item.
|
||||
*/
|
||||
QString get_node_id_from_menu_action(QAction *action);
|
||||
|
||||
}
|
||||
|
||||
#endif // OAK_FACTORYMENU_H
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "node/factory.h"
|
||||
#include "ui/icons/icons.h"
|
||||
#include "widget/menu/factorymenu.h"
|
||||
#include "widget/menu/menu.h"
|
||||
|
||||
namespace olive
|
||||
@@ -39,12 +40,12 @@ NodeComboBox::NodeComboBox(QWidget *parent)
|
||||
|
||||
void NodeComboBox::showPopup()
|
||||
{
|
||||
Menu *m = NodeFactory::create_menu(this, true);
|
||||
Menu *m = create_node_menu(this, true);
|
||||
|
||||
QAction *selected = m->exec(parentWidget()->mapToGlobal(pos()));
|
||||
|
||||
if (selected) {
|
||||
QString new_id = NodeFactory::GetIDFromMenuAction(selected);
|
||||
QString new_id = get_node_id_from_menu_action(selected);
|
||||
|
||||
set_node_internal(new_id, true);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "node/block/clip/clip.h"
|
||||
#include "node/factory.h"
|
||||
#include "node/nodeundo.h"
|
||||
#include "widget/menu/factorymenu.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -147,7 +147,7 @@ void NodeParamViewContext::add_effect_button_clicked()
|
||||
}
|
||||
|
||||
Menu *m =
|
||||
NodeFactory::create_menu(this, false, Node::k_category_unknown, flag);
|
||||
create_node_menu(this, false, Node::k_category_unknown, flag);
|
||||
connect(m, &Menu::triggered, this,
|
||||
&NodeParamViewContext::add_effect_menu_item_triggered);
|
||||
m->exec(QCursor::pos());
|
||||
@@ -156,7 +156,7 @@ void NodeParamViewContext::add_effect_button_clicked()
|
||||
|
||||
void NodeParamViewContext::add_effect_menu_item_triggered(QAction *a)
|
||||
{
|
||||
Node *n = NodeFactory::CreateFromMenuAction(a);
|
||||
Node *n = create_node_from_menu_action(a);
|
||||
|
||||
if (n) {
|
||||
NodeInput new_node_input = n->get_effect_input();
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
|
||||
#include "node/audio/volume/volume.h"
|
||||
#include "node/distort/transform/transformdistortnode.h"
|
||||
#include "node/factory.h"
|
||||
#include "node/group/group.h"
|
||||
#include "node/nodeundo.h"
|
||||
#include "node/project/serializer/serializer.h"
|
||||
#include "panel/panelmanager.h"
|
||||
#include "node/traverser.h"
|
||||
#include "ui/icons/icons.h"
|
||||
#include "widget/menu/factorymenu.h"
|
||||
#include "widget/menu/menushared.h"
|
||||
#include "widget/timebased/timebasedview.h"
|
||||
|
||||
@@ -936,7 +936,7 @@ void NodeView::show_context_menu(const QPoint &pos)
|
||||
|
||||
void NodeView::create_node_slot(QAction *action)
|
||||
{
|
||||
Node *new_node = NodeFactory::CreateFromMenuAction(action);
|
||||
Node *new_node = create_node_from_menu_action(action);
|
||||
|
||||
if (new_node) {
|
||||
NodeViewItem *new_item = new NodeViewItem(new_node, nullptr);
|
||||
@@ -1381,7 +1381,7 @@ bool NodeView::get_assumed_position_for_selected_node(Node *node,
|
||||
|
||||
Menu *NodeView::create_add_menu(Menu *parent)
|
||||
{
|
||||
Menu *add_menu = NodeFactory::create_menu(parent);
|
||||
Menu *add_menu = create_node_menu(parent);
|
||||
add_menu->setTitle(tr("Add"));
|
||||
connect(add_menu, &Menu::triggered, this, &NodeView::create_node_slot);
|
||||
return add_menu;
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#include <QResizeEvent>
|
||||
#include <QVariant>
|
||||
|
||||
#include "node/factory.h"
|
||||
#include "ui/icons/icons.h"
|
||||
#include "widget/menu/factorymenu.h"
|
||||
#include "widget/menu/menu.h"
|
||||
#include "widget/menu/menushared.h"
|
||||
|
||||
@@ -206,7 +206,7 @@ void Toolbar::add_button_clicked()
|
||||
|
||||
void Toolbar::transition_button_clicked()
|
||||
{
|
||||
Menu *m = NodeFactory::create_menu(this, false, Node::k_category_transition);
|
||||
Menu *m = create_node_menu(this, false, Node::k_category_transition);
|
||||
|
||||
connect(m, &QMenu::triggered, this, &Toolbar::transition_menu_item_triggered);
|
||||
|
||||
@@ -217,7 +217,7 @@ void Toolbar::transition_button_clicked()
|
||||
|
||||
void Toolbar::transition_menu_item_triggered(QAction *a)
|
||||
{
|
||||
emit selected_transition_changed(NodeFactory::GetIDFromMenuAction(a));
|
||||
emit selected_transition_changed(get_node_id_from_menu_action(a));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user