diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index d3a774c25..ac090737e 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -33,7 +33,8 @@ include(friction-ffmpeg)
add_definitions(-DPROJECT_VERSION="${PROJECT_VERSION}")
if(${LINUX_DEPLOY})
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
+ #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
+ set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
endif()
option(USE_SKIA_SYSTEM_LIBS "Use skia (third-party) system libraries on Linux" ON)
diff --git a/src/app/GUI/extraactions.cpp b/src/app/GUI/extraactions.cpp
index 1aa86d928..4c1304b1c 100644
--- a/src/app/GUI/extraactions.cpp
+++ b/src/app/GUI/extraactions.cpp
@@ -84,7 +84,7 @@ void MainWindow::setupMenuExtras()
}
// add in
{
- const auto act = menu->addAction(QIcon::fromTheme("pivot-align-left"),
+ const auto act = menu->addAction(QIcon::fromTheme("range-in"),
tr("In at ..."));
act->setData("cmd:in");
act->setToolTip(QString("
%1 %2 %3
").arg(tr("Frame In"),
@@ -94,7 +94,7 @@ void MainWindow::setupMenuExtras()
}
// add out
{
- const auto act = menu->addAction(QIcon::fromTheme("pivot-align-right"),
+ const auto act = menu->addAction(QIcon::fromTheme("range-out"),
tr("Out at ..."));
act->setData("cmd:out");
act->setToolTip(QString("%1 %2 %3
").arg(tr("Frame Out"),
@@ -126,7 +126,7 @@ void MainWindow::setupMenuExtras()
cmdAddAction(act);
}
{
- const auto act = menu->addAction(QIcon::fromTheme("trash"/* TODO: find new (blender) icon! */),
+ const auto act = menu->addAction(QIcon::fromTheme("range-clear"),
tr("Clear In/Out"));
connect(act, &QAction::triggered,
this, [this](){
diff --git a/src/app/GUI/mainwindow.cpp b/src/app/GUI/mainwindow.cpp
index d393cef5f..5ee63dcdf 100644
--- a/src/app/GUI/mainwindow.cpp
+++ b/src/app/GUI/mainwindow.cpp
@@ -1126,19 +1126,19 @@ void MainWindow::setupMenuScene()
cmdAddAction(mAddToQueAct);
mSceneMenu->addSeparator();
- mSceneMenu->addAction(QIcon::fromTheme("sequence"),
+ mSceneMenu->addAction(QIcon::fromTheme("range-in"),
tr("Set In"), this, [this]() {
const auto scene = *mDocument.fActiveScene;
if (!scene) { return; }
scene->setFrameIn(true, scene->getCurrentFrame());
});
- mSceneMenu->addAction(QIcon::fromTheme("sequence"),
+ mSceneMenu->addAction(QIcon::fromTheme("range-out"),
tr("Set Out"), this, [this]() {
const auto scene = *mDocument.fActiveScene;
if (!scene) { return; }
scene->setFrameOut(true, scene->getCurrentFrame());
});
- mSceneMenu->addAction(QIcon::fromTheme("sequence"),
+ mSceneMenu->addAction(QIcon::fromTheme("range-clear"),
tr("Clear In/Out"), this, [this]() {
const auto scene = *mDocument.fActiveScene;
if (!scene) { return; }
@@ -1146,7 +1146,7 @@ void MainWindow::setupMenuScene()
scene->setFrameOut(false, 0);
});
mSceneMenu->addSeparator();
- mSceneMenu->addAction(QIcon::fromTheme("dialog-information"),
+ mSceneMenu->addAction(QIcon::fromTheme("markers-add"),
tr("Add Marker"), this, [this]() {
const auto scene = *mDocument.fActiveScene;
if (!scene) { return; }
@@ -1158,7 +1158,7 @@ void MainWindow::setupMenuScene()
if (!scene) { return; }
scene->clearMarkers();
});
- mSceneMenu->addAction(QIcon::fromTheme("dialog-information"),
+ mSceneMenu->addAction(QIcon::fromTheme("markers-edit"),
tr("Edit Markers"), this, [this]() {
openMarkerEditor();
});
diff --git a/src/app/icons b/src/app/icons
index 37e223d07..21e8d76d1 160000
--- a/src/app/icons
+++ b/src/app/icons
@@ -1 +1 @@
-Subproject commit 37e223d07131b162f47dace8086046e826c292dc
+Subproject commit 21e8d76d17befbf7a5b65689f8418b13dc9b13de
diff --git a/src/app/main.cpp b/src/app/main.cpp
index c46ab4b08..4249e1d2a 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -58,6 +58,17 @@ void setDefaultFormat()
//format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
//format.setSwapInterval(0); // Disable vertical refresh syncing
QSurfaceFormat::setDefaultFormat(format);
+
+ const QString oVersion = QString("%1.%2").arg(QString::number(QSurfaceFormat::defaultFormat().version().first),
+ QString::number(QSurfaceFormat::defaultFormat().version().second));
+ const auto oDepth = QSurfaceFormat::defaultFormat().depthBufferSize();
+ const auto oStencil = QSurfaceFormat::defaultFormat().stencilBufferSize();
+ const auto oSamples = QSurfaceFormat::defaultFormat().samples();
+ qWarning() << "OpenGL Format:"
+ << "version" << oVersion.toDouble()
+ << "depth" << oDepth
+ << "stencil" << oStencil
+ << "samples" << oSamples;
}
void generateAlphaMesh(QPixmap& alphaMesh,
diff --git a/src/core/Animators/staticcomplexanimator.cpp b/src/core/Animators/staticcomplexanimator.cpp
index c0cb7e52e..8f69dd5b3 100644
--- a/src/core/Animators/staticcomplexanimator.cpp
+++ b/src/core/Animators/staticcomplexanimator.cpp
@@ -39,9 +39,13 @@ void StaticComplexAnimator::prp_readProperty_impl(eReadStream &src)
{
const auto& children = ca_getChildren();
const auto SVGProperties = QStringList() << "begin event" << "end event";
+ const bool isSubPathEffect = prp_getName() == "sub-path effect";
+
for (const auto& prop : children) {
if (src.evFileVersion() < EvFormat::svgBeginEnd &&
SVGProperties.contains(prop->prp_getName())) { continue; }
+ if (src.evFileVersion() < EvFormat::subPathOffset &&
+ isSubPathEffect && prop->prp_getName() == "offset") { continue; }
prop->prp_readProperty(src);
}
}
diff --git a/src/core/PathEffects/subpatheffect.cpp b/src/core/PathEffects/subpatheffect.cpp
index c527b08dd..e4d281134 100644
--- a/src/core/PathEffects/subpatheffect.cpp
+++ b/src/core/PathEffects/subpatheffect.cpp
@@ -41,9 +41,14 @@ SubPathEffect::SubPathEffect() :
mMax->setValueRange(-999, 999);
mMax->setCurrentBaseValue(100);
+ mOffset = enve::make_shared("offset");
+ mOffset->setValueRange(-999, 999);
+ mOffset->setCurrentBaseValue(0);
+
ca_addChild(mPathWise);
ca_addChild(mMin);
ca_addChild(mMax);
+ ca_addChild(mOffset);
}
class SubPathEffectCaller : public PathEffectCaller {
@@ -121,7 +126,9 @@ void SubPathEffectCaller::apply(SkPath &path) {
stdsptr SubPathEffect::getEffectCaller(
const qreal relFrame, const qreal influence) const {
const bool pathWise = mPathWise->getValue();
- const qreal minFrac = mMin->getEffectiveValue(relFrame)*0.01*influence;
- const qreal maxFrac = mMax->getEffectiveValue(relFrame)*0.01*influence + 1 - influence;
+ const qreal offset = mOffset->getEffectiveValue(relFrame);
+ const qreal minFrac = (mMin->getEffectiveValue(relFrame) + offset) * 0.01 * influence;
+ const qreal maxFrac = (mMax->getEffectiveValue(relFrame) + offset) * 0.01 * influence + 1 - influence;
+
return enve::make_shared(pathWise, minFrac, maxFrac);
}
diff --git a/src/core/PathEffects/subpatheffect.h b/src/core/PathEffects/subpatheffect.h
index cd5f529fa..5f9579fbb 100644
--- a/src/core/PathEffects/subpatheffect.h
+++ b/src/core/PathEffects/subpatheffect.h
@@ -38,6 +38,7 @@ class CORE_EXPORT SubPathEffect : public PathEffect {
qsptr mPathWise;
qsptr mMin;
qsptr mMax;
+ qsptr mOffset;
};
#endif // SUBPATHEFFECT_H
diff --git a/src/core/ReadWrite/evformat.h b/src/core/ReadWrite/evformat.h
index a3c4e54a6..6d584beaa 100644
--- a/src/core/ReadWrite/evformat.h
+++ b/src/core/ReadWrite/evformat.h
@@ -44,6 +44,7 @@ namespace EvFormat {
svgBeginEnd = 29,
formatOptions = 30,
formatOptions2 = 31,
+ subPathOffset = 32,
nextVersion
};
diff --git a/src/scripts/build_vfxplatform_package.sh b/src/scripts/build_vfxplatform_package.sh
index 07e2e0a68..e893a7fdf 100755
--- a/src/scripts/build_vfxplatform_package.sh
+++ b/src/scripts/build_vfxplatform_package.sh
@@ -135,7 +135,8 @@ echo "[Paths]" > ${BUILD}/${FRICTION_PKG}/opt/friction/bin/qt.conf
echo "Prefix = .." >> ${BUILD}/${FRICTION_PKG}/opt/friction/bin/qt.conf
echo "Plugins = plugins" >> ${BUILD}/${FRICTION_PKG}/opt/friction/bin/qt.conf
-(cd ${BUILD}/${FRICTION_PKG}/opt/friction/bin ; patchelf --set-rpath '$ORIGIN/../lib' friction)
+#(cd ${BUILD}/${FRICTION_PKG}/opt/friction/bin ; patchelf --set-rpath '$ORIGIN/../lib' friction)
+
(cd ${BUILD}/${FRICTION_PKG}/opt/friction/lib ;
for so in *.so*; do
patchelf --set-rpath '$ORIGIN' ${so}
diff --git a/src/scripts/git-backup.sh b/src/scripts/git-backup.sh
index 359381361..06c253466 100755
--- a/src/scripts/git-backup.sh
+++ b/src/scripts/git-backup.sh
@@ -7,15 +7,18 @@ DATE=`date +%Y%m%d%H%M`
URL=https://github.com/friction2d
BACKUP_DIR=${DIR}/friction-git-backup-${DATE}
REPOS="
+friction-icon-theme
friction
-friction2d.github.io
skia
-gperftools
-sfntly
+friction2d.github.io
friction-shader-plugins
+friction-sdk
mxe
+friction-svgo
+friction-unit-tests
+gperftools
friction-examples
-friction-icon-theme
+sfntly
"
mkdir -p ${BACKUP_DIR}
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index e262e064f..44c34c13b 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -45,6 +45,7 @@ set(
dialogs/adjustscenedialog.cpp
dialogs/applyexpressiondialog.cpp
dialogs/commandpalette.cpp
+ dialogs/dialog.cpp
dialogs/durationrectsettingsdialog.cpp
dialogs/exportsvgdialog.cpp
dialogs/markereditordialog.cpp
@@ -116,6 +117,7 @@ set(
dialogs/adjustscenedialog.h
dialogs/applyexpressiondialog.h
dialogs/commandpalette.h
+ dialogs/dialog.h
dialogs/durationrectsettingsdialog.h
dialogs/exportsvgdialog.h
dialogs/markereditordialog.h
diff --git a/src/ui/dialogs/dialog.cpp b/src/ui/dialogs/dialog.cpp
new file mode 100644
index 000000000..b92806303
--- /dev/null
+++ b/src/ui/dialogs/dialog.cpp
@@ -0,0 +1,34 @@
+/*
+#
+# Friction - https://friction.graphics
+#
+# Copyright (c) Ole-André Rodlie and contributors
+#
+# 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 .
+#
+# See 'README.md' for more information.
+#
+*/
+
+#include "dialog.h"
+
+using namespace Friction::Ui;
+
+Dialog::Dialog(QWidget *parent)
+ : QDialog(parent)
+{
+#ifdef Q_OS_MAC
+ setWindowFlag(Qt::Tool);
+#endif
+}
diff --git a/src/ui/dialogs/dialog.h b/src/ui/dialogs/dialog.h
new file mode 100644
index 000000000..13fe6f56a
--- /dev/null
+++ b/src/ui/dialogs/dialog.h
@@ -0,0 +1,44 @@
+/*
+#
+# Friction - https://friction.graphics
+#
+# Copyright (c) Ole-André Rodlie and contributors
+#
+# 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 .
+#
+# See 'README.md' for more information.
+#
+*/
+
+#ifndef DIALOG_H
+#define DIALOG_H
+
+#include "ui_global.h"
+
+#include
+
+namespace Friction
+{
+ namespace Ui
+ {
+ class UI_EXPORT Dialog : public QDialog
+ {
+ Q_OBJECT
+ public:
+ explicit Dialog(QWidget *parent = nullptr);
+ };
+ }
+}
+
+#endif // DIALOG_H
diff --git a/src/ui/widgets/framescrollbar.cpp b/src/ui/widgets/framescrollbar.cpp
index f0ecf3d13..77f4d95ad 100644
--- a/src/ui/widgets/framescrollbar.cpp
+++ b/src/ui/widgets/framescrollbar.cpp
@@ -341,17 +341,17 @@ void FrameScrollBar::mousePressEvent(QMouseEvent *event)
bool hasMarker = mCurrentCanvas ? mCurrentCanvas->hasMarker(mCurrentCanvas->getCurrentFrame()) : false;
- const auto setFrameInAct = new QAction(QIcon::fromTheme("sequence"),
+ const auto setFrameInAct = new QAction(QIcon::fromTheme("range-in"),
tr("Set In"), this);
- const auto setFrameOutAct = new QAction(QIcon::fromTheme("sequence"),
+ const auto setFrameOutAct = new QAction(QIcon::fromTheme("range-out"),
tr("Set Out"), this);
- const auto clearFrameOutAct = new QAction(QIcon::fromTheme("trash"),
+ const auto clearFrameOutAct = new QAction(QIcon::fromTheme("range-clear"),
tr("Clear In/Out"), this);
- const auto setMarkerAct = new QAction(QIcon::fromTheme("dialog-information"),
+ const auto setMarkerAct = new QAction(QIcon::fromTheme("markers-add"),
tr(hasMarker ? "Remove Marker" : "Add Marker"), this);
const auto clearMarkersAct = new QAction(QIcon::fromTheme("trash"),
tr("Clear Markers"), this);
- const auto openMarkerEditorAct = new QAction(QIcon::fromTheme("dialog-information"),
+ const auto openMarkerEditorAct = new QAction(QIcon::fromTheme("markers-edit"),
tr("Edit Markers"), this);
const auto splitDurationAct = new QAction(QIcon::fromTheme("cut"),
tr("Split Clip"), this);