diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 4d2430e30..3b54fcdb2 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -458,6 +458,7 @@ bool FFmpegDecoder::Probe(Footage *f, const QAtomicInt* cancelled) video_stream->set_width(avstream->codecpar->width); video_stream->set_height(avstream->codecpar->height); + video_stream->set_format(GetNativePixelFormat(FFmpegCommon::GetCompatiblePixelFormat(static_cast(avstream->codecpar->format)))); video_stream->set_frame_rate(av_guess_frame_rate(fmt_ctx, avstream, nullptr)); video_stream->set_start_time(avstream->start_time); diff --git a/app/codec/oiio/oiiodecoder.cpp b/app/codec/oiio/oiiodecoder.cpp index e5f7b74c8..6d0804267 100644 --- a/app/codec/oiio/oiiodecoder.cpp +++ b/app/codec/oiio/oiiodecoder.cpp @@ -117,6 +117,7 @@ bool OIIODecoder::Probe(Footage *f, const QAtomicInt *cancelled) image_stream->set_width(in->spec().width); image_stream->set_height(in->spec().height); + image_stream->set_format(GetFormatFromOIIOBasetype(in->spec())); // Images will always have just one stream image_stream->set_index(0); @@ -278,6 +279,23 @@ void OIIODecoder::BufferToFrame(OIIO::ImageBuf *buf, FramePtr frame) #endif } +PixelFormat::Format OIIODecoder::GetFormatFromOIIOBasetype(const OIIO::ImageSpec& spec) +{ + bool has_alpha = (spec.nchannels == kRGBAChannels); + + if (spec.format == OIIO::TypeDesc::UINT8) { + return has_alpha ? PixelFormat::PIX_FMT_RGBA8 : PixelFormat::PIX_FMT_RGB8; + } else if (spec.format == OIIO::TypeDesc::UINT16) { + return has_alpha ? PixelFormat::PIX_FMT_RGBA16U : PixelFormat::PIX_FMT_RGB16U; + } else if (spec.format == OIIO::TypeDesc::HALF) { + return has_alpha ? PixelFormat::PIX_FMT_RGBA16F : PixelFormat::PIX_FMT_RGB16F; + } else if (spec.format == OIIO::TypeDesc::FLOAT) { + return has_alpha ? PixelFormat::PIX_FMT_RGBA32F : PixelFormat::PIX_FMT_RGB32F; + } else { + return PixelFormat::PIX_FMT_INVALID; + } +} + bool OIIODecoder::FileTypeIsSupported(const QString& fn) { // We prioritize OIIO over FFmpeg to pick up still images more effectively, but some OIIO decoders (notably OpenJPEG) @@ -361,16 +379,9 @@ bool OIIODecoder::OpenImageHandler(const QString &fn) is_rgba_ = (spec.nchannels == kRGBAChannels); - // Weirdly, switch statement doesn't work correctly here - if (spec.format == OIIO::TypeDesc::UINT8) { - pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA8 : PixelFormat::PIX_FMT_RGB8; - } else if (spec.format == OIIO::TypeDesc::UINT16) { - pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA16U : PixelFormat::PIX_FMT_RGB16U; - } else if (spec.format == OIIO::TypeDesc::HALF) { - pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA16F : PixelFormat::PIX_FMT_RGB16F; - } else if (spec.format == OIIO::TypeDesc::FLOAT) { - pix_fmt_ = is_rgba_ ? PixelFormat::PIX_FMT_RGBA32F : PixelFormat::PIX_FMT_RGB32F; - } else { + pix_fmt_ = GetFormatFromOIIOBasetype(spec.format); + + if (pix_fmt_ == PixelFormat::PIX_FMT_INVALID) { qWarning() << "Failed to convert OIIO::ImageDesc to native pixel format"; return false; } diff --git a/app/codec/oiio/oiiodecoder.h b/app/codec/oiio/oiiodecoder.h index f481481b1..990fc3aff 100644 --- a/app/codec/oiio/oiiodecoder.h +++ b/app/codec/oiio/oiiodecoder.h @@ -57,6 +57,8 @@ public: static void BufferToFrame(OIIO::ImageBuf* buf, FramePtr frame); + static PixelFormat::Format GetFormatFromOIIOBasetype(const OIIO::ImageSpec& spec); + private: #if OIIO_VERSION < 10903 OIIO::ImageInput* image_; diff --git a/app/node/param.cpp b/app/node/param.cpp index ff8e72b21..ec1eb8b65 100644 --- a/app/node/param.cpp +++ b/app/node/param.cpp @@ -185,6 +185,58 @@ NodeEdgePtr NodeParam::DisconnectForNewOutput(NodeInput *input) return nullptr; } +QString NodeParam::GetPrettyDataTypeName(const NodeParam::DataType &type) +{ + switch (type) { + case kNone: + return tr("None"); + case kInt: + case kCombo: + return tr("Integer"); + case kFloat: + return tr("Float"); + case kRational: + return tr("Rational"); + case kBoolean: + return tr("Boolean"); + case kColor: + return tr("Color"); + case kMatrix: + return tr("Matrix"); + case kText: + return tr("Text"); + case kFont: + return tr("Font"); + case kFile: + return tr("File"); + case kTexture: + return tr("Texture"); + case kSamples: + return tr("Samples"); + case kFootage: + return tr("Footage"); + case kVec2: + return tr("Vector 2D"); + case kVec3: + return tr("Vector 3D"); + case kVec4: + return tr("Vector 4D"); + + case kDecimal: + case kNumber: + case kString: + case kBuffer: + case kVector: + case kShaderJob: + case kSampleJob: + case kGenerateJob: + case kAny: + break; + } + + return tr("Unknown"); +} + QByteArray NodeParam::ValueToBytes(const NodeParam::DataType &type, const QVariant &value) { switch (type) { @@ -222,39 +274,6 @@ QByteArray NodeParam::ValueToBytes(const NodeParam::DataType &type, const QVaria return QByteArray(); } -NodeParam::DataType NodeParam::StringToDataType(const QString &s) -{ - QString type_id = s.toLower(); - - if (type_id == QStringLiteral("float")) { - return kFloat; - } else if (type_id == QStringLiteral("int")) { - return kInt; - } else if (type_id == QStringLiteral("rational")) { - return kRational; - } else if (type_id == QStringLiteral("bool")) { - return kBoolean; - } else if (type_id == QStringLiteral("color")) { - return kColor; - } else if (type_id == QStringLiteral("matrix")) { - return kMatrix; - } else if (type_id == QStringLiteral("text")) { - return kText; - } else if (type_id == QStringLiteral("texture")) { - return kTexture; - } else if (type_id == QStringLiteral("vec2")) { - return kVec2; - } else if (type_id == QStringLiteral("vec3")) { - return kVec3; - } else if (type_id == QStringLiteral("vec4")) { - return kVec4; - } else if (type_id == QStringLiteral("combo")) { - return kCombo; - } - - return kAny; -} - template QByteArray NodeParam::ValueToBytesInternal(const QVariant &v) { diff --git a/app/node/param.h b/app/node/param.h index 40e5a9716..03e667936 100644 --- a/app/node/param.h +++ b/app/node/param.h @@ -378,18 +378,13 @@ public: /** * @brief Get a human-readable translated name for a certain data type */ - static QString GetDefaultDataTypeName(const DataType &type); + static QString GetPrettyDataTypeName(const DataType &type); /** * @brief Convert a value from a NodeParam into bytes */ static QByteArray ValueToBytes(const DataType &type, const QVariant& value); - /** - * @brief Convert a string to a data type - */ - static DataType StringToDataType(const QString& s); - signals: /** * @brief Signal emitted when an edge is added to this parameter diff --git a/app/node/value.cpp b/app/node/value.cpp index d487f0a3d..e2f9913c5 100644 --- a/app/node/value.cpp +++ b/app/node/value.cpp @@ -61,26 +61,11 @@ NodeValue::NodeValue(const NodeParam::DataType &type, const QVariant &data, cons { } -const NodeParam::DataType &NodeValue::type() const -{ - return type_; -} - -const QString &NodeValue::tag() const -{ - return tag_; -} - bool NodeValue::operator==(const NodeValue &rhs) const { return type_ == rhs.type_ && tag_ == rhs.tag_ && data_ == rhs.data_; } -const QVariant &NodeValue::data() const -{ - return data_; -} - QVariant NodeValueTable::Get(const NodeParam::DataType &type, const QString &tag) const { return GetWithMeta(type, tag).data(); diff --git a/app/node/value.h b/app/node/value.h index 387117993..7efb8592a 100644 --- a/app/node/value.h +++ b/app/node/value.h @@ -33,9 +33,25 @@ public: NodeValue(); NodeValue(const NodeParam::DataType& type, const QVariant& data, const Node* from, const QString& tag = QString()); - const NodeParam::DataType& type() const; - const QVariant& data() const; - const QString& tag() const; + const NodeParam::DataType& type() const + { + return type_; + } + + const QVariant& data() const + { + return data_; + } + + const QString& tag() const + { + return tag_; + } + + const Node* source() const + { + return from_; + } bool operator==(const NodeValue& rhs) const; @@ -90,6 +106,16 @@ public: NodeValueTable Merge() const; + using const_iterator = QHash::const_iterator; + + inline QHash::const_iterator begin() const { + return tables_.cbegin(); + } + + inline QHash::const_iterator end() const { + return tables_.cend(); + } + private: QHash tables_; diff --git a/app/panel/CMakeLists.txt b/app/panel/CMakeLists.txt index 0c6423398..75c1c7738 100644 --- a/app/panel/CMakeLists.txt +++ b/app/panel/CMakeLists.txt @@ -23,6 +23,7 @@ add_subdirectory(pixelsampler) add_subdirectory(project) add_subdirectory(scope) add_subdirectory(sequenceviewer) +add_subdirectory(table) add_subdirectory(taskmanager) add_subdirectory(timebased) add_subdirectory(timeline) diff --git a/app/panel/table/CMakeLists.txt b/app/panel/table/CMakeLists.txt new file mode 100644 index 000000000..f332aa646 --- /dev/null +++ b/app/panel/table/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} + panel/table/table.h + panel/table/table.cpp + PARENT_SCOPE +) diff --git a/app/panel/table/table.cpp b/app/panel/table/table.cpp new file mode 100644 index 000000000..7183e9c23 --- /dev/null +++ b/app/panel/table/table.cpp @@ -0,0 +1,44 @@ +/*** + + 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 . + +***/ + +#include "table.h" + +OLIVE_NAMESPACE_ENTER + +NodeTablePanel::NodeTablePanel(QWidget* parent) : + TimeBasedPanel(QStringLiteral("NodeTablePanel"), parent) +{ + view_ = new NodeTableWidget(); + SetTimeBasedWidget(view_); + + Retranslate(); +} + +void NodeTablePanel::SetNodes(const QList &nodes) +{ + view_->SetNodes(nodes); +} + +void NodeTablePanel::Retranslate() +{ + SetTitle(tr("Table View")); +} + +OLIVE_NAMESPACE_EXIT diff --git a/app/panel/table/table.h b/app/panel/table/table.h new file mode 100644 index 000000000..0587cf51b --- /dev/null +++ b/app/panel/table/table.h @@ -0,0 +1,45 @@ +/*** + + 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 . + +***/ + +#ifndef NODETABLEPANEL_H +#define NODETABLEPANEL_H + +#include "panel/timebased/timebased.h" +#include "widget/nodetableview/nodetablewidget.h" + +OLIVE_NAMESPACE_ENTER + +class NodeTablePanel : public TimeBasedPanel +{ +public: + NodeTablePanel(QWidget* parent); + +public slots: + void SetNodes(const QList& nodes); + +private: + virtual void Retranslate() override; + + NodeTableWidget* view_; +}; + +OLIVE_NAMESPACE_EXIT + +#endif // NODETABLEPANEL_H diff --git a/app/project/item/footage/imagestream.cpp b/app/project/item/footage/imagestream.cpp index beb5f3b3b..41a9d0d23 100644 --- a/app/project/item/footage/imagestream.cpp +++ b/app/project/item/footage/imagestream.cpp @@ -72,26 +72,6 @@ QString ImageStream::description() const QString::number(height())); } -const int &ImageStream::width() const -{ - return width_; -} - -void ImageStream::set_width(const int &width) -{ - width_ = width; -} - -const int &ImageStream::height() const -{ - return height_; -} - -void ImageStream::set_height(const int &height) -{ - height_ = height; -} - bool ImageStream::premultiplied_alpha() const { return premultiplied_alpha_; diff --git a/app/project/item/footage/imagestream.h b/app/project/item/footage/imagestream.h index 9e3b6f72b..30fc712a2 100644 --- a/app/project/item/footage/imagestream.h +++ b/app/project/item/footage/imagestream.h @@ -21,6 +21,7 @@ #ifndef IMAGESTREAM_H #define IMAGESTREAM_H +#include "render/pixelformat.h" #include "stream.h" OLIVE_NAMESPACE_ENTER @@ -36,11 +37,35 @@ public: virtual QString description() const override; - const int& width() const; - void set_width(const int& width); + const int& width() const + { + return width_; + } - const int& height() const; - void set_height(const int& height); + void set_width(const int& width) + { + width_ = width; + } + + const int& height() const + { + return height_; + } + + void set_height(const int& height) + { + height_ = height; + } + + const PixelFormat::Format& format() const + { + return format_; + } + + void set_format(const PixelFormat::Format& format) + { + format_ = format; + } bool premultiplied_alpha() const; void set_premultiplied_alpha(bool e); @@ -63,6 +88,8 @@ private: bool premultiplied_alpha_; QString colorspace_; + PixelFormat::Format format_; + private slots: void ColorConfigChanged(); diff --git a/app/render/videoparams.h b/app/render/videoparams.h index b108874d5..56534ed3c 100644 --- a/app/render/videoparams.h +++ b/app/render/videoparams.h @@ -91,4 +91,6 @@ private: OLIVE_NAMESPACE_EXIT +Q_DECLARE_METATYPE(OLIVE_NAMESPACE::VideoParams) + #endif // VIDEOPARAMS_H diff --git a/app/widget/CMakeLists.txt b/app/widget/CMakeLists.txt index dc068e82b..67c20349e 100644 --- a/app/widget/CMakeLists.txt +++ b/app/widget/CMakeLists.txt @@ -31,6 +31,7 @@ add_subdirectory(nodecombobox) add_subdirectory(nodecopypaste) add_subdirectory(nodeview) add_subdirectory(nodeparamview) +add_subdirectory(nodetableview) add_subdirectory(panel) add_subdirectory(pixelsampler) add_subdirectory(playbackcontrols) diff --git a/app/widget/nodetableview/CMakeLists.txt b/app/widget/nodetableview/CMakeLists.txt new file mode 100644 index 000000000..f12dff040 --- /dev/null +++ b/app/widget/nodetableview/CMakeLists.txt @@ -0,0 +1,26 @@ +# 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/nodetableview/nodetabletraverser.h + widget/nodetableview/nodetabletraverser.cpp + widget/nodetableview/nodetableview.h + widget/nodetableview/nodetableview.cpp + widget/nodetableview/nodetablewidget.h + widget/nodetableview/nodetablewidget.cpp + PARENT_SCOPE +) diff --git a/app/widget/nodetableview/nodetabletraverser.cpp b/app/widget/nodetableview/nodetabletraverser.cpp new file mode 100644 index 000000000..1ca0e1080 --- /dev/null +++ b/app/widget/nodetableview/nodetabletraverser.cpp @@ -0,0 +1,44 @@ +/*** + + 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 . + +***/ + +#include "nodetabletraverser.h" + +OLIVE_NAMESPACE_ENTER + +QVariant NodeTableTraverser::ProcessVideoFootage(StreamPtr stream, const rational &input_time) +{ + ImageStreamPtr video_stream = std::static_pointer_cast(stream); + + return QVariant::fromValue(VideoParams(video_stream->width(), + video_stream->height(), + video_stream->timebase(), + video_stream->format())); +} + +QVariant NodeTableTraverser::ProcessAudioFootage(StreamPtr stream, const TimeRange &input_time) +{ + AudioStreamPtr audio_stream = std::static_pointer_cast(stream); + + return QVariant::fromValue(AudioParams(audio_stream->sample_rate(), + audio_stream->channel_layout(), + SampleFormat::kInternalFormat)); +} + +OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodetableview/nodetabletraverser.h b/app/widget/nodetableview/nodetabletraverser.h new file mode 100644 index 000000000..20dae8e2e --- /dev/null +++ b/app/widget/nodetableview/nodetabletraverser.h @@ -0,0 +1,42 @@ +/*** + + 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 . + +***/ + +#ifndef NODETABLETRAVERSER_H +#define NODETABLETRAVERSER_H + +#include "node/traverser.h" + +OLIVE_NAMESPACE_ENTER + +class NodeTableTraverser : public NodeTraverser +{ +public: + NodeTableTraverser() = default; + +protected: + virtual QVariant ProcessVideoFootage(StreamPtr stream, const rational &input_time); + + virtual QVariant ProcessAudioFootage(StreamPtr stream, const TimeRange &input_time); + +}; + +OLIVE_NAMESPACE_EXIT + +#endif // NODETABLETRAVERSER_H diff --git a/app/widget/nodetableview/nodetableview.cpp b/app/widget/nodetableview/nodetableview.cpp new file mode 100644 index 000000000..8e9f5aab0 --- /dev/null +++ b/app/widget/nodetableview/nodetableview.cpp @@ -0,0 +1,113 @@ +/*** + + 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 . + +***/ + +#include "nodetableview.h" + +#include + +#include "node/param.h" +#include "nodetabletraverser.h" + +OLIVE_NAMESPACE_ENTER + +NodeTableView::NodeTableView(QWidget* parent) : + QTreeWidget(parent) +{ + setColumnCount(3); + setHeaderLabels({tr("Type"), tr("Value"), tr("Source")}); +} + +void NodeTableView::SetNode(Node *n, const rational &time) +{ + clear(); + + NodeTableTraverser traverser; + NodeValueDatabase db = traverser.GenerateDatabase(n, TimeRange(time, time)); + + NodeValueDatabase::const_iterator i; + + for (i=db.begin(); i!=db.end(); i++) { + const NodeValueTable& table = i.value(); + + NodeInput* input = n->GetInputWithID(i.key()); + if (!input) { + // Filters out table entries that aren't inputs (like "global") + continue; + } + + QTreeWidgetItem* top_item = new QTreeWidgetItem(); + top_item->setText(0, input->name()); + top_item->setFirstColumnSpanned(true); + this->addTopLevelItem(top_item); + + for (int j=table.Count()-1; j>=0; j--) { + const NodeValue& value = table.at(j); + + QString value_str = NodeInput::ValueToString(value.type(), value.data()); + + QString source_name; + if (value.source()) { + source_name = value.source()->Name(); + } else { + source_name = tr("(unknown)"); + } + + QTreeWidgetItem* sub_item = new QTreeWidgetItem(); + sub_item->setText(0, NodeParam::GetPrettyDataTypeName(value.type())); + sub_item->setText(1, value_str); + sub_item->setText(2, source_name); + top_item->addChild(sub_item); + + // Special cases + if (value.type() == NodeParam::kTexture) { + // NodeTableTraverser converts footage to VideoParams + QTreeWidgetItem* red_channel = new QTreeWidgetItem(); + red_channel->setText(0, tr("Red")); + sub_item->addChild(red_channel); + + QTreeWidgetItem* green_channel = new QTreeWidgetItem(); + green_channel->setText(0, tr("Green")); + sub_item->addChild(green_channel); + + QTreeWidgetItem* blue_channel = new QTreeWidgetItem(); + blue_channel->setText(0, tr("Blue")); + sub_item->addChild(blue_channel); + + if (PixelFormat::FormatHasAlphaChannel(value.data().value().format())) { + QTreeWidgetItem* alpha_channel = new QTreeWidgetItem(); + alpha_channel->setText(0, tr("Alpha")); + sub_item->addChild(alpha_channel); + } + } + } + } +} + +void NodeTableView::SetMultipleNodeMessage() +{ + this->clear(); + + QTreeWidgetItem* item = new QTreeWidgetItem(); + item->setText(0, tr("Multiple nodes selected")); + item->setFirstColumnSpanned(true); + this->addTopLevelItem(item); +} + +OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodetableview/nodetableview.h b/app/widget/nodetableview/nodetableview.h new file mode 100644 index 000000000..e453903b7 --- /dev/null +++ b/app/widget/nodetableview/nodetableview.h @@ -0,0 +1,43 @@ +/*** + + 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 . + +***/ + +#ifndef NODETABLEVIEW_H +#define NODETABLEVIEW_H + +#include + +#include "node/node.h" + +OLIVE_NAMESPACE_ENTER + +class NodeTableView : public QTreeWidget +{ +public: + NodeTableView(QWidget* parent = nullptr); + + void SetNode(Node* n, const rational& time); + + void SetMultipleNodeMessage(); + +}; + +OLIVE_NAMESPACE_EXIT + +#endif // NODETABLEVIEW_H diff --git a/app/widget/nodetableview/nodetablewidget.cpp b/app/widget/nodetableview/nodetablewidget.cpp new file mode 100644 index 000000000..20db058c2 --- /dev/null +++ b/app/widget/nodetableview/nodetablewidget.cpp @@ -0,0 +1,49 @@ +/*** + + 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 . + +***/ + +#include "nodetablewidget.h" + +#include + +OLIVE_NAMESPACE_ENTER + +NodeTableWidget::NodeTableWidget(QWidget* parent) : + TimeBasedWidget(parent) +{ + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setSpacing(0); + layout->setMargin(0); + + view_ = new NodeTableView(); + layout->addWidget(view_); +} + +void NodeTableWidget::SetNodes(const QList &nodes) +{ + if (nodes.isEmpty()) { + view_->clear(); + } else if (nodes.size() == 1) { + view_->SetNode(nodes.first(), rational()); + } else { + view_->SetMultipleNodeMessage(); + } +} + +OLIVE_NAMESPACE_EXIT diff --git a/app/widget/nodetableview/nodetablewidget.h b/app/widget/nodetableview/nodetablewidget.h new file mode 100644 index 000000000..ae0c82cc4 --- /dev/null +++ b/app/widget/nodetableview/nodetablewidget.h @@ -0,0 +1,43 @@ +/*** + + 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 . + +***/ + +#ifndef NODETABLEWIDGET_H +#define NODETABLEWIDGET_H + +#include "nodetableview.h" +#include "widget/timebased/timebased.h" + +OLIVE_NAMESPACE_ENTER + +class NodeTableWidget : public TimeBasedWidget +{ +public: + NodeTableWidget(QWidget* parent = nullptr); + + void SetNodes(const QList& nodes); + +private: + NodeTableView* view_; + +}; + +OLIVE_NAMESPACE_EXIT + +#endif // NODETABLEWIDGET_H diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 31239436d..e6b0f8d34 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -72,6 +72,7 @@ MainWindow::MainWindow(QWidget *parent) : node_panel_ = PanelManager::instance()->CreatePanel(this); footage_viewer_panel_ = PanelManager::instance()->CreatePanel(this); param_panel_ = PanelManager::instance()->CreatePanel(this); + table_panel_ = PanelManager::instance()->CreatePanel(this); sequence_viewer_panel_ = PanelManager::instance()->CreatePanel(this); pixel_sampler_panel_ = PanelManager::instance()->CreatePanel(this); AppendProjectPanel(); @@ -82,6 +83,7 @@ MainWindow::MainWindow(QWidget *parent) : // Make connections to sequence viewer connect(node_panel_, &NodePanel::SelectionChanged, param_panel_, &ParamPanel::SetNodes); + connect(node_panel_, &NodePanel::SelectionChanged, table_panel_, &NodeTablePanel::SetNodes); connect(param_panel_, &ParamPanel::RequestSelectNode, node_panel_, &NodePanel::Select); connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp); connect(param_panel_, &ParamPanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp); @@ -590,6 +592,10 @@ void MainWindow::SetDefaultLayout() tabifyDockWidget(footage_viewer_panel_, param_panel_); footage_viewer_panel_->raise(); + table_panel_->hide(); + table_panel_->setFloating(true); + addDockWidget(Qt::TopDockWidgetArea, table_panel_); + sequence_viewer_panel_->show(); addDockWidget(Qt::TopDockWidgetArea, sequence_viewer_panel_); diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index 21a6d561c..787eb2899 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -30,6 +30,7 @@ #include "panel/param/param.h" #include "panel/project/project.h" #include "panel/scope/scope.h" +#include "panel/table/table.h" #include "panel/taskmanager/taskmanager.h" #include "panel/timeline/timeline.h" #include "panel/tool/tool.h" @@ -145,6 +146,7 @@ private: QList curve_panels_; PixelSamplerPanel* pixel_sampler_panel_; QList scope_panels_; + NodeTablePanel* table_panel_; #ifdef Q_OS_WINDOWS unsigned int taskbar_btn_id_;