diff --git a/app/node/CMakeLists.txt b/app/node/CMakeLists.txt index 82920dc0d..c4f9db7f7 100644 --- a/app/node/CMakeLists.txt +++ b/app/node/CMakeLists.txt @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +add_subdirectory(block) add_subdirectory(generator) add_subdirectory(input) add_subdirectory(output) diff --git a/app/node/block/CMakeLists.txt b/app/node/block/CMakeLists.txt new file mode 100644 index 000000000..92a0fca1f --- /dev/null +++ b/app/node/block/CMakeLists.txt @@ -0,0 +1,24 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 Olive Team +# +# 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 . + +#add_subdirectory(image) + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + node/block/block.h + node/block/block.cpp + PARENT_SCOPE +) diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp new file mode 100644 index 000000000..ceacac3a7 --- /dev/null +++ b/app/node/block/block.cpp @@ -0,0 +1,11 @@ +#include "block.h" + +Block::Block() +{ + +} + +QString Block::Category() +{ + return tr("Block"); +} diff --git a/app/node/block/block.h b/app/node/block/block.h new file mode 100644 index 000000000..9f69658d1 --- /dev/null +++ b/app/node/block/block.h @@ -0,0 +1,20 @@ +#ifndef BLOCK_H +#define BLOCK_H + +#include "node/node.h" + +class Block : public Node +{ + Q_OBJECT +public: + Block(); + + virtual QString Category() override; + +public slots: +// virtual void Process(const rational &time) override; + + +}; + +#endif // BLOCK_H diff --git a/app/node/input/CMakeLists.txt b/app/node/input/CMakeLists.txt index 2a8c2fc3a..eca5ea46f 100644 --- a/app/node/input/CMakeLists.txt +++ b/app/node/input/CMakeLists.txt @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -add_subdirectory(image) +add_subdirectory(media) set(OLIVE_SOURCES ${OLIVE_SOURCES} diff --git a/app/node/input/image/CMakeLists.txt b/app/node/input/media/CMakeLists.txt similarity index 93% rename from app/node/input/image/CMakeLists.txt rename to app/node/input/media/CMakeLists.txt index 48e815787..3fed54b7b 100644 --- a/app/node/input/image/CMakeLists.txt +++ b/app/node/input/media/CMakeLists.txt @@ -16,7 +16,7 @@ set(OLIVE_SOURCES ${OLIVE_SOURCES} - node/input/image/image.h - node/input/image/image.cpp + node/input/media/media.h + node/input/media/media.cpp PARENT_SCOPE ) diff --git a/app/node/input/image/image.cpp b/app/node/input/media/media.cpp similarity index 50% rename from app/node/input/image/image.cpp rename to app/node/input/media/media.cpp index e82f30cc4..f1b5a28d4 100644 --- a/app/node/input/image/image.cpp +++ b/app/node/input/media/media.cpp @@ -1,39 +1,43 @@ -#include "image.h" +#include "media.h" -ImageInput::ImageInput() : +MediaInput::MediaInput() : texture_(nullptr) { + footage_input_ = new NodeInput(); + footage_input_->add_data_input(NodeInput::kFootage); + AddParameter(footage_input_); + texture_output_ = new NodeOutput(); texture_output_->set_data_type(NodeOutput::kTexture); AddParameter(texture_output_); } -QString ImageInput::Name() +QString MediaInput::Name() { - return tr("Image"); + return tr("Media"); } -QString ImageInput::id() +QString MediaInput::id() { - return "org.olivevideoeditor.Olive.imageinput"; + return "org.olivevideoeditor.Olive.mediainput"; } -QString ImageInput::Category() +QString MediaInput::Category() { return tr("Input"); } -QString ImageInput::Description() +QString MediaInput::Description() { - return tr("Import an image file."); + return tr("Import a footage stream."); } -NodeOutput *ImageInput::texture_output() +NodeOutput *MediaInput::texture_output() { return texture_output_; } -void ImageInput::Process(const rational &time) +void MediaInput::Process(const rational &time) { // FIXME: Use OIIO and OCIO here diff --git a/app/node/input/image/image.h b/app/node/input/media/media.h similarity index 89% rename from app/node/input/image/image.h rename to app/node/input/media/media.h index b07e1734d..e359ea076 100644 --- a/app/node/input/image/image.h +++ b/app/node/input/media/media.h @@ -11,11 +11,11 @@ * FIXME: This will likely be replaced by the Media node as the Media node will be set up to pull from various decoders * from the beginning. */ -class ImageInput : public Node +class MediaInput : public Node { Q_OBJECT public: - ImageInput(); + MediaInput(); virtual QString Name() override; virtual QString id() override; @@ -28,6 +28,8 @@ public slots: virtual void Process(const rational &time) override; private: + NodeInput* footage_input_; + NodeOutput* texture_output_; QOpenGLTexture* texture_; diff --git a/app/node/param.cpp b/app/node/param.cpp index 4f5939325..a8f294fca 100644 --- a/app/node/param.cpp +++ b/app/node/param.cpp @@ -183,6 +183,7 @@ QString NodeParam::GetDefaultDataTypeName(const DataType& type) case kTexture: return tr("Texture"); case kMatrix: return tr("Matrix"); case kBlock: return tr("Block"); + case kFootage: return tr("Footage"); case kAny: return tr("Any"); } diff --git a/app/node/param.h b/app/node/param.h index eafb32501..819254957 100644 --- a/app/node/param.h +++ b/app/node/param.h @@ -65,6 +65,7 @@ public: kTexture, kMatrix, kBlock, + kFootage, kAny }; diff --git a/app/project/item/item.cpp b/app/project/item/item.cpp index 0105f0f3e..0705a6ac7 100644 --- a/app/project/item/item.cpp +++ b/app/project/item/item.cpp @@ -60,12 +60,12 @@ void Item::remove_child(Item *c) c->parent_ = nullptr; } -int Item::child_count() +int Item::child_count() const { return children_.size(); } -Item *Item::child(int i) +Item *Item::child(int i) const { return children_.at(i).get(); } @@ -116,6 +116,17 @@ Item *Item::parent() const return parent_; } +const Item *Item::root() const +{ + const Item* item = this; + + while (item->parent() != nullptr) { + item = item->parent(); + } + + return item; +} + bool Item::CanHaveChildren() const { return false; diff --git a/app/project/item/item.h b/app/project/item/item.h index ef8da3e33..a7ad340db 100644 --- a/app/project/item/item.h +++ b/app/project/item/item.h @@ -79,8 +79,8 @@ public: void add_child(ItemPtr c); void remove_child(Item* c); - int child_count(); - Item* child(int i); + int child_count() const; + Item* child(int i) const; ItemPtr shared_ptr_from_raw(Item* item); @@ -94,6 +94,7 @@ public: void set_icon(const QIcon& icon); Item *parent() const; + const Item* root() const; virtual bool CanHaveChildren() const; diff --git a/app/ui/style/olive-dark/style.css b/app/ui/style/olive-dark/style.css index a4c14e326..f6dc64880 100644 --- a/app/ui/style/olive-dark/style.css +++ b/app/ui/style/olive-dark/style.css @@ -63,7 +63,7 @@ a { } /* All of these widgets' backgrounds are dark */ -QTreeView, QListView, QLineEdit, QMenu, QProgressBar, QPushButton::checked, NodeView { +QTreeView, QListView, QLineEdit, QMenu, QProgressBar, QPushButton::checked, NodeView, QComboBox { /* Dark */ background: #191919; } diff --git a/app/ui/style/olive-light/style.css b/app/ui/style/olive-light/style.css index b8771d162..29de1db44 100644 --- a/app/ui/style/olive-light/style.css +++ b/app/ui/style/olive-light/style.css @@ -63,7 +63,7 @@ a { } /* All of these widgets' backgrounds are dark */ -QTreeView, QListView, QLineEdit, QMenu, QProgressBar, QPushButton::checked, NodeView { +QTreeView, QListView, QLineEdit, QMenu, QProgressBar, QPushButton::checked, NodeView, QCheckBox { /* Dark */ background: #ffffff; } diff --git a/app/widget/CMakeLists.txt b/app/widget/CMakeLists.txt index 872fe3343..f1e1f87bc 100644 --- a/app/widget/CMakeLists.txt +++ b/app/widget/CMakeLists.txt @@ -15,6 +15,7 @@ # along with this program. If not, see . add_subdirectory(flowlayout) +add_subdirectory(footagecombobox) add_subdirectory(menu) add_subdirectory(nodeview) add_subdirectory(nodeparamview) diff --git a/app/widget/footagecombobox/CMakeLists.txt b/app/widget/footagecombobox/CMakeLists.txt new file mode 100644 index 000000000..e9aab3fcb --- /dev/null +++ b/app/widget/footagecombobox/CMakeLists.txt @@ -0,0 +1,22 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 Olive Team +# +# 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 . + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + widget/footagecombobox/footagecombobox.h + widget/footagecombobox/footagecombobox.cpp + PARENT_SCOPE +) diff --git a/app/widget/footagecombobox/footagecombobox.cpp b/app/widget/footagecombobox/footagecombobox.cpp new file mode 100644 index 000000000..ebeae17d9 --- /dev/null +++ b/app/widget/footagecombobox/footagecombobox.cpp @@ -0,0 +1,59 @@ +#include "footagecombobox.h" + +#include +#include + +FootageComboBox::FootageComboBox(QWidget *parent) : + QComboBox(parent), + root_(nullptr) +{ + +} + +void FootageComboBox::showPopup() +{ + if (root_ == nullptr) { + return; + } + + QMenu menu; + + menu.setMinimumWidth(width()); + + TraverseFolder(root_, &menu); + + QAction* selected = menu.exec(parentWidget()->mapToGlobal(pos())); + + if (selected != nullptr) { + clear(); + + addItem(selected->text()); + + emit FootageChanged(reinterpret_cast(selected->data().value())); + } +} + +void FootageComboBox::SetRoot(const Folder *p) +{ + root_ = p; + + clear(); +} + +void FootageComboBox::TraverseFolder(const Folder *f, QMenu *m) +{ + for (int i=0;ichild_count();i++) { + Item* child = f->child(i); + + if (child->type() == Item::kFolder) { + + TraverseFolder(static_cast(child), m->addMenu(child->name())); + + } else if (child->type() == Item::kFootage) { + + QAction* footage_action = m->addAction(child->name()); + footage_action->setData(reinterpret_cast(child)); + + } + } +} diff --git a/app/widget/footagecombobox/footagecombobox.h b/app/widget/footagecombobox/footagecombobox.h new file mode 100644 index 000000000..8611fb15b --- /dev/null +++ b/app/widget/footagecombobox/footagecombobox.h @@ -0,0 +1,29 @@ +#ifndef FOOTAGECOMBOBOX_H +#define FOOTAGECOMBOBOX_H + +#include +#include + +#include "project/item/footage/footage.h" +#include "project/project.h" + +class FootageComboBox : public QComboBox +{ + Q_OBJECT +public: + FootageComboBox(QWidget* parent = nullptr); + + virtual void showPopup() override; + + void SetRoot(const Folder *p); + +signals: + void FootageChanged(Footage* f); + +private: + void TraverseFolder(const Folder *f, QMenu* m); + + const Folder* root_; +}; + +#endif // FOOTAGECOMBOBOX_H diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index aae5c99b4..a64f6ebf9 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -20,10 +20,20 @@ #include "nodeparamviewitem.h" +#include #include +#include +#include #include +#include "project/item/sequence/sequence.h" #include "ui/icons/icons.h" +#include "widget/footagecombobox/footagecombobox.h" + +// FIXME: Test code only +#include "panel/panelfocusmanager.h" +#include "panel/project/project.h" +// End test code NodeParamViewItem::NodeParamViewItem(QWidget *parent) : QWidget(parent) @@ -107,15 +117,90 @@ void NodeParamViewItem::SetupUI() // This widget only needs to show input parameters if (param->type() == NodeParam::kInput) { + + // Add descriptor label QLabel* param_label = new QLabel(tr("%1:").arg(param->name())); content_layout_->addWidget(param_label, row_count, 0); + // Add widgets for this parameter + QList widgets_for_param = CreateWidget(static_cast(param)); + for (int i=0;iaddWidget(widgets_for_param.at(i), row_count, i + 1); + } + row_count++; } } } +QList NodeParamViewItem::CreateWidget(NodeInput* input) +{ + QList widgets; + + if (input->inputs().isEmpty()) { + return widgets; + } + + switch (input->inputs().first()) { + case NodeParam::kNone: + case NodeParam::kAny: + case NodeParam::kBlock: + case NodeParam::kTexture: + case NodeParam::kMatrix: + break; + case NodeParam::kInt: + // FIXME: LabelSlider in INTEGER mode + break; + case NodeParam::kFloat: + // FIXME: LabelSlider in FLOAT mode + break; + case NodeParam::kFile: + // FIXME: File selector + break; + case NodeParam::kColor: + // FIXME: Color selector + break; + case NodeParam::kString: + { + QLineEdit* line_edit = new QLineEdit(); + widgets.append(line_edit); + } + break; + case NodeParam::kBoolean: + { + QCheckBox* check_box = new QCheckBox(); + widgets.append(check_box); + } + break; + case NodeParam::kFont: + { + QFontComboBox* font_combobox = new QFontComboBox(); + widgets.append(font_combobox); + } + break; + case NodeParam::kFootage: + { + FootageComboBox* footage_combobox = new FootageComboBox(); + + // FIXME: Test code + ProjectPanel* pp = olive::panel_focus_manager->MostRecentlyFocused(); + footage_combobox->SetRoot(pp->project()->root()); + // End test code + + + // Pretty hacky way of getting the root folder for this node's sequence + //const Folder* root_folder = static_cast(static_cast(input->parent()->parent())->root()); + //footage_combobox->SetRoot(root_folder); + + widgets.append(footage_combobox); + } + break; + } + + return widgets; +} + void NodeParamViewItem::SetExpanded(bool e) { expanded_ = e; diff --git a/app/widget/nodeparamview/nodeparamviewitem.h b/app/widget/nodeparamview/nodeparamviewitem.h index dbddf7ddf..e2cb3f5bb 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.h +++ b/app/widget/nodeparamview/nodeparamviewitem.h @@ -53,6 +53,8 @@ protected: private: void SetupUI(); + QList CreateWidget(NodeInput *input); + bool expanded_; NodeParamViewItemTitleBar* title_bar_; diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 32ccbbf0a..558c3a9bb 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -34,7 +34,7 @@ #include "mainmenu.h" // FIXME: Test code -#include "node/input/image/image.h" +#include "node/input/media/media.h" #include "node/output/viewer/viewer.h" #include "node/generator/solid/solid.h" // End test code @@ -96,7 +96,7 @@ void olive::MainWindow::ProjectOpen(Project* p) SolidGenerator* sg = new SolidGenerator(); NodeInput::ConnectEdge(sg->texture_output(), vo->texture_input()); graph->AddNode(sg); - ImageInput* ii = new ImageInput(); + MediaInput* ii = new MediaInput(); graph->AddNode(ii); node_panel->SetGraph(graph); // End test code