engine: internals supporting the facade migration
UndoStack push_pre_executed, FolderAddChild-based true folder moves, NodeViewDeleteCommand delete-then-reconnect support, event emission points for the facade event bus, and related internal adjustments.
This commit is contained in:
@@ -31,8 +31,12 @@
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#ifndef OAK_CONFIG
|
||||
#define OAK_CONFIG(x) Config::current()[QStringLiteral(x)]
|
||||
#endif
|
||||
#ifndef OAK_CONFIG_STR
|
||||
#define OAK_CONFIG_STR(x) Config::current()[x]
|
||||
#endif
|
||||
|
||||
class Config {
|
||||
public:
|
||||
|
||||
@@ -178,7 +178,7 @@ void EngineCore::declare_types_for_qt()
|
||||
qRegisterMetaType<olive::AudioVisualWaveform>();
|
||||
qRegisterMetaType<olive::VideoParams>();
|
||||
qRegisterMetaType<olive::VideoParams::Interlacing>();
|
||||
qRegisterMetaType<olive::MainWindowLayoutInfo>();
|
||||
qRegisterMetaType<olive::SerializedLayoutInfo>();
|
||||
qRegisterMetaType<olive::RenderTicketPtr>();
|
||||
}
|
||||
|
||||
|
||||
+33
-16
@@ -33,7 +33,7 @@
|
||||
#include "node/project/footage/footage.h"
|
||||
#include "node/project.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "node/project/serializer/mainwindowlayoutinfo.h"
|
||||
#include "node/project/serializer/serializedlayoutinfo.h"
|
||||
#include "task/task.h"
|
||||
#include "tool/tool.h"
|
||||
#include "undo/undostack.h"
|
||||
@@ -304,7 +304,7 @@ public:
|
||||
* @brief Handler applying a loaded main window layout after a project load
|
||||
*/
|
||||
using LoadLayoutHandler =
|
||||
std::function<void(const MainWindowLayoutInfo &layout)>;
|
||||
std::function<void(const SerializedLayoutInfo &layout)>;
|
||||
void set_load_layout_handler(LoadLayoutHandler handler);
|
||||
|
||||
/**
|
||||
@@ -320,6 +320,17 @@ public:
|
||||
*/
|
||||
void remove_recently_opened_project(int index);
|
||||
|
||||
/**
|
||||
* @brief Currently open project (may be nullptr)
|
||||
*
|
||||
* Read accessor for the C ABI facade (oakengine_app_open_project());
|
||||
* the UI layer used to read the protected member directly.
|
||||
*/
|
||||
Project *open_project() const
|
||||
{
|
||||
return open_project_;
|
||||
}
|
||||
|
||||
#ifdef USE_OTIO
|
||||
/**
|
||||
* @brief Handler showing the OTIO import options dialog
|
||||
@@ -410,6 +421,26 @@ public slots:
|
||||
bool show_otio_import_dialog(const QList<Sequence *> &sequences);
|
||||
#endif
|
||||
|
||||
void add_recovery_project_from_task(Task *task);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Adds a project to the "open projects" list
|
||||
*
|
||||
* (Public for the C ABI facade; was protected while olive::Core derived
|
||||
* from this class.)
|
||||
*/
|
||||
void add_open_project(olive::Project *p, bool add_to_recents = false);
|
||||
|
||||
bool add_open_project_from_task(Task *task, bool add_to_recents);
|
||||
|
||||
void set_active_project(Project *p);
|
||||
|
||||
/**
|
||||
* @brief Returns the filename of the autorecovery index
|
||||
*/
|
||||
static QString get_auto_recovery_index_filename();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the tool is changed from somewhere
|
||||
@@ -471,15 +502,6 @@ signals:
|
||||
void active_project_changed(Project *p);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Adds a project to the "open projects" list
|
||||
*/
|
||||
void add_open_project(olive::Project *p, bool add_to_recents = false);
|
||||
|
||||
bool add_open_project_from_task(Task *task, bool add_to_recents);
|
||||
|
||||
void set_active_project(Project *p);
|
||||
|
||||
/**
|
||||
* @brief Currently open project
|
||||
*
|
||||
@@ -487,11 +509,6 @@ protected:
|
||||
*/
|
||||
Project *open_project_;
|
||||
|
||||
static QString get_auto_recovery_index_filename();
|
||||
|
||||
protected slots:
|
||||
void add_recovery_project_from_task(Task *task);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Returns the filename where the recently opened/saved projects should be stored
|
||||
|
||||
@@ -69,6 +69,9 @@ public:
|
||||
|
||||
static QString format_string(const QString &input, const QStringList &args);
|
||||
|
||||
/** @brief Access the text gizmo. */
|
||||
TextGizmo *text_gizmo() { return text_gizmo_; }
|
||||
|
||||
protected:
|
||||
virtual void InputValueChangedEvent(const QString &input,
|
||||
int element) override;
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "project.h"
|
||||
#include "serializeddata.h"
|
||||
#include "ui/colorcoding.h"
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -109,7 +108,7 @@ QVariant Node::data(const DataType &d) const
|
||||
{
|
||||
if (d == icon) {
|
||||
// Just a meaningless default icon to be used where necessary
|
||||
return icon::New;
|
||||
return QStringLiteral("new");
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@@ -2481,7 +2480,7 @@ void Node::childEvent(QChildEvent *event)
|
||||
connect(key, &NodeKeyframe::bezier_control_out_changed, this,
|
||||
&Node::invalidate_from_keyframe_bezier_out_change);
|
||||
|
||||
emit keyframe_added(key);
|
||||
emit keyframe_added(reinterpret_cast<OakEngineKeyframe *>(key));
|
||||
parameter_value_changed(i, get_range_affected_by_keyframe(key));
|
||||
} else if (event->type() == QEvent::ChildRemoved) {
|
||||
TimeRange time_affected = get_range_affected_by_keyframe(key);
|
||||
@@ -2497,7 +2496,7 @@ void Node::childEvent(QChildEvent *event)
|
||||
disconnect(key, &NodeKeyframe::bezier_control_out_changed, this,
|
||||
&Node::invalidate_from_keyframe_bezier_out_change);
|
||||
|
||||
emit keyframe_removed(key);
|
||||
emit keyframe_removed(reinterpret_cast<OakEngineKeyframe *>(key));
|
||||
|
||||
get_immediate(key->input(), key->element())->remove_keyframe(key);
|
||||
parameter_value_changed(i, time_affected);
|
||||
@@ -2570,7 +2569,7 @@ void Node::invalidate_from_keyframe_time_change()
|
||||
parameter_value_changed(key->key_track_ref().input(), r);
|
||||
}
|
||||
|
||||
emit keyframe_time_changed(key);
|
||||
emit keyframe_time_changed(reinterpret_cast<OakEngineKeyframe *>(key));
|
||||
}
|
||||
|
||||
void Node::invalidate_from_keyframe_value_change()
|
||||
@@ -2579,7 +2578,7 @@ void Node::invalidate_from_keyframe_value_change()
|
||||
parameter_value_changed(key->key_track_ref().input(),
|
||||
get_range_affected_by_keyframe(key));
|
||||
|
||||
emit keyframe_value_changed(key);
|
||||
emit keyframe_value_changed(reinterpret_cast<OakEngineKeyframe *>(key));
|
||||
}
|
||||
|
||||
void Node::invalidate_from_keyframe_type_changed()
|
||||
@@ -2597,7 +2596,7 @@ void Node::invalidate_from_keyframe_type_changed()
|
||||
get_range_around_index(key->input(), track.indexOf(key),
|
||||
key->track(), key->element()));
|
||||
|
||||
emit keyframe_type_changed(key);
|
||||
emit keyframe_type_changed(reinterpret_cast<OakEngineKeyframe *>(key));
|
||||
}
|
||||
|
||||
void Node::set_value_at_time(const NodeInput &input, const Rational &time,
|
||||
|
||||
+9
-5
@@ -47,6 +47,10 @@
|
||||
#include "render/shadercode.h"
|
||||
#include "splitvalue.h"
|
||||
|
||||
/* Forward declaration for C ABI keyframe handle used in signals that cross
|
||||
* the app/engine boundary. */
|
||||
struct OakEngineKeyframe;
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
@@ -1319,17 +1323,17 @@ signals:
|
||||
void input_array_size_changed(const QString &input, int old_size,
|
||||
int new_size);
|
||||
|
||||
void keyframe_added(NodeKeyframe *key);
|
||||
void keyframe_added(OakEngineKeyframe *key);
|
||||
|
||||
void keyframe_removed(NodeKeyframe *key);
|
||||
void keyframe_removed(OakEngineKeyframe *key);
|
||||
|
||||
void keyframe_time_changed(NodeKeyframe *key);
|
||||
void keyframe_time_changed(OakEngineKeyframe *key);
|
||||
|
||||
void message_count_changed();
|
||||
|
||||
void keyframe_type_changed(NodeKeyframe *key);
|
||||
void keyframe_type_changed(OakEngineKeyframe *key);
|
||||
|
||||
void keyframe_value_changed(NodeKeyframe *key);
|
||||
void keyframe_value_changed(OakEngineKeyframe *key);
|
||||
|
||||
void keyframe_enable_changed(const NodeInput &input, bool enabled);
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "node/nodeundo.h"
|
||||
#include "node/project/footage/footage.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -45,7 +44,7 @@ Folder::Folder()
|
||||
QVariant Folder::data(const DataType &d) const
|
||||
{
|
||||
if (d == icon) {
|
||||
return icon::folder;
|
||||
return QStringLiteral("folder");
|
||||
}
|
||||
|
||||
return super::data(d);
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "node/color/colormanager/colormanager.h"
|
||||
#include "node/project.h"
|
||||
#include "render/job/footagejob.h"
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
@@ -613,18 +612,18 @@ QVariant Footage::data(const DataType &d) const
|
||||
|
||||
if (s.is_valid() &&
|
||||
s.video_type() != VideoParams::k_video_type_still) {
|
||||
return icon::video;
|
||||
return QStringLiteral("video");
|
||||
} else if (has_enabled_audio_streams()) {
|
||||
return icon::audio;
|
||||
return QStringLiteral("audio");
|
||||
} else if (s.is_valid() &&
|
||||
s.video_type() == VideoParams::k_video_type_still) {
|
||||
return icon::image;
|
||||
return QStringLiteral("image");
|
||||
} else if (has_enabled_subtitle_streams()) {
|
||||
return icon::subtitles;
|
||||
return QStringLiteral("subtitles");
|
||||
}
|
||||
}
|
||||
|
||||
return icon::error;
|
||||
return QStringLiteral("error");
|
||||
}
|
||||
case tooltip: {
|
||||
if (valid_) {
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#include "ui/icons/icons.h"
|
||||
#include "timeline/timelineundogeneral.h"
|
||||
|
||||
namespace olive
|
||||
@@ -81,7 +80,7 @@ void Sequence::add_default_nodes(MultiUndoCommand *command)
|
||||
QVariant Sequence::data(const DataType &d) const
|
||||
{
|
||||
if (d == icon) {
|
||||
return icon::sequence;
|
||||
return QStringLiteral("sequence");
|
||||
}
|
||||
|
||||
return super::data(d);
|
||||
|
||||
@@ -33,8 +33,8 @@ set(OLIVE_SOURCES
|
||||
node/project/serializer/serializer230220.h
|
||||
|
||||
|
||||
node/project/serializer/mainwindowlayoutinfo.cpp
|
||||
node/project/serializer/mainwindowlayoutinfo.h
|
||||
node/project/serializer/serializedlayoutinfo.cpp
|
||||
node/project/serializer/serializedlayoutinfo.h
|
||||
|
||||
node/project/serializer/typeserializer.cpp
|
||||
node/project/serializer/typeserializer.h
|
||||
|
||||
+15
-49
@@ -16,19 +16,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mainwindowlayoutinfo.h"
|
||||
#include "serializedlayoutinfo.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
void MainWindowLayoutInfo::to_xml(QXmlStreamWriter *writer) const
|
||||
void SerializedLayoutInfo::to_xml(QXmlStreamWriter *writer) const
|
||||
{
|
||||
writer->writeAttribute(QStringLiteral("version"),
|
||||
QString::number(k_version));
|
||||
|
||||
writer->writeStartElement(QStringLiteral("folders"));
|
||||
|
||||
foreach (Folder *folder, open_folders_) {
|
||||
foreach (Folder *folder, open_folders) {
|
||||
writer->writeTextElement(
|
||||
QStringLiteral("folder"),
|
||||
QString::number(reinterpret_cast<quintptr>(folder)));
|
||||
@@ -38,7 +38,7 @@ void MainWindowLayoutInfo::to_xml(QXmlStreamWriter *writer) const
|
||||
|
||||
writer->writeStartElement(QStringLiteral("timeline"));
|
||||
|
||||
foreach (Sequence *sequence, open_sequences_) {
|
||||
foreach (Sequence *sequence, open_sequences) {
|
||||
writer->writeTextElement(
|
||||
QStringLiteral("sequence"),
|
||||
QString::number(reinterpret_cast<quintptr>(sequence)));
|
||||
@@ -48,7 +48,7 @@ void MainWindowLayoutInfo::to_xml(QXmlStreamWriter *writer) const
|
||||
|
||||
writer->writeStartElement(QStringLiteral("viewers"));
|
||||
|
||||
foreach (ViewerOutput *viewer, open_viewers_) {
|
||||
foreach (ViewerOutput *viewer, open_viewers) {
|
||||
writer->writeTextElement(
|
||||
QStringLiteral("viewer"),
|
||||
QString::number(reinterpret_cast<quintptr>(viewer)));
|
||||
@@ -58,7 +58,7 @@ void MainWindowLayoutInfo::to_xml(QXmlStreamWriter *writer) const
|
||||
|
||||
writer->writeStartElement(QStringLiteral("data"));
|
||||
|
||||
for (auto it = panel_data_.cbegin(); it != panel_data_.cend(); it++) {
|
||||
for (auto it = panel_data.cbegin(); it != panel_data.cend(); it++) {
|
||||
writer->writeStartElement(QStringLiteral("panel"));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("id"), it->first);
|
||||
@@ -80,14 +80,14 @@ void MainWindowLayoutInfo::to_xml(QXmlStreamWriter *writer) const
|
||||
writer->writeEndElement(); // data
|
||||
|
||||
writer->writeTextElement(QStringLiteral("state"),
|
||||
QString(state_.toBase64()));
|
||||
QString(state.toBase64()));
|
||||
}
|
||||
|
||||
MainWindowLayoutInfo
|
||||
MainWindowLayoutInfo::from_xml(QXmlStreamReader *reader,
|
||||
SerializedLayoutInfo
|
||||
SerializedLayoutInfo::from_xml(QXmlStreamReader *reader,
|
||||
const QHash<quintptr, Node *> &node_ptrs)
|
||||
{
|
||||
MainWindowLayoutInfo info;
|
||||
SerializedLayoutInfo info;
|
||||
|
||||
unsigned int file_version = 0;
|
||||
|
||||
@@ -110,7 +110,7 @@ MainWindowLayoutInfo::from_xml(QXmlStreamReader *reader,
|
||||
|
||||
Folder *open_item =
|
||||
static_cast<Folder *>(node_ptrs.value(item_id));
|
||||
info.open_folders_.push_back(open_item);
|
||||
info.open_folders.push_back(open_item);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
@@ -123,7 +123,7 @@ MainWindowLayoutInfo::from_xml(QXmlStreamReader *reader,
|
||||
|
||||
Sequence *open_seq =
|
||||
static_cast<Sequence *>(node_ptrs.value(item_id));
|
||||
info.open_sequences_.push_back(open_seq);
|
||||
info.open_sequences.push_back(open_seq);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
@@ -136,14 +136,14 @@ MainWindowLayoutInfo::from_xml(QXmlStreamReader *reader,
|
||||
|
||||
ViewerOutput *open_viewer =
|
||||
static_cast<ViewerOutput *>(node_ptrs.value(item_id));
|
||||
info.open_viewers_.push_back(open_viewer);
|
||||
info.open_viewers.push_back(open_viewer);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
} else if (reader->name() == QStringLiteral("state")) {
|
||||
info.state_ =
|
||||
info.state =
|
||||
QByteArray::fromBase64(reader->readElementText().toLatin1());
|
||||
|
||||
} else if (reader->name() == QStringLiteral("data")) {
|
||||
@@ -179,7 +179,7 @@ MainWindowLayoutInfo::from_xml(QXmlStreamReader *reader,
|
||||
}
|
||||
}
|
||||
|
||||
info.panel_data_[id] = i;
|
||||
info.panel_data[id] = i;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -195,38 +195,4 @@ MainWindowLayoutInfo::from_xml(QXmlStreamReader *reader,
|
||||
return info;
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::add_folder(olive::Folder *f)
|
||||
{
|
||||
open_folders_.push_back(f);
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::add_sequence(Sequence *seq)
|
||||
{
|
||||
open_sequences_.push_back(seq);
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::add_viewer(ViewerOutput *viewer)
|
||||
{
|
||||
open_viewers_.push_back(viewer);
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::set_panel_data(const QString &id,
|
||||
const PanelLayoutInfo &data)
|
||||
{
|
||||
panel_data_[id] = data;
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::move_panel_data(const QString &old,
|
||||
const QString &now)
|
||||
{
|
||||
PanelLayoutInfo tmp = panel_data_.at(old);
|
||||
panel_data_.erase(old);
|
||||
panel_data_[now] = tmp;
|
||||
}
|
||||
|
||||
void MainWindowLayoutInfo::set_state(const QByteArray &layout)
|
||||
{
|
||||
state_ = layout;
|
||||
}
|
||||
|
||||
}
|
||||
+19
-49
@@ -16,8 +16,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OAK_MAINWINDOWLAYOUTINFO_H
|
||||
#define OAK_MAINWINDOWLAYOUTINFO_H
|
||||
#ifndef OAK_SERIALIZEDLAYOUTINFO_H
|
||||
#define OAK_SERIALIZEDLAYOUTINFO_H
|
||||
|
||||
#include <map>
|
||||
|
||||
@@ -35,68 +35,38 @@ namespace olive
|
||||
*/
|
||||
using PanelLayoutInfo = std::map<QString, QString>;
|
||||
|
||||
class MainWindowLayoutInfo {
|
||||
/**
|
||||
* @brief Plain data container for a serialized main window layout
|
||||
*
|
||||
* Pure data structure with no behavior beyond XML (de)serialization, so
|
||||
* consumers (app, tests) can use it without pulling in any engine-side
|
||||
* C++ symbols.
|
||||
*/
|
||||
class SerializedLayoutInfo {
|
||||
public:
|
||||
MainWindowLayoutInfo() = default;
|
||||
SerializedLayoutInfo() = default;
|
||||
|
||||
void to_xml(QXmlStreamWriter *writer) const;
|
||||
|
||||
static MainWindowLayoutInfo
|
||||
static SerializedLayoutInfo
|
||||
from_xml(QXmlStreamReader *reader, const QHash<quintptr, Node *> &node_map);
|
||||
|
||||
void add_folder(Folder *f);
|
||||
QByteArray state;
|
||||
|
||||
void add_sequence(Sequence *seq);
|
||||
std::vector<Folder *> open_folders;
|
||||
|
||||
void add_viewer(ViewerOutput *viewer);
|
||||
std::vector<Sequence *> open_sequences;
|
||||
|
||||
void set_panel_data(const QString &id, const PanelLayoutInfo &data);
|
||||
std::vector<ViewerOutput *> open_viewers;
|
||||
|
||||
void move_panel_data(const QString &old, const QString &now);
|
||||
|
||||
void set_state(const QByteArray &layout);
|
||||
|
||||
const std::vector<Folder *> &open_folders() const
|
||||
{
|
||||
return open_folders_;
|
||||
}
|
||||
|
||||
const std::vector<Sequence *> &open_sequences() const
|
||||
{
|
||||
return open_sequences_;
|
||||
}
|
||||
|
||||
const std::vector<ViewerOutput *> &open_viewers() const
|
||||
{
|
||||
return open_viewers_;
|
||||
}
|
||||
|
||||
const std::map<QString, PanelLayoutInfo> &panel_data() const
|
||||
{
|
||||
return panel_data_;
|
||||
}
|
||||
|
||||
const QByteArray &state() const
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
std::map<QString, PanelLayoutInfo> panel_data;
|
||||
|
||||
private:
|
||||
QByteArray state_;
|
||||
|
||||
std::vector<Folder *> open_folders_;
|
||||
|
||||
std::vector<Sequence *> open_sequences_;
|
||||
|
||||
std::vector<ViewerOutput *> open_viewers_;
|
||||
|
||||
std::map<QString, PanelLayoutInfo> panel_data_;
|
||||
|
||||
static const unsigned int k_version = 1;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(olive::MainWindowLayoutInfo)
|
||||
Q_DECLARE_METATYPE(olive::SerializedLayoutInfo)
|
||||
|
||||
#endif // OAK_MAINWINDOWLAYOUTINFO_H
|
||||
#endif // OAK_SERIALIZEDLAYOUTINFO_H
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "common/define.h"
|
||||
#include "node/project.h"
|
||||
#include "node/project/serializer/mainwindowlayoutinfo.h"
|
||||
#include "node/project/serializer/serializedlayoutinfo.h"
|
||||
#include "typeserializer.h"
|
||||
|
||||
namespace olive
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
SerializedKeyframes keyframes;
|
||||
|
||||
MainWindowLayoutInfo layout;
|
||||
SerializedLayoutInfo layout;
|
||||
|
||||
QVector<Node *> nodes;
|
||||
|
||||
@@ -173,11 +173,11 @@ public:
|
||||
return type_;
|
||||
}
|
||||
|
||||
const MainWindowLayoutInfo &get_layout() const
|
||||
const SerializedLayoutInfo &get_layout() const
|
||||
{
|
||||
return layout_;
|
||||
}
|
||||
void set_layout(const MainWindowLayoutInfo &layout)
|
||||
void set_layout(const SerializedLayoutInfo &layout)
|
||||
{
|
||||
layout_ = layout;
|
||||
}
|
||||
@@ -226,7 +226,7 @@ public:
|
||||
|
||||
QString filename_;
|
||||
|
||||
MainWindowLayoutInfo layout_;
|
||||
SerializedLayoutInfo layout_;
|
||||
|
||||
QVector<Node *> only_serialize_nodes_;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ ProjectSerializer220403::load(Project *project, QXmlStreamReader *reader,
|
||||
// can continue loading and queue it with the main window so it can handle the data
|
||||
// appropriately in its own thread.
|
||||
|
||||
load_data.layout = MainWindowLayoutInfo::from_xml(
|
||||
load_data.layout = SerializedLayoutInfo::from_xml(
|
||||
reader, xml_node_data.node_ptrs);
|
||||
|
||||
} else if (reader->name() == QStringLiteral("uuid")) {
|
||||
|
||||
@@ -49,7 +49,7 @@ ProjectSerializer230220::load(Project *project, QXmlStreamReader *reader,
|
||||
project_data = project->load(reader);
|
||||
load_data.node_ptrs = project_data.node_ptrs;
|
||||
} else if (reader->name() == QStringLiteral("layout")) {
|
||||
load_data.layout = MainWindowLayoutInfo::from_xml(
|
||||
load_data.layout = SerializedLayoutInfo::from_xml(
|
||||
reader, project_data.node_ptrs);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
global:
|
||||
oakengine_*;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -439,17 +439,16 @@ void OlivePluginInstance::progressStart(const std::string &message,
|
||||
|
||||
if (progress_reporter_) {
|
||||
progress_reporter_->close();
|
||||
progress_reporter_->deleteLater();
|
||||
progress_reporter_.reset();
|
||||
}
|
||||
|
||||
QString dialog_message = message.empty() ? QStringLiteral("Processing...") :
|
||||
QString::fromStdString(message);
|
||||
|
||||
progress_reporter_ = create_plugin_progress_reporter(
|
||||
dialog_message, QStringLiteral("OpenFX"));
|
||||
QObject::connect(progress_reporter_, &PluginProgressReporter::cancelled,
|
||||
progress_reporter_,
|
||||
[this]() { progress_cancelled_ = true; });
|
||||
progress_reporter_.reset(create_plugin_progress_reporter(
|
||||
dialog_message, QStringLiteral("OpenFX")));
|
||||
progress_reporter_->set_cancel_callback(
|
||||
[this](void *) { progress_cancelled_ = true; }, nullptr);
|
||||
progress_reporter_->show();
|
||||
}
|
||||
|
||||
@@ -460,7 +459,7 @@ void OlivePluginInstance::progressEnd()
|
||||
|
||||
if (progress_reporter_) {
|
||||
progress_reporter_->close();
|
||||
progress_reporter_->deleteLater();
|
||||
progress_reporter_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <QString>
|
||||
#include "ofxhImageEffect.h"
|
||||
#include "node/plugins/plugin.h"
|
||||
#include "pluginSupport/pluginprogressreporter.h"
|
||||
#include "render/videoparams.h"
|
||||
#include "undo/undocommand.h"
|
||||
|
||||
@@ -228,7 +229,7 @@ private:
|
||||
QString edit_label_;
|
||||
QString edit_first_label_;
|
||||
int edit_param_count_ = 0;
|
||||
QPointer<PluginProgressReporter> progress_reporter_;
|
||||
std::unique_ptr<PluginProgressReporter> progress_reporter_;
|
||||
bool progress_cancelled_ = false;
|
||||
bool progress_active_ = false;
|
||||
bool open_gl_enabled_ = false;
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace
|
||||
/**
|
||||
* @brief No-op reporter used when no UI factory is registered
|
||||
*
|
||||
* Never emits cancelled(), so processing always continues.
|
||||
* Never reports cancellation, so processing always continues.
|
||||
*/
|
||||
class NullPluginProgressReporter : public PluginProgressReporter {
|
||||
public:
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#ifndef OAK_PLUGIN_PROGRESS_REPORTER_H
|
||||
#define OAK_PLUGIN_PROGRESS_REPORTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include <functional>
|
||||
@@ -35,16 +34,16 @@ namespace plugin
|
||||
* this interface. The UI layer registers a factory (see
|
||||
* set_plugin_progress_reporter_factory()) that creates a reporter wrapping a
|
||||
* ProgressDialog; without a factory, a no-op reporter is used instead.
|
||||
*
|
||||
* Cancellation is delivered through a C-style callback rather than a Qt
|
||||
* signal, so the class does not need Q_OBJECT and can be used across the
|
||||
* liboakengine C ABI boundary without MOC-generated symbols.
|
||||
*/
|
||||
class PluginProgressReporter : public QObject {
|
||||
Q_OBJECT
|
||||
class PluginProgressReporter {
|
||||
public:
|
||||
explicit PluginProgressReporter(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
PluginProgressReporter() = default;
|
||||
|
||||
virtual ~PluginProgressReporter() override = default;
|
||||
virtual ~PluginProgressReporter() = default;
|
||||
|
||||
virtual void set_progress(double value) = 0;
|
||||
|
||||
@@ -52,8 +51,40 @@ public:
|
||||
|
||||
virtual void close() = 0;
|
||||
|
||||
signals:
|
||||
void cancelled();
|
||||
/**
|
||||
* @brief Register a callback to be invoked when the user cancels.
|
||||
*
|
||||
* The engine (or any C ABI consumer) registers this to receive the
|
||||
* cancellation event. Only one callback is supported; subsequent calls
|
||||
* replace the previous registration. Pass nullptr to clear.
|
||||
*/
|
||||
void set_cancel_callback(std::function<void(void *)> cb, void *userdata)
|
||||
{
|
||||
cancel_callback_ = std::move(cb);
|
||||
cancel_callback_userdata_ = userdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mark this reporter as cancelled and notify the registered
|
||||
* callback.
|
||||
*/
|
||||
void set_cancelled()
|
||||
{
|
||||
cancelled_ = true;
|
||||
if (cancel_callback_) {
|
||||
cancel_callback_(cancel_callback_userdata_);
|
||||
}
|
||||
}
|
||||
|
||||
bool cancelled() const
|
||||
{
|
||||
return cancelled_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(void *)> cancel_callback_;
|
||||
void *cancel_callback_userdata_ = nullptr;
|
||||
bool cancelled_ = false;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -64,7 +95,7 @@ signals:
|
||||
*/
|
||||
using PluginProgressReporterFactory =
|
||||
std::function<PluginProgressReporter *(const QString &message,
|
||||
const QString &title)>;
|
||||
const QString &title)>;
|
||||
|
||||
void set_plugin_progress_reporter_factory(
|
||||
PluginProgressReporterFactory factory);
|
||||
|
||||
@@ -19,50 +19,7 @@
|
||||
|
||||
***/
|
||||
|
||||
#include "managedcolor.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
ManagedColor::ManagedColor()
|
||||
{
|
||||
}
|
||||
|
||||
ManagedColor::ManagedColor(const double &r, const double &g, const double &b,
|
||||
const double &a)
|
||||
: Color(r, g, b, a)
|
||||
{
|
||||
}
|
||||
|
||||
ManagedColor::ManagedColor(const char *data, const PixelFormat &format,
|
||||
int channel_layout)
|
||||
: Color(data, format, channel_layout)
|
||||
{
|
||||
}
|
||||
|
||||
ManagedColor::ManagedColor(const Color &c)
|
||||
: Color(c)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &ManagedColor::color_input() const
|
||||
{
|
||||
return color_input_;
|
||||
}
|
||||
|
||||
void ManagedColor::set_color_input(const QString &color_input)
|
||||
{
|
||||
color_input_ = color_input;
|
||||
}
|
||||
|
||||
const ColorTransform &ManagedColor::color_output() const
|
||||
{
|
||||
return color_transform_;
|
||||
}
|
||||
|
||||
void ManagedColor::set_color_output(const ColorTransform &color_output)
|
||||
{
|
||||
color_transform_ = color_output;
|
||||
}
|
||||
|
||||
}
|
||||
// ManagedColor has moved to application code
|
||||
// (app/widget/manageddisplay/colorprocessorhandle.h) as part of the C ABI
|
||||
// migration. This translation unit is intentionally left empty (the file is
|
||||
// kept so the existing build rules keep working).
|
||||
|
||||
@@ -22,34 +22,10 @@
|
||||
#ifndef OAK_MANAGEDCOLOR_H
|
||||
#define OAK_MANAGEDCOLOR_H
|
||||
|
||||
#include <olive/core/core.h>
|
||||
|
||||
#include "colortransform.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ManagedColor : public Color {
|
||||
public:
|
||||
ManagedColor();
|
||||
ManagedColor(const double &r, const double &g, const double &b,
|
||||
const double &a = 1.0);
|
||||
ManagedColor(const char *data, const PixelFormat &format,
|
||||
int channel_layout);
|
||||
ManagedColor(const Color &c);
|
||||
|
||||
const QString &color_input() const;
|
||||
void set_color_input(const QString &color_input);
|
||||
|
||||
const ColorTransform &color_output() const;
|
||||
void set_color_output(const ColorTransform &color_output);
|
||||
|
||||
private:
|
||||
QString color_input_;
|
||||
|
||||
ColorTransform color_transform_;
|
||||
};
|
||||
|
||||
}
|
||||
// ManagedColor has moved to application code
|
||||
// (app/widget/manageddisplay/colorprocessorhandle.h) as part of the C ABI
|
||||
// migration: it is a pure UI value type that the engine never uses. This
|
||||
// header is intentionally left empty (the file is kept so the existing
|
||||
// build rules keep working) and must not be included by new code.
|
||||
|
||||
#endif // OAK_MANAGEDCOLOR_H
|
||||
|
||||
@@ -446,6 +446,12 @@ bool RenderWorkerPool::submit_frame(
|
||||
|
||||
ticket->moveToThread(this);
|
||||
|
||||
// Mark the ticket running the moment it is accepted for rendering.
|
||||
// Otherwise there is a window between dispatch and worker pickup where the
|
||||
// ticket still appears idle, and clear_single_frame_renders() -- which only
|
||||
// spares running tickets -- would cancel a frame the viewer just requested.
|
||||
ticket->start();
|
||||
|
||||
QMutexLocker locker(&mutex_);
|
||||
queue_.push_back(job);
|
||||
wait_.wakeOne();
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/***
|
||||
|
||||
Oak - Non-Linear Video Editor
|
||||
Copyright (C) 2026 Oak 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
void HideWorkerDockIcon()
|
||||
{
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
|
||||
}
|
||||
@@ -46,6 +46,11 @@ ProjectImportTask::ProjectImportTask(Folder *folder,
|
||||
set_title(tr("Importing %n file(s)", nullptr, file_count_));
|
||||
}
|
||||
|
||||
ProjectImportTask::~ProjectImportTask()
|
||||
{
|
||||
delete command_;
|
||||
}
|
||||
|
||||
const int &ProjectImportTask::get_file_count() const
|
||||
{
|
||||
return file_count_;
|
||||
|
||||
@@ -37,12 +37,17 @@ class ProjectImportTask : public Task {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProjectImportTask(Folder *folder, const QStringList &filenames);
|
||||
~ProjectImportTask() override;
|
||||
|
||||
const int &get_file_count() const;
|
||||
|
||||
MultiUndoCommand *get_command() const
|
||||
/** Take ownership of the import command. After this call the task no
|
||||
* longer owns (and will not delete) the returned command. */
|
||||
MultiUndoCommand *take_command()
|
||||
{
|
||||
return command_;
|
||||
MultiUndoCommand *c = command_;
|
||||
command_ = nullptr;
|
||||
return c;
|
||||
}
|
||||
|
||||
const QStringList &get_invalid_files() const
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define OAK_PROJECTLOADMANAGER_H
|
||||
|
||||
#include "loadbasetask.h"
|
||||
#include "node/project/serializer/mainwindowlayoutinfo.h"
|
||||
#include "node/project/serializer/serializedlayoutinfo.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define OAK_PROJECTLOADBASETASK_H
|
||||
|
||||
#include "node/project.h"
|
||||
#include "node/project/serializer/mainwindowlayoutinfo.h"
|
||||
#include "node/project/serializer/serializedlayoutinfo.h"
|
||||
#include "task/task.h"
|
||||
|
||||
namespace olive
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
return filename_;
|
||||
}
|
||||
|
||||
const MainWindowLayoutInfo &get_loaded_layout() const
|
||||
const SerializedLayoutInfo &get_loaded_layout() const
|
||||
{
|
||||
return layout_;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
protected:
|
||||
Project *project_;
|
||||
|
||||
MainWindowLayoutInfo layout_;
|
||||
SerializedLayoutInfo layout_;
|
||||
|
||||
private:
|
||||
QString filename_;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define OAK_PROJECTSAVEMANAGER_H
|
||||
|
||||
#include "node/project.h"
|
||||
#include "node/project/serializer/mainwindowlayoutinfo.h"
|
||||
#include "node/project/serializer/serializedlayoutinfo.h"
|
||||
#include "task/task.h"
|
||||
|
||||
namespace olive
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
override_filename_ = filename;
|
||||
}
|
||||
|
||||
void set_layout(const MainWindowLayoutInfo &layout)
|
||||
void set_layout(const SerializedLayoutInfo &layout)
|
||||
{
|
||||
layout_ = layout;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
|
||||
bool use_compression_;
|
||||
|
||||
MainWindowLayoutInfo layout_;
|
||||
SerializedLayoutInfo layout_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
timeline/timelinecommon.h
|
||||
timeline/timelinecoordinate.h
|
||||
timeline/timelinecoordinate.cpp
|
||||
timeline/timelinemarker.h
|
||||
timeline/timelinemarker.cpp
|
||||
timeline/timelineundocommon.h
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/***
|
||||
|
||||
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 "timelinecoordinate.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
TimelineCoordinate::TimelineCoordinate()
|
||||
: track_(Track::k_none, 0)
|
||||
{
|
||||
}
|
||||
|
||||
TimelineCoordinate::TimelineCoordinate(const Rational &frame,
|
||||
const Track::Reference &track)
|
||||
: frame_(frame)
|
||||
, track_(track)
|
||||
{
|
||||
}
|
||||
|
||||
TimelineCoordinate::TimelineCoordinate(const Rational &frame,
|
||||
const Track::Type &track_type,
|
||||
const int &track_index)
|
||||
: frame_(frame)
|
||||
, track_(track_type, track_index)
|
||||
{
|
||||
}
|
||||
|
||||
const Rational &TimelineCoordinate::get_frame() const
|
||||
{
|
||||
return frame_;
|
||||
}
|
||||
|
||||
const Track::Reference &TimelineCoordinate::get_track() const
|
||||
{
|
||||
return track_;
|
||||
}
|
||||
|
||||
void TimelineCoordinate::set_frame(const Rational &frame)
|
||||
{
|
||||
frame_ = frame;
|
||||
}
|
||||
|
||||
void TimelineCoordinate::set_track(const Track::Reference &track)
|
||||
{
|
||||
track_ = track;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/***
|
||||
|
||||
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_TIMELINECOORDINATE_H
|
||||
#define OAK_TIMELINECOORDINATE_H
|
||||
|
||||
#include "node/output/track/track.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class TimelineCoordinate {
|
||||
public:
|
||||
TimelineCoordinate();
|
||||
TimelineCoordinate(const Rational &frame, const Track::Reference &track);
|
||||
TimelineCoordinate(const Rational &frame, const Track::Type &track_type,
|
||||
const int &track_index);
|
||||
|
||||
const Rational &get_frame() const;
|
||||
const Track::Reference &get_track() const;
|
||||
|
||||
void set_frame(const Rational &frame);
|
||||
void set_track(const Track::Reference &track);
|
||||
|
||||
private:
|
||||
Rational frame_;
|
||||
|
||||
Track::Reference track_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // OAK_TIMELINECOORDINATE_H
|
||||
@@ -14,8 +14,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
add_subdirectory(icons)
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
ui/colorcoding.cpp
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2022 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
ui/icons/icons.h
|
||||
ui/icons/icons.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -1,192 +0,0 @@
|
||||
/***
|
||||
|
||||
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 "icons.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
/// Works in conjunction with `genicons.sh` to generate and utilize icons of specific sizes
|
||||
const int icon_size_count = 4;
|
||||
const int icon_sizes[] = { 16, 32, 64, 128 };
|
||||
|
||||
/// Internal icon library for use throughout Olive without having to regenerate constantly
|
||||
QIcon icon::go_to_start;
|
||||
QIcon icon::prev_frame;
|
||||
QIcon icon::play;
|
||||
QIcon icon::pause;
|
||||
QIcon icon::next_frame;
|
||||
QIcon icon::go_to_end;
|
||||
QIcon icon::New;
|
||||
QIcon icon::open;
|
||||
QIcon icon::save;
|
||||
QIcon icon::undo;
|
||||
QIcon icon::redo;
|
||||
QIcon icon::tree_view;
|
||||
QIcon icon::list_view;
|
||||
QIcon icon::icon_view;
|
||||
QIcon icon::tool_pointer;
|
||||
QIcon icon::tool_edit;
|
||||
QIcon icon::tool_ripple;
|
||||
QIcon icon::tool_rolling;
|
||||
QIcon icon::tool_razor;
|
||||
QIcon icon::tool_slip;
|
||||
QIcon icon::tool_slide;
|
||||
QIcon icon::tool_hand;
|
||||
QIcon icon::tool_transition;
|
||||
QIcon icon::tool_track_select;
|
||||
QIcon icon::folder;
|
||||
QIcon icon::sequence;
|
||||
QIcon icon::video;
|
||||
QIcon icon::audio;
|
||||
QIcon icon::image;
|
||||
QIcon icon::mini_map;
|
||||
QIcon icon::tri_up;
|
||||
QIcon icon::tri_left;
|
||||
QIcon icon::tri_down;
|
||||
QIcon icon::tri_right;
|
||||
QIcon icon::text_bold;
|
||||
QIcon icon::text_italic;
|
||||
QIcon icon::text_underline;
|
||||
QIcon icon::text_strikethrough;
|
||||
QIcon icon::text_small_caps;
|
||||
QIcon icon::text_align_left;
|
||||
QIcon icon::text_align_right;
|
||||
QIcon icon::text_align_center;
|
||||
QIcon icon::text_align_justify;
|
||||
QIcon icon::text_align_top;
|
||||
QIcon icon::text_align_bottom;
|
||||
QIcon icon::text_align_middle;
|
||||
QIcon icon::snapping;
|
||||
QIcon icon::zoom_in;
|
||||
QIcon icon::zoom_out;
|
||||
QIcon icon::record;
|
||||
QIcon icon::add;
|
||||
QIcon icon::error;
|
||||
QIcon icon::dir_up;
|
||||
QIcon icon::clock;
|
||||
QIcon icon::diamond;
|
||||
QIcon icon::plus;
|
||||
QIcon icon::minus;
|
||||
QIcon icon::add_effect;
|
||||
QIcon icon::eye_opened;
|
||||
QIcon icon::eye_closed;
|
||||
QIcon icon::lock_opened;
|
||||
QIcon icon::lock_closed;
|
||||
QIcon icon::pencil;
|
||||
QIcon icon::subtitles;
|
||||
QIcon icon::color_picker;
|
||||
|
||||
void icon::load_all(const QString &theme)
|
||||
{
|
||||
go_to_start = create(theme, "prev");
|
||||
prev_frame = create(theme, "rew");
|
||||
play = create(theme, "play");
|
||||
pause = create(theme, "pause");
|
||||
next_frame = create(theme, "ff");
|
||||
go_to_end = create(theme, "next");
|
||||
|
||||
New = create(theme, "new");
|
||||
open = create(theme, "open");
|
||||
save = create(theme, "save");
|
||||
undo = create(theme, "undo");
|
||||
redo = create(theme, "redo");
|
||||
tree_view = create(theme, "treeview");
|
||||
list_view = create(theme, "listview");
|
||||
icon_view = create(theme, "iconview");
|
||||
|
||||
tool_pointer = create(theme, "arrow");
|
||||
tool_edit = create(theme, "beam");
|
||||
tool_ripple = create(theme, "ripple");
|
||||
tool_rolling = create(theme, "rolling");
|
||||
tool_razor = create(theme, "razor");
|
||||
tool_slip = create(theme, "slip");
|
||||
tool_slide = create(theme, "slide");
|
||||
tool_hand = create(theme, "hand");
|
||||
tool_transition = create(theme, "transition-tool");
|
||||
tool_track_select = create(theme, "track-tool");
|
||||
|
||||
folder = create(theme, "folder");
|
||||
sequence = create(theme, "sequence");
|
||||
video = create(theme, "videosource");
|
||||
audio = create(theme, "audiosource");
|
||||
image = create(theme, "imagesource");
|
||||
|
||||
mini_map = create(theme, "map");
|
||||
|
||||
tri_up = create(theme, "tri-up");
|
||||
tri_left = create(theme, "tri-left");
|
||||
tri_down = create(theme, "tri-down");
|
||||
tri_right = create(theme, "tri-right");
|
||||
|
||||
text_bold = create(theme, "text-bold");
|
||||
text_italic = create(theme, "text-italic");
|
||||
text_underline = create(theme, "text-underline");
|
||||
text_strikethrough = create(theme, "text-strikethrough");
|
||||
text_small_caps = create(theme, "text-small-caps");
|
||||
text_align_left = create(theme, "align-left");
|
||||
text_align_right = create(theme, "align-right");
|
||||
text_align_center = create(theme, "align-center");
|
||||
text_align_justify = create(theme, "align-justify-all");
|
||||
text_align_top = create(theme, "align-v-top");
|
||||
text_align_bottom = create(theme, "align-v-bottom");
|
||||
text_align_middle = create(theme, "align-v-middle");
|
||||
|
||||
snapping = create(theme, "magnet");
|
||||
zoom_in = create(theme, "zoomin");
|
||||
zoom_out = create(theme, "zoomout");
|
||||
record = create(theme, "record");
|
||||
add = create(theme, "add-button");
|
||||
error = create(theme, "error");
|
||||
dir_up = create(theme, "dirup");
|
||||
clock = create(theme, "clock");
|
||||
diamond = create(theme, "diamond");
|
||||
plus = create(theme, "plus");
|
||||
minus = create(theme, "minus");
|
||||
add_effect = create(theme, "add-effect");
|
||||
color_picker = create(theme, "color-picker");
|
||||
|
||||
eye_opened = create(theme, "eye-opened");
|
||||
eye_closed = create(theme, "eye-closed");
|
||||
lock_opened = create(theme, "lock-opened");
|
||||
lock_closed = create(theme, "lock-closed");
|
||||
|
||||
pencil = create(theme, "text-edit");
|
||||
subtitles = create(theme, "subtitles");
|
||||
}
|
||||
|
||||
QIcon icon::create(const QString &theme, const QString &name)
|
||||
{
|
||||
QIcon icon;
|
||||
|
||||
for (int i = 0; i < icon_size_count; i++) {
|
||||
icon.addFile(QStringLiteral("%1/png/%2.%3.png")
|
||||
.arg(theme, name, QString::number(icon_sizes[i])),
|
||||
QSize(icon_sizes[i], icon_sizes[i]), QIcon::Normal);
|
||||
icon.addFile(QStringLiteral("%1/png/%2.%3.disabled.png")
|
||||
.arg(theme, name, QString::number(icon_sizes[i])),
|
||||
QSize(icon_sizes[i], icon_sizes[i]), QIcon::Disabled);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/***
|
||||
|
||||
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_ICONS_H
|
||||
#define OAK_ICONS_H
|
||||
|
||||
#include <QIcon>
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
namespace olive
|
||||
{
|
||||
|
||||
namespace icon
|
||||
{
|
||||
|
||||
// Playback Icons
|
||||
extern QIcon go_to_start;
|
||||
extern QIcon prev_frame;
|
||||
extern QIcon play;
|
||||
extern QIcon pause;
|
||||
extern QIcon next_frame;
|
||||
extern QIcon go_to_end;
|
||||
|
||||
// Project Management Toolbar Icons
|
||||
extern QIcon New;
|
||||
extern QIcon open;
|
||||
extern QIcon save;
|
||||
extern QIcon undo;
|
||||
extern QIcon redo;
|
||||
extern QIcon tree_view;
|
||||
extern QIcon list_view;
|
||||
extern QIcon icon_view;
|
||||
|
||||
// Tool Icons
|
||||
extern QIcon tool_pointer;
|
||||
extern QIcon tool_edit;
|
||||
extern QIcon tool_ripple;
|
||||
extern QIcon tool_rolling;
|
||||
extern QIcon tool_razor;
|
||||
extern QIcon tool_slip;
|
||||
extern QIcon tool_slide;
|
||||
extern QIcon tool_hand;
|
||||
extern QIcon tool_transition;
|
||||
extern QIcon tool_track_select;
|
||||
|
||||
// Project Icons
|
||||
extern QIcon folder;
|
||||
extern QIcon sequence;
|
||||
extern QIcon video;
|
||||
extern QIcon audio;
|
||||
extern QIcon image;
|
||||
|
||||
// Node Icons
|
||||
extern QIcon mini_map;
|
||||
|
||||
// Triangle Arrows
|
||||
extern QIcon tri_up;
|
||||
extern QIcon tri_left;
|
||||
extern QIcon tri_down;
|
||||
extern QIcon tri_right;
|
||||
|
||||
// Text
|
||||
extern QIcon text_bold;
|
||||
extern QIcon text_italic;
|
||||
extern QIcon text_underline;
|
||||
extern QIcon text_strikethrough;
|
||||
extern QIcon text_small_caps;
|
||||
extern QIcon text_align_left;
|
||||
extern QIcon text_align_right;
|
||||
extern QIcon text_align_center;
|
||||
extern QIcon text_align_justify;
|
||||
extern QIcon text_align_top;
|
||||
extern QIcon text_align_bottom;
|
||||
extern QIcon text_align_middle;
|
||||
|
||||
// Miscellaneous Icons
|
||||
extern QIcon snapping;
|
||||
extern QIcon zoom_in;
|
||||
extern QIcon zoom_out;
|
||||
extern QIcon record;
|
||||
extern QIcon add;
|
||||
extern QIcon error;
|
||||
extern QIcon dir_up;
|
||||
extern QIcon clock;
|
||||
extern QIcon diamond;
|
||||
extern QIcon plus;
|
||||
extern QIcon minus;
|
||||
extern QIcon add_effect;
|
||||
extern QIcon eye_opened;
|
||||
extern QIcon eye_closed;
|
||||
extern QIcon lock_opened;
|
||||
extern QIcon lock_closed;
|
||||
extern QIcon pencil;
|
||||
extern QIcon subtitles;
|
||||
extern QIcon color_picker;
|
||||
|
||||
/**
|
||||
* @brief Create an icon object loaded from file
|
||||
*
|
||||
* Using `name`, this function will load icon files to create an icon object that can be used throughout the
|
||||
* application.
|
||||
*
|
||||
* Olive's icons are stored in a very specific format. They are all sourced from SVGs, but stored as PNGs of various
|
||||
* sizes. See `app/ui/icons/genicons.sh`, as this script not only generates the multiple sizes but also the QRC file
|
||||
* used to compile the icons into the executable.
|
||||
*
|
||||
* This function is heavily tied into `genicons.sh` and will load all the different sized images (using the same
|
||||
* filename formatting and QRC resource directory) that `genicons.sh` generates into one QIcon file. If you change
|
||||
* either this function or `genicons.sh`, you will very likely have to change the other too.
|
||||
*
|
||||
* There is not much reason to call this outside of LoadAll() (which stores icons globally in memory so they don't
|
||||
* have to be reloaded each time a new object needs an icon).
|
||||
*
|
||||
* @param theme
|
||||
*
|
||||
* Name of the theme (used in the URL as the folder to load PNGs from)
|
||||
*
|
||||
* @param name
|
||||
*
|
||||
* Name of the icon (will correspond to the original SVG's filename with no path or extension)
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* A QIcon object containing the various icon sizes loaded from resource
|
||||
*/
|
||||
QIcon create(const QString &theme, const QString &name);
|
||||
|
||||
/**
|
||||
* @brief Methodically load all Olive icons into global variables that can be accessed throughout the application
|
||||
*
|
||||
* It's recommended to load any UI icons here so they're ready at startup and don't need to be re-loaded upon each
|
||||
* use.
|
||||
*/
|
||||
void load_all(const QString &theme);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // OAK_ICONS_H
|
||||
@@ -105,6 +105,42 @@ void UndoStack::push(UndoCommand *command, const QString &name)
|
||||
update_actions();
|
||||
}
|
||||
|
||||
void UndoStack::push_pre_executed(UndoCommand *command, const QString &name)
|
||||
{
|
||||
MultiUndoCommand *mcu = dynamic_cast<MultiUndoCommand *>(command);
|
||||
if (mcu && mcu->child_count() == 0) {
|
||||
delete command;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear any redoable commands
|
||||
this->beginRemoveRows(QModelIndex(), commands_.size(),
|
||||
commands_.size() + undone_commands_.size());
|
||||
if (can_redo()) {
|
||||
for (auto it = undone_commands_.cbegin(); it != undone_commands_.cend();
|
||||
it++) {
|
||||
delete (*it).command;
|
||||
}
|
||||
undone_commands_.clear();
|
||||
}
|
||||
this->endRemoveRows();
|
||||
|
||||
// Push without redoing: the caller already executed the children.
|
||||
this->beginInsertRows(QModelIndex(), commands_.size(), commands_.size());
|
||||
commands_.push_back({ command, name });
|
||||
this->endInsertRows();
|
||||
|
||||
// Delete oldest
|
||||
if (commands_.size() > k_max_undo_commands) {
|
||||
this->beginRemoveRows(QModelIndex(), 0, 0);
|
||||
delete commands_.front().command;
|
||||
commands_.pop_front();
|
||||
this->endRemoveRows();
|
||||
}
|
||||
|
||||
update_actions();
|
||||
}
|
||||
|
||||
void UndoStack::jump(size_t index)
|
||||
{
|
||||
while (commands_.size() > index) {
|
||||
|
||||
@@ -40,6 +40,15 @@ public:
|
||||
|
||||
void push(UndoCommand *command, const QString &name);
|
||||
|
||||
/**
|
||||
* @brief Push a command that has already been executed (redo skipped).
|
||||
*
|
||||
* Used by the facade undo-group: child commands are added to the group
|
||||
* and executed eagerly, then the whole group is pushed with this method
|
||||
* so it is not redone again. Empty commands are discarded.
|
||||
*/
|
||||
void push_pre_executed(UndoCommand *command, const QString &name);
|
||||
|
||||
void jump(size_t index);
|
||||
|
||||
void clear();
|
||||
@@ -78,6 +87,40 @@ public:
|
||||
virtual bool
|
||||
hasChildren(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
// Facade accessors (oakengine/undo.h C ABI): row-based history queries.
|
||||
// Rows 0..done_count()-1 are done commands (commands_ in order), rows
|
||||
// done_count()..command_count()-1 are undone commands (undone_commands_
|
||||
// in order, most recently undone first).
|
||||
int command_count() const
|
||||
{
|
||||
return int(commands_.size() + undone_commands_.size());
|
||||
}
|
||||
|
||||
int done_count() const
|
||||
{
|
||||
return int(commands_.size());
|
||||
}
|
||||
|
||||
bool command_is_done(int row) const
|
||||
{
|
||||
return row >= 0 && row < done_count();
|
||||
}
|
||||
|
||||
QString command_name(int row) const
|
||||
{
|
||||
if (row < 0 || row >= command_count()) {
|
||||
return QString();
|
||||
}
|
||||
if (row < done_count()) {
|
||||
auto it = commands_.begin();
|
||||
std::advance(it, row);
|
||||
return it->name;
|
||||
}
|
||||
auto it = undone_commands_.begin();
|
||||
std::advance(it, row - done_count());
|
||||
return it->name;
|
||||
}
|
||||
|
||||
signals:
|
||||
void index_changed(int i);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user