diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c5c244368..03d46da51 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,359 +1,350 @@
add_definitions(${Qt5Gui_DEFINITIONS})
SET(KDENLIVE_CXX_FLAGS "${DEFAULT_CXX_FLAGS} -Wall -pedantic -Wextra")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wcast-qual -Wcast-align -Wfloat-equal -Wpointer-arith")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wunreachable-code -Wchar-subscripts -Wcomment -Wformat")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Werror-implicit-function-declaration -Wmain -Wmissing-braces")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wparentheses -Wsequence-point -Wreturn-type -Wswitch")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wuninitialized -Wreorder -Wundef -Wshadow -Wwrite-strings")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wsign-compare -Wconversion")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wmissing-noreturn -Wsign-conversion -Wunused ")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wstrict-aliasing -Wconversion")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wdisabled-optimization")
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wno-undef")
if (KDENLIVE_COMPILER_IS_GNUCXX)
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wlogical-op -Wunsafe-loop-optimizations ")
endif()
SET(KDENLIVE_CXX_FLAGS "${KDENLIVE_CXX_FLAGS} -Wunused-parameter -Wshadow -Wno-variadic-macros -Wno-float-conversion")
if(NOT WIN32)
find_package(PkgConfig QUIET)
execute_process(
COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=mltdatadir mlt-framework
OUTPUT_VARIABLE MLT_DATADIR
RESULT_VARIABLE MLT_DATADIR_failed)
if (NOT MLT_DATADIR_failed)
string(REGEX REPLACE "[\r\n]" "" MLT_DATADIR "${MLT_DATADIR}")
endif()
execute_process(
COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=meltbin mlt-framework
OUTPUT_VARIABLE MLT_MELTBIN
RESULT_VARIABLE MLT_MELTBIN_failed)
if (NOT MLT_MELTBIN_failed)
string(REGEX REPLACE "[\r\n]" "" MLT_MELTBIN "${MLT_MELTBIN}")
endif()
else()
set(MLT_MELTBIN "melt.exe")
set(MLT_DATADIR "../share/mlt")
endif()
configure_file( mlt_config.h.in ${CMAKE_BINARY_DIR}/generated/mlt_config.h )
include_directories( ${CMAKE_BINARY_DIR}/generated/ ) # Make sure it can be included...
option(WITH_JogShuttle "Build Jog/Shuttle support" ON)
set(FFMPEG_SUFFIX "" CACHE STRING "FFmpeg custom suffix")
find_package(LibV4L2)
set_package_properties(LibV4L2 PROPERTIES
DESCRIPTION "Collection of video4linux support libraries"
URL "http://freecode.com/projects/libv4l"
TYPE RUNTIME
PURPOSE "Required for better webcam support")
if(WITH_JogShuttle)
check_include_files(linux/input.h HAVE_LINUX_INPUT_H)
if(HAVE_LINUX_INPUT_H)
set(BUILD_JogShuttle TRUE)
endif(HAVE_LINUX_INPUT_H)
endif()
set_package_properties(OpenGL PROPERTIES
DESCRIPTION "the OpenGL library"
URL ""
TYPE RUNTIME
PURPOSE "")
#if(APPLE)
# macro_log_feature(SDL_FOUND
# "SDL"
# "Cross-platform multimedia library"
# "http://www.libsdl.org"
# TRUE
# )
#endif(APPLE)
# use sane compile flags
add_definitions(
# -DQT_USE_QSTRINGBUILDER
-DQT_NO_CAST_TO_ASCII
# -DQT_NO_CAST_FROM_ASCII
-DQT_STRICT_ITERATORS
-DQT_NO_URL_CAST_FROM_STRING
-DQT_NO_CAST_FROM_BYTEARRAY
# -DQT_USE_FAST_OPERATOR_PLUS
)
install(FILES kdenlivesettings.kcfg DESTINATION ${KCFG_INSTALL_DIR})
kconfig_add_kcfg_files(kdenlive_SRCS kdenlivesettings.kcfgc)
add_subdirectory(abstractmodel)
add_subdirectory(assets)
add_subdirectory(bin)
add_subdirectory(capture)
add_subdirectory(dialogs)
add_subdirectory(doc)
add_subdirectory(dvdwizard)
add_subdirectory(effects)
add_subdirectory(effectslist)
add_subdirectory(jobs)
add_subdirectory(lib)
+add_subdirectory(library)
add_subdirectory(mltcontroller)
add_subdirectory(monitor)
add_subdirectory(profiles)
add_subdirectory(project)
add_subdirectory(qml)
add_subdirectory(scopes)
add_subdirectory(simplekeyframes)
add_subdirectory(timeline2)
add_subdirectory(titler)
add_subdirectory(transitions)
add_subdirectory(utils)
add_subdirectory(widgets)
add_subdirectory(xml)
if (Qt5WebKitWidgets_FOUND)
add_subdirectory(qt-oauth-lib)
endif()
-add_subdirectory(library)
-list(APPEND kdenlive_SRCS
- colortools.cpp
- definitions.cpp
- gentime.cpp
- doc/kthumb.cpp
- mainwindow.cpp
-# renderer.cpp
- statusbarmessagelabel.cpp
- timecode.cpp
- timecodedisplay.cpp
- layoutmanagement.cpp
- hidetitlebars.cpp
- mltconnection.cpp
- core.cpp
- undohelper.cpp
- )
+FILE(GLOB top_SRCS "*.cpp")
+string(REGEX REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/lib/[^;]+;?" "" top_SRCS "${top_SRCS}")
+LIST(REMOVE_ITEM top_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
+list(APPEND kdenlive_SRCS ${top_SRCS})
+
+
ecm_qt_declare_logging_category(kdenlive_SRCS HEADER kdenlive_debug.h IDENTIFIER KDENLIVE_LOG CATEGORY_NAME org.kde.multimedia.kdenlive)
ki18n_wrap_ui(kdenlive_UIS
ui/addtrack_ui.ui
ui/archivewidget_ui.ui
ui/audiospectrum_ui.ui
ui/backupdialog_ui.ui
ui/bezierspline_ui.ui
ui/boolparamwidget_ui.ui
ui/clipdurationdialog_ui.ui
ui/clipproperties_ui.ui
ui/clipspeed_ui.ui
ui/clipstabilize_ui.ui
ui/cliptranscode_ui.ui
ui/collapsiblewidget_ui.ui
ui/colorclip_ui.ui
ui/colorplaneexport_ui.ui
ui/configcapture_ui.ui
ui/configenv_ui.ui
ui/configjogshuttle_ui.ui
ui/configmisc_ui.ui
ui/configproject_ui.ui
ui/configproxy_ui.ui
ui/configsdl_ui.ui
ui/configtimeline_ui.ui
ui/configtranscode_ui.ui
ui/cutjobdialog_ui.ui
ui/dvdwizardchapters_ui.ui
ui/dvdwizardmenu_ui.ui
ui/dvdwizardstatus_ui.ui
ui/dvdwizardvob_ui.ui
ui/effectlist_ui.ui
ui/fontval_ui.ui
ui/freesound_ui.ui
ui/geometrywidget_ui.ui
ui/gradientedit_ui.ui
ui/histogram_ui.ui
ui/keyframedialog_ui.ui
ui/keyframeeditor_ui.ui
ui/keyframewidget_ui.ui
ui/keywordval_ui.ui
ui/listparamwidget_ui.ui
ui/logindialog_ui.ui
ui/managecaptures_ui.ui
ui/manageencodingprofile_ui.ui
ui/markerdialog_ui.ui
ui/missingclips_ui.ui
ui/monitoreditwidget_ui.ui
ui/profiledialog_ui.ui
ui/projectsettings_ui.ui
ui/qtextclip_ui.ui
ui/recmonitor_ui.ui
ui/renderwidget_ui.ui
ui/rgbparade_ui.ui
ui/saveprofile_ui.ui
ui/scenecutdialog_ui.ui
ui/selectivecolor_ui.ui
ui/slideshowclip_ui.ui
ui/smconfig_ui.ui
ui/spacerdialog_ui.ui
ui/spectrogram_ui.ui
ui/templateclip_ui.ui
ui/titlewidget_ui.ui
ui/tracksconfigdialog_ui.ui
ui/transitionsettings_ui.ui
ui/unicodewidget_ui.ui
ui/urlval_ui.ui
ui/vectorscope_ui.ui
ui/waveform_ui.ui
ui/wipeval_ui.ui
ui/wizardcapture_ui.ui
ui/wizardcheck_ui.ui
ui/wizardextra_ui.ui
ui/wizardmltcheck_ui.ui
ui/wizardstandard_ui.ui
)
if(BUILD_JogShuttle)
list(APPEND kdenlive_SRCS
jogshuttle/jogmanager.cpp
jogshuttle/jogaction.cpp
jogshuttle/jogshuttle.cpp
jogshuttle/jogshuttleconfig.cpp
)
endif()
# Sets the icon on Windows and OSX
file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/*-apps-kdenlive.png")
ecm_add_app_icon(kdenlive_SRCS ICONS ${ICONS_SRCS})
qt5_add_dbus_adaptor(kdenlive_SRCS
org.kdenlive.MainWindow.xml
mainwindow.h
MainWindow
)
qt5_add_resources(kdenlive_extra_SRCS icons.qrc ui/resources.qrc uiresources.qrc)
qt5_wrap_cpp(kdenlive_MOC definitions.h)
add_library(kdenliveLib STATIC ${kdenlive_SRCS} ${kdenlive_UIS} ${kdenlive_MOC})
add_executable(kdenlive
main.cpp
${kdenlive_extra_SRCS}
)
target_link_libraries(kdenlive
kdenliveLib
)
# To compile kiss_fft.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c99")
# KDE definitions and include directories *must* always come first, Qt follows
# (to avoid breaking builds when KDE and/or Qt are installed to different
# prefixes).
include_directories(
${CMAKE_BINARY_DIR}
${MLT_INCLUDE_DIR}
${MLTPP_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/lib/external
${CMAKE_CURRENT_SOURCE_DIR}/lib
)
# Adds Qt definitions and include directories, and sets QT_LIBRARIES according
# to the components requested in find_package().
#include(${QT_USE_FILE})
target_link_libraries(kdenliveLib
KF5::WidgetsAddons
KF5::Archive
KF5::CoreAddons
KF5::KIOCore
KF5::KIOFileWidgets
KF5::KIOWidgets
KF5::NotifyConfig
KF5::NewStuff
KF5::DBusAddons
KF5::XmlGui
KF5::GuiAddons
KF5::Notifications
KF5::TextWidgets
KF5::Declarative
KF5::IconThemes
KF5::Solid
Qt5::Svg
Qt5::Quick
Qt5::QuickWidgets
Qt5::Concurrent
${OPENGL_LIBRARIES}
${OPENGLES_LIBRARIES}
${MLT_LIBRARIES}
${MLTPP_LIBRARIES}
${CMAKE_DL_LIBS}
${CMAKE_THREAD_LIBS_INIT}
kiss_fft
RTTR::Core
)
set_property(TARGET kdenliveLib PROPERTY CXX_STANDARD 14)
set_target_properties(kdenliveLib PROPERTIES COMPILE_FLAGS "${KDENLIVE_CXX_FLAGS}")
message(STATUS "Found MLT++: ${MLTPP_LIBRARIES}")
if (KF5_FILEMETADATA)
add_definitions(-DKF5_USE_FILEMETADATA)
target_link_libraries(kdenliveLib KF5::FileMetaData)
endif()
if (DRMINGW_FOUND)
add_definitions(-DUSE_DRMINGW)
target_link_libraries(kdenlive ${DRMINGW_LIBRARY})
elseif (KF5Crash_FOUND)
add_definitions(-DKF5_USE_CRASH)
target_link_libraries(kdenlive KF5::Crash)
endif()
if (KF5_PURPOSE)
add_definitions(-DKF5_USE_PURPOSE)
target_link_libraries(kdenliveLib KF5::Purpose KF5::PurposeWidgets)
endif()
if (KF5_PURPOSE)
add_definitions(-DKF5_USE_PURPOSE)
target_link_libraries(kdenlive KF5::Purpose KF5::PurposeWidgets)
endif()
if (Qt5WebKitWidgets_FOUND)
message(STATUS "Found Qt5 WebKitWidgets. You can use your Freesound.org credentials to download files")
add_definitions(-DQT5_USE_WEBKIT)
target_link_libraries(kdenliveLib Qt5::WebKitWidgets)
else()
message(STATUS "Qt5 WebKitWidgets not found. You cannot use your Freesound.org credentials, only preview files can be downloaded from the Online Resources Widget")
endif()
if(Q_WS_X11)
include_directories(${X11_Xlib_INCLUDE_PATH})
target_link_libraries(kdenliveLib ${X11_LIBRARIES})
endif(Q_WS_X11)
if(SDL2_FOUND)
target_link_libraries(kdenliveLib ${SDL2_LIBRARY})
elseif(SDL_FOUND)
target_link_libraries(kdenliveLib ${SDL_LIBRARY})
endif(SDL2_FOUND)
if(LIBV4L2_FOUND)
include_directories(${LIBV4L2_INCLUDE_DIR})
target_link_libraries(kdenliveLib ${LIBV4L2_LIBRARY})
add_definitions(-DUSE_V4L)
endif()
if(BUILD_JogShuttle)
add_definitions(-DUSE_JOGSHUTTLE)
target_link_libraries(kdenliveLib
media_ctrl
)
endif()
set_property(SOURCE definitions.h PROPERTY SKIP_AUTOMOC ON)
install(TARGETS kdenlive DESTINATION ${BIN_INSTALL_DIR})
install(FILES kdenliveui.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/kdenlive)
diff --git a/src/assets/view/widgets/curves/bezier/beziersplineeditor.h b/src/assets/view/widgets/curves/bezier/beziersplineeditor.h
index 84428d533..af41515c2 100644
--- a/src/assets/view/widgets/curves/bezier/beziersplineeditor.h
+++ b/src/assets/view/widgets/curves/bezier/beziersplineeditor.h
@@ -1,74 +1,74 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive 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 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive 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 Kdenlive. If not, see . *
***************************************************************************/
#ifndef BEZIERSPLINEEDITOR_H
#define BEZIERSPLINEEDITOR_H
+#include "../abstractcurvewidget.h"
#include "bpoint.h"
#include "colortools.h"
#include "cubicbezierspline.h"
-#include "effectstack/widgets/curves/abstractcurvewidget.h"
#include
class BezierSplineEditor : public AbstractCurveWidget
{
Q_OBJECT
public:
typedef BPoint Point_t;
explicit BezierSplineEditor(QWidget *parent = nullptr);
~BezierSplineEditor();
/** @brief Sets the property showAllHandles to @param show.
*
* showAllHandles: Whether to show only handles for the selected point for all points.
*/
void setShowAllHandles(bool show);
QList getPoints() const override;
public slots:
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
private:
/** Whether to show handles for all points or only for the selected one. */
bool m_showAllHandles;
BPoint::PointType m_currentPointType;
double m_grabOffsetX;
double m_grabOffsetY;
/** selected point before it was modified by dragging (at the time of the mouse press) */
BPoint m_grabPOriginal;
/** point with the index currentPointIndex + 1 at the time of the mouse press */
BPoint m_grabPNext;
/** point with the index currentPointIndex - 1 at the time of the mouse press */
BPoint m_grabPPrevious;
/** @brief Finds the point nearest to @param p and returns it's index.
* @param sel Is filled with the type of the closest point (h1, p, h2)
*
* If no point is near enough -1 is returned. */
int nearestPointInRange(const QPointF &p, int wWidth, int wHeight, BPoint::PointType *sel);
};
#endif
diff --git a/src/assets/view/widgets/curves/cubic/kis_curve_widget.h b/src/assets/view/widgets/curves/cubic/kis_curve_widget.h
index 99e7bfec3..85387b9da 100644
--- a/src/assets/view/widgets/curves/cubic/kis_curve_widget.h
+++ b/src/assets/view/widgets/curves/cubic/kis_curve_widget.h
@@ -1,106 +1,106 @@
/*
* Copyright (c) 2005 Casper Boemann
* Copyright (c) 2009 Dmitry Kazakov
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_CURVE_WIDGET_H
#define KIS_CURVE_WIDGET_H
// Qt includes.
#include
+#include "../abstractcurvewidget.h"
#include "colortools.h"
-#include "effectstack/widgets/curves/abstractcurvewidget.h"
#include "kis_cubic_curve.h"
class QEvent;
class QMouseEvent;
class QObject;
class QPaintEvent;
class QPixmap;
class QSpinBox;
/**
* KisCurveWidget is a widget that shows a single curve that can be edited
* by the user. The user can grab the curve and move it; this creates
* a new control point. Control points can be deleted by selecting a point
* and pressing the delete key.
*
* (From: http://techbase.kde.org/Projects/Widgets_and_Classes#KisCurveWidget)
* KisCurveWidget allows editing of spline based y=f(x) curves. Handy for cases
* where you want the user to control such things as tablet pressure
* response, color transformations, acceleration by time, aeroplane lift
*by angle of attack.
*/
class KisCurveWidget : public AbstractCurveWidget
{
Q_OBJECT
public:
typedef QPointF Point_t;
/**
* Create a new curve widget with a default curve, that is a straight
* line from bottom-left to top-right.
*/
explicit KisCurveWidget(QWidget *parent = nullptr);
virtual ~KisCurveWidget();
QSize sizeHint() const override;
protected:
void paintEvent(QPaintEvent *) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
public:
/**
* Handy function that creates new point in the middle
* of the curve and sets focus on the m_intIn field,
* so the user can move this point anywhere in a moment
*/
void addPointInTheMiddle();
void setCurve(KisCubicCurve &&curve);
QList getPoints() const override;
private:
double io2sp(int x) const;
int sp2io(double x) const;
bool jumpOverExistingPoints(QPointF &pt, int skipIndex);
int nearestPointInRange(QPointF pt, int wWidth, int wHeight) const;
/* Dragging variables */
double m_grabOffsetX;
double m_grabOffsetY;
double m_grabOriginalX;
double m_grabOriginalY;
QPointF m_draggedAwayPoint;
int m_draggedAwayPointIndex;
bool m_guideVisible;
QColor m_colorGuide;
/* Working range of them */
int m_inOutMin;
int m_inOutMax;
};
#endif /* KIS_CURVE_WIDGET_H */
diff --git a/src/doc/CMakeLists.txt b/src/doc/CMakeLists.txt
index 0fe43ef19..1506a57ca 100644
--- a/src/doc/CMakeLists.txt
+++ b/src/doc/CMakeLists.txt
@@ -1,8 +1,9 @@
set(kdenlive_SRCS
${kdenlive_SRCS}
doc/documentchecker.cpp
doc/documentvalidator.cpp
doc/kdenlivedoc.cpp
+ doc/kthumb.cpp
doc/docundostack.cpp
PARENT_SCOPE)
diff --git a/src/effectstack/CMakeLists.txt b/src/effectstack/CMakeLists.txt
deleted file mode 100644
index eb5e3d16b..000000000
--- a/src/effectstack/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_subdirectory(widgets/curves)
-set(kdenlive_SRCS
- ${kdenlive_SRCS}
-# effectstack/abstractcollapsiblewidget.cpp
-# effectstack/collapsibleeffect.cpp
-# effectstack/collapsiblegroup.cpp
-# effectstack/effectstackedit.cpp
-# effectstack/effectstackview2.cpp
- effectstack/graphicsscenerectmove.cpp
- effectstack/keyframehelper.cpp
- effectstack/animkeyframeruler.cpp
- PARENT_SCOPE)
-
diff --git a/src/effectstack/animkeyframeruler.cpp b/src/effectstack/animkeyframeruler.cpp
deleted file mode 100644
index ad117567b..000000000
--- a/src/effectstack/animkeyframeruler.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
- * *
- * 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 2 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, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#include "animkeyframeruler.h"
-
-#include "definitions.h"
-#include "kdenlivesettings.h"
-
-#include "mlt++/MltAnimation.h"
-
-#include
-#include
-
-#include
-#include
-#include
-
-const int margin = 5;
-
-#define SEEK_INACTIVE (-1)
-
-AnimKeyframeRuler::AnimKeyframeRuler(int min, int max, QWidget *parent)
- : QWidget(parent)
- , frameLength(max - min)
- , m_position(0)
- , m_scale(0)
- , m_movingKeyframe(false)
- , m_movingKeyframePos(-1)
- , m_movingKeyframeType(mlt_keyframe_linear)
- , m_hoverKeyframe(-1)
- , m_selectedKeyframe(-1)
- , m_seekPosition(SEEK_INACTIVE)
- , m_attachedToEnd(-2)
-{
- setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
- setMouseTracking(true);
- QPalette p = palette();
- m_size = QFontInfo(font()).pixelSize() * 1.8;
- m_lineHeight = m_size / 2;
- setMinimumHeight(m_size);
- setMaximumHeight(m_size);
- KColorScheme scheme(p.currentColorGroup(), KColorScheme::Window);
- m_selected = palette().highlight().color();
- m_keyframe = scheme.foreground(KColorScheme::LinkText).color();
-}
-
-void AnimKeyframeRuler::setRange(int in, int out)
-{
- frameLength = out - in;
- update();
-}
-
-void AnimKeyframeRuler::updateKeyframes(const QVector &keyframes, const QVector &types, int attachToEnd)
-{
- m_keyframes = keyframes;
- m_keyframeTypes = types;
- m_attachedToEnd = attachToEnd;
- update();
-}
-
-// virtual
-void AnimKeyframeRuler::mousePressEvent(QMouseEvent *event)
-{
- m_hoverKeyframe = -1;
- if (event->button() != Qt::LeftButton) {
- QWidget::mousePressEvent(event);
- return;
- }
- int xPos = event->x() - margin;
- int headOffset = m_lineHeight / 1.5;
- if (event->y() < m_lineHeight) {
- // check if we want to move a keyframe
- for (int i = 0; i < m_keyframes.count(); i++) {
- int kfrPos = m_keyframes.at(i);
- if (kfrPos * m_scale - xPos > headOffset) {
- break;
- }
- if (qAbs(kfrPos * m_scale - xPos) < headOffset) {
- m_hoverKeyframe = kfrPos;
- setCursor(Qt::PointingHandCursor);
- event->accept();
- m_dragStart = event->pos();
- return;
- }
- }
- }
- int seekRequest = xPos / m_scale;
- if (seekRequest != m_position) {
- m_seekPosition = seekRequest;
- emit requestSeek(m_seekPosition);
- update();
- }
-}
-
-void AnimKeyframeRuler::leaveEvent(QEvent *event)
-{
- Q_UNUSED(event)
- if (m_hoverKeyframe != -1) {
- m_hoverKeyframe = -1;
- update();
- }
-}
-
-void AnimKeyframeRuler::setActiveKeyframe(int frame)
-{
- m_selectedKeyframe = frame;
- update();
-}
-
-int AnimKeyframeRuler::activeKeyframe() const
-{
- return m_selectedKeyframe;
-}
-
-// virtual
-void AnimKeyframeRuler::mouseMoveEvent(QMouseEvent *event)
-{
- int xPos = event->x() - margin;
- int headOffset = m_lineHeight / 1.5;
- if (event->buttons() == Qt::NoButton) {
- if (qAbs(m_position * m_scale - xPos) < m_lineHeight && event->y() >= m_lineHeight) {
- // Mouse over time cursor
- if (m_hoverKeyframe != -2) {
- m_hoverKeyframe = -2;
- update();
- }
- event->accept();
- return;
- }
- if (event->y() < m_lineHeight) {
- // check if we want to move a keyframe
- for (int i = 0; i < m_keyframes.count(); i++) {
- int kfrPos = m_keyframes.at(i);
- if (kfrPos * m_scale - xPos > headOffset) {
- break;
- }
- if (qAbs(kfrPos * m_scale - xPos) < headOffset) {
- m_hoverKeyframe = kfrPos;
- setCursor(Qt::PointingHandCursor);
- update();
- event->accept();
- return;
- }
- }
- }
- if (m_hoverKeyframe != -1) {
- m_hoverKeyframe = -1;
- setCursor(Qt::ArrowCursor);
- update();
- }
- event->accept();
- return;
- }
- if (!m_dragStart.isNull() || m_movingKeyframe) {
- if (!m_movingKeyframe) {
- if ((QPoint(xPos, event->y()) - m_dragStart).manhattanLength() < QApplication::startDragDistance()) {
- return;
- }
- m_movingKeyframe = true;
- int index = m_keyframes.indexOf(m_hoverKeyframe);
- m_movingKeyframeType = m_keyframeTypes.value(index);
- m_keyframeTypes.removeAt(index);
- m_keyframes.removeAt(index);
- m_dragStart = QPoint();
- }
- m_movingKeyframePos = qBound(0, (int)(xPos / m_scale), frameLength);
- if ((event->modifiers() & Qt::ShiftModifier) != 0u) {
- m_seekPosition = m_movingKeyframePos;
- emit requestSeek(m_seekPosition);
- } else if (KdenliveSettings::snaptopoints() && qAbs(m_movingKeyframePos - m_position) < headOffset / m_scale) {
- m_movingKeyframePos = m_position;
- }
- update();
- return;
- }
- m_seekPosition = (int)(xPos / m_scale);
- m_seekPosition = qMax(0, m_seekPosition);
- m_seekPosition = qMin(frameLength, m_seekPosition);
- m_hoverKeyframe = -2;
- emit requestSeek(m_seekPosition);
- update();
-}
-
-void AnimKeyframeRuler::mouseDoubleClickEvent(QMouseEvent *event)
-{
- QWidget::mouseDoubleClickEvent(event);
- if (event->button() == Qt::LeftButton) {
- // check if we want to move a keyframe
- int xPos = event->x() - margin;
- int headOffset = m_lineHeight / 1.5;
- for (int i = 0; i < m_keyframes.count(); i++) {
- int kfrPos = m_keyframes.at(i);
- if (kfrPos * m_scale - xPos > headOffset) {
- break;
- }
- if (qAbs(kfrPos * m_scale - xPos) < headOffset) {
- // There is already a keyframe close to mouse click
- emit removeKeyframe(kfrPos);
- return;
- }
- }
- // add new keyframe
- int newFrame = xPos / m_scale;
- m_selectedKeyframe = newFrame;
- emit addKeyframe(newFrame);
- }
-}
-
-// virtual
-void AnimKeyframeRuler::mouseReleaseEvent(QMouseEvent *event)
-{
- setCursor(Qt::ArrowCursor);
- QWidget::mouseReleaseEvent(event);
- if (m_movingKeyframe) {
- m_selectedKeyframe = m_movingKeyframePos;
- update();
- emit moveKeyframe(m_hoverKeyframe, m_movingKeyframePos);
- } else if (!m_dragStart.isNull()) {
- // Seek to selected keyframe
- m_seekPosition = m_hoverKeyframe;
- m_selectedKeyframe = m_hoverKeyframe;
- m_dragStart = QPoint();
- update();
- emit requestSeek(m_seekPosition);
- }
- m_movingKeyframe = false;
- m_hoverKeyframe = -1;
- m_movingKeyframePos = -1;
-}
-
-// virtual
-void AnimKeyframeRuler::wheelEvent(QWheelEvent *e)
-{
- int pos = m_seekPosition == SEEK_INACTIVE ? m_position : m_seekPosition;
- if (e->delta() < 0) {
- --pos;
- } else {
- ++pos;
- }
- m_seekPosition = pos;
- emit requestSeek(m_seekPosition);
- update();
-}
-
-// virtual
-void AnimKeyframeRuler::paintEvent(QPaintEvent *e)
-{
- QPainter p(this);
- p.setRenderHints(QPainter::Antialiasing);
- const QRectF clipRect = e->rect();
- p.setClipRect(clipRect);
- m_scale = (double)(width() - 2 * margin) / frameLength;
- int headOffset = m_lineHeight / 1.5;
- if (m_attachedToEnd > -2) {
- int negStart = margin + m_attachedToEnd * m_scale;
- QRect negRect(negStart, 0, width() - margin - negStart, m_lineHeight + (headOffset / 2));
- QColor neg(Qt::darkYellow);
- neg.setAlpha(140);
- p.fillRect(negRect, neg);
- }
-
- QPolygon polygon;
- p.setPen(palette().text().color());
- for (int i = 0; i < m_keyframes.count(); i++) {
- int pos = m_keyframes.at(i);
- // draw keyframes
- if (pos == m_selectedKeyframe) {
- p.setBrush(Qt::red);
- } else if (pos == m_hoverKeyframe) {
- // active keyframe
- p.setBrush(m_selected);
- } else {
- // p.setBrush(m_keyframeRelatives.at(i) >= 0 ? palette().text() : Qt::yellow);
- p.setBrush(palette().text());
- }
- int scaledPos = margin + pos * m_scale;
- p.drawLine(scaledPos, headOffset, scaledPos, m_size);
- mlt_keyframe_type type = (mlt_keyframe_type)m_keyframeTypes.at(i);
- switch (type) {
- case mlt_keyframe_discrete:
- p.drawRect(scaledPos - headOffset / 2, 0, headOffset, headOffset);
- break;
- case mlt_keyframe_linear:
- polygon.setPoints(3, scaledPos, 0, scaledPos + headOffset / 2, headOffset, scaledPos - headOffset / 2, headOffset);
- p.drawPolygon(polygon);
- break;
- default:
- p.drawEllipse(scaledPos - headOffset / 2, 0, headOffset, headOffset);
- break;
- }
- }
- if (m_movingKeyframe) {
- p.setBrush(m_selected);
- int scaledPos = margin + (int)(m_movingKeyframePos * m_scale);
- // draw keyframes
- p.drawLine(scaledPos, headOffset, scaledPos, m_size);
- switch ((int)m_movingKeyframeType) {
- case mlt_keyframe_discrete:
- p.drawRect(scaledPos - headOffset / 2, 0, headOffset, headOffset);
- break;
- case mlt_keyframe_linear:
- polygon.setPoints(3, scaledPos, 0, scaledPos + headOffset / 2, headOffset, scaledPos - headOffset / 2, headOffset);
- p.drawPolygon(polygon);
- break;
- default:
- p.drawEllipse(scaledPos - headOffset / 2, 0, headOffset, headOffset);
- break;
- }
- p.setBrush(m_keyframe);
- }
- p.setPen(palette().text().color());
- p.drawLine(margin, m_lineHeight + (headOffset / 2), width() - margin - 1, m_lineHeight + (headOffset / 2));
- p.drawLine(margin, m_lineHeight - headOffset, margin, m_lineHeight + headOffset);
- p.drawLine(width() - margin, m_lineHeight - headOffset, width() - margin, m_lineHeight + headOffset);
- p.setPen(Qt::NoPen);
- // draw pointer
- if (m_seekPosition != SEEK_INACTIVE) {
- p.fillRect(margin + m_seekPosition * m_scale - 1, 0, 3, height(), palette().linkVisited());
- }
- QPolygon pa(3);
- const int cursor = margin + m_position * m_scale;
- int cursorwidth = (m_size - (m_lineHeight + headOffset / 2)) / 2 + 1;
- pa.setPoints(3, cursor - cursorwidth, m_size, cursor + cursorwidth, m_size, cursor, m_lineHeight + (headOffset / 2) + 1);
- if (m_hoverKeyframe == -2) {
- p.setBrush(palette().highlight());
- } else {
- p.setBrush(palette().text());
- }
- p.drawPolygon(pa);
-}
-
-int AnimKeyframeRuler::position() const
-{
- if (m_seekPosition == SEEK_INACTIVE) {
- return m_position;
- }
- return m_seekPosition;
-}
-
-void AnimKeyframeRuler::setValue(const int pos)
-{
- if (pos == m_position) {
- return;
- }
- if (pos == m_seekPosition) {
- m_seekPosition = SEEK_INACTIVE;
- }
- m_position = pos;
- if (m_movingKeyframePos >= 0) {
- return;
- }
- update();
-}
diff --git a/src/effectstack/animkeyframeruler.h b/src/effectstack/animkeyframeruler.h
deleted file mode 100644
index 8e931c4ed..000000000
--- a/src/effectstack/animkeyframeruler.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
- * *
- * 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 2 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, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#ifndef ANIMKEYFRAMERULER_H
-#define ANIMKEYFRAMERULER_H
-
-#include
-
-#include "timecode.h"
-
-namespace Mlt {
-}
-
-class AnimKeyframeRuler : public QWidget
-{
- Q_OBJECT
-public:
- explicit AnimKeyframeRuler(int min, int max, QWidget *parent = nullptr);
- int position() const;
- int frameLength;
- void updateKeyframes(const QVector &keyframes, const QVector &types, int attachToEnd);
- void setActiveKeyframe(int frame);
- int activeKeyframe() const;
- void setRange(int in, int out);
-
-protected:
- void paintEvent(QPaintEvent * /*e*/) override;
- void wheelEvent(QWheelEvent *e) override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void mouseDoubleClickEvent(QMouseEvent *event) override;
- void leaveEvent(QEvent *event) override;
-
-private:
- /** @brief Holds a list of frame positions for the keyframes. */
- QVector m_keyframes;
- /** @brief Holds the keyframe type (linear, discrete, smooth) for each keyframes. */
- QVector m_keyframeTypes;
- /** @brief Holds the keyframe relativity (relative to start, to end, percent) for each keyframes. */
- // QVector m_keyframeRelatives;
- int m_position;
- int m_size;
- double m_scale;
- bool m_movingKeyframe;
- int m_movingKeyframePos;
- int m_movingKeyframeType;
- int m_hoverKeyframe;
- int m_selectedKeyframe;
- QPoint m_dragStart;
- int m_lineHeight;
- QColor m_selected;
- QColor m_keyframe;
- int m_seekPosition;
- int m_attachedToEnd;
-
-public slots:
- void setValue(const int pos);
-
-signals:
- void requestSeek(int);
- void keyframeMoved(int);
- void addKeyframe(int);
- void removeKeyframe(int);
- void moveKeyframe(int, int);
-};
-
-#endif
diff --git a/src/effectstack/graphicsscenerectmove.cpp b/src/effectstack/graphicsscenerectmove.cpp
deleted file mode 100644
index 590f574f2..000000000
--- a/src/effectstack/graphicsscenerectmove.cpp
+++ /dev/null
@@ -1,1079 +0,0 @@
-/***************************************************************************
- * copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) *
- * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
- * *
- * 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 2 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, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#include "graphicsscenerectmove.h"
-#include "titler/gradientwidget.h"
-#include "titler/titledocument.h"
-
-#include "kdenlive_debug.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-MyQGraphicsEffect::MyQGraphicsEffect(QObject *parent)
- : QGraphicsEffect(parent)
- , m_xOffset(0)
- , m_yOffset(0)
- , m_blur(0)
-{
-}
-
-void MyQGraphicsEffect::setShadow(const QImage &image)
-{
- m_shadow = image;
-}
-
-void MyQGraphicsEffect::setOffset(int xOffset, int yOffset, int blur)
-{
- m_xOffset = xOffset;
- m_yOffset = yOffset;
- m_blur = blur;
- updateBoundingRect();
-}
-
-void MyQGraphicsEffect::draw(QPainter *painter)
-{
- painter->fillRect(boundingRect(), Qt::transparent);
- painter->drawImage(-2 * m_blur + m_xOffset, -2 * m_blur + m_yOffset, m_shadow);
- drawSource(painter);
-}
-
-MyTextItem::MyTextItem(const QString &txt, QGraphicsItem *parent)
- : QGraphicsTextItem(txt, parent)
- , m_alignment(Qt::AlignLeft)
-{
- setCacheMode(QGraphicsItem::ItemCoordinateCache);
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
- document()->setDocumentMargin(0);
- m_shadowEffect = new MyQGraphicsEffect(this);
- m_shadowEffect->setEnabled(false);
- setGraphicsEffect(m_shadowEffect);
- updateGeometry();
- connect(document(), SIGNAL(contentsChange(int, int, int)), this, SLOT(updateGeometry(int, int, int)));
-}
-
-Qt::Alignment MyTextItem::alignment() const
-{
- return m_alignment;
-}
-
-void MyTextItem::updateShadow(bool enabled, int blur, int xoffset, int yoffset, QColor color)
-{
- m_shadowOffset = QPoint(xoffset, yoffset);
- m_shadowBlur = blur;
- m_shadowColor = std::move(color);
- m_shadowEffect->setEnabled(enabled);
- m_shadowEffect->setOffset(xoffset, yoffset, blur);
- if (enabled) {
- updateShadow();
- }
- update();
-}
-
-void MyTextItem::setTextColor(const QColor &col)
-{
- setDefaultTextColor(col);
- refreshFormat();
-}
-
-QStringList MyTextItem::shadowInfo() const
-{
- QStringList info;
- info << QString::number(static_cast(m_shadowEffect->isEnabled())) << m_shadowColor.name(QColor::HexArgb) << QString::number(m_shadowBlur)
- << QString::number(m_shadowOffset.x()) << QString::number(m_shadowOffset.y());
- return info;
-}
-
-void MyTextItem::loadShadow(const QStringList &info)
-{
- if (info.count() < 5) {
- return;
- }
- updateShadow((static_cast(info.at(0).toInt())), info.at(2).toInt(), info.at(3).toInt(), info.at(4).toInt(), QColor(info.at(1)));
-}
-
-void MyTextItem::setAlignment(Qt::Alignment alignment)
-{
- m_alignment = alignment;
- QTextBlockFormat format;
- format.setAlignment(alignment);
- QTextCursor cursor = textCursor(); // save cursor position
- int position = textCursor().position();
- cursor.select(QTextCursor::Document);
- cursor.mergeBlockFormat(format);
- cursor.clearSelection();
- cursor.setPosition(position); // restore cursor position
- setTextCursor(cursor);
-}
-
-void MyTextItem::refreshFormat()
-{
- QString gradientData = data(TitleDocument::Gradient).toString();
- QTextCursor cursor = textCursor();
- QTextCharFormat cformat;
- cursor.select(QTextCursor::Document);
- int position = textCursor().position();
-
- // Formatting can be lost on paste, since our QTextCursor gets overwritten, so re-apply all formatting here
- QColor fgColor = defaultTextColor();
- cformat.setForeground(fgColor);
- cformat.setFont(font());
-
- if (!gradientData.isEmpty()) {
- QRectF rect = boundingRect();
- QLinearGradient gr = GradientWidget::gradientFromString(gradientData, rect.width(), rect.height());
- cformat.setForeground(QBrush(gr));
- }
-
- // Apply
- cursor.mergeCharFormat(cformat);
- // restore cursor position
- cursor.clearSelection();
- cursor.setPosition(position);
- setTextCursor(cursor);
-}
-
-void MyTextItem::updateGeometry(int, int, int)
-{
- updateGeometry();
- // update gradient if necessary
- refreshFormat();
-
- QString text = toPlainText();
- m_path = QPainterPath();
- m_path.setFillRule(Qt::WindingFill);
- if (text.isEmpty()) {
- //
- } else {
- QFontMetrics metrics(font());
- double lineSpacing = data(TitleDocument::LineSpacing).toInt() + metrics.lineSpacing();
-
- // Calculate line width
- const QStringList lines = text.split(QLatin1Char('\n'));
- double linePos = metrics.ascent();
- QRectF bounding = boundingRect();
- /*if (lines.count() > 0) {
- lineSpacing = bounding.height() / lines.count();
- if (lineSpacing != data(TitleDocument::LineSpacing).toInt() + metrics.lineSpacing()) {
- linePos = 2 * lineSpacing - metrics.descent() - metrics.height();
- }
- }*/
-
- for (const QString &line : lines) {
- QPainterPath linePath;
- linePath.addText(0, linePos, font(), line);
- linePos += lineSpacing;
- if (m_alignment == Qt::AlignHCenter) {
- double offset = (bounding.width() - metrics.width(line)) / 2;
- linePath.translate(offset, 0);
- } else if (m_alignment == Qt::AlignRight) {
- double offset = bounding.width() - metrics.width(line);
- linePath.translate(offset, 0);
- }
- m_path.addPath(linePath);
- }
- }
-
- if (m_shadowEffect->isEnabled()) {
- updateShadow();
- }
- update();
-}
-
-void MyTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w)
-{
- if ((textInteractionFlags() & static_cast((Qt::TextEditable) != 0)) != 0) {
- QGraphicsTextItem::paint(painter, option, w);
- } else {
- painter->setRenderHint(QPainter::Antialiasing);
- int outline = data(TitleDocument::OutlineWidth).toInt();
- QString gradientData = data(TitleDocument::Gradient).toString();
- QTextCursor cursor(document());
- cursor.select(QTextCursor::Document);
- QBrush paintBrush;
- if (gradientData.isEmpty()) {
- paintBrush = QBrush(cursor.charFormat().foreground().color());
- } else {
- QRectF rect = boundingRect();
- paintBrush = QBrush(GradientWidget::gradientFromString(gradientData, rect.width(), rect.height()));
- }
- painter->fillPath(m_path, paintBrush);
- if (outline > 0) {
- QVariant variant = data(TitleDocument::OutlineColor);
- QColor outlineColor = variant.value();
- QPen pen(outlineColor);
- pen.setWidthF(outline);
- painter->strokePath(m_path, pen);
- }
- if (isSelected()) {
- QPen pen(Qt::red);
- pen.setStyle(Qt::DashLine);
- painter->setPen(pen);
- painter->drawRect(boundingRect());
- }
- }
-}
-
-void MyTextItem::updateShadow()
-{
- QString text = toPlainText();
- if (text.isEmpty()) {
- m_shadowEffect->setShadow(QImage());
- return;
- }
- QRectF bounding = boundingRect();
- QPainterPath path = m_path;
- // Calculate position of text in parent item
- path.translate(QPointF(2 * m_shadowBlur, 2 * m_shadowBlur));
- QRectF fullSize = bounding.united(path.boundingRect());
- QImage shadow(fullSize.width() + qAbs(m_shadowOffset.x()) + 4 * m_shadowBlur, fullSize.height() + qAbs(m_shadowOffset.y()) + 4 * m_shadowBlur,
- QImage::Format_ARGB32_Premultiplied);
- shadow.fill(Qt::transparent);
- QPainter painter(&shadow);
- painter.fillPath(path, QBrush(m_shadowColor));
- painter.end();
- if (m_shadowBlur > 0) {
- blurShadow(shadow, m_shadowBlur);
- }
- m_shadowEffect->setShadow(shadow);
-}
-
-void MyTextItem::blurShadow(QImage &result, int radius)
-{
- int tab[] = {14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2};
- int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius - 1];
-
- int r1 = 0;
- int r2 = result.height() - 1;
- int c1 = 0;
- int c2 = result.width() - 1;
-
- int bpl = result.bytesPerLine();
- int rgba[4];
- unsigned char *p;
-
- int i1 = 0;
- int i2 = 3;
-
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r1) + col * 4;
- for (int i = i1; i <= i2; i++) {
- rgba[i] = p[i] << 4;
- }
-
- p += bpl;
- for (int j = r1; j < r2; j++, p += bpl)
- for (int i = i1; i <= i2; i++) {
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
- }
-
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c1 * 4;
- for (int i = i1; i <= i2; i++) {
- rgba[i] = p[i] << 4;
- }
-
- p += 4;
- for (int j = c1; j < c2; j++, p += 4)
- for (int i = i1; i <= i2; i++) {
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
- }
-
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r2) + col * 4;
- for (int i = i1; i <= i2; i++) {
- rgba[i] = p[i] << 4;
- }
-
- p -= bpl;
- for (int j = r1; j < r2; j++, p -= bpl)
- for (int i = i1; i <= i2; i++) {
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
- }
-
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c2 * 4;
- for (int i = i1; i <= i2; i++) {
- rgba[i] = p[i] << 4;
- }
-
- p -= 4;
- for (int j = c1; j < c2; j++, p -= 4)
- for (int i = i1; i <= i2; i++) {
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
- }
-}
-
-void MyTextItem::updateGeometry()
-{
- QPointF topRightPrev = boundingRect().topRight();
- setTextWidth(-1);
- setTextWidth(boundingRect().width());
- setAlignment(m_alignment);
- QPointF topRight = boundingRect().topRight();
-
- if ((m_alignment & static_cast((Qt::AlignRight) != 0)) != 0) {
- setPos(pos() + (topRightPrev - topRight));
- }
-}
-
-QRectF MyTextItem::baseBoundingRect() const
-{
- QRectF base = QGraphicsTextItem::boundingRect();
- QTextCursor cur(document());
- cur.select(QTextCursor::Document);
- QTextBlockFormat format = cur.blockFormat();
- int lineHeight = format.lineHeight();
- int lineHeight2 = QFontMetrics(font()).lineSpacing();
- int lines = document()->lineCount();
- if (lines > 1) {
- base.setHeight(lines * lineHeight2 + lineHeight * (lines - 1));
- }
- return base;
-}
-
-QRectF MyTextItem::boundingRect() const
-{
- QRectF base = baseBoundingRect();
- if (m_shadowEffect->isEnabled() && m_shadowOffset.x() > 0) {
- base.setRight(base.right() + m_shadowOffset.x());
- }
- if (m_shadowEffect->isEnabled() && m_shadowOffset.y() > 0) {
- base.setBottom(base.bottom() + m_shadowOffset.y());
- }
- return base;
-}
-
-QVariant MyTextItem::itemChange(GraphicsItemChange change, const QVariant &value)
-{
- if (change == ItemPositionChange && (scene() != nullptr)) {
- QPoint newPos = value.toPoint();
- if (QApplication::mouseButtons() == Qt::LeftButton && (qobject_cast(scene()) != nullptr)) {
- GraphicsSceneRectMove *customScene = qobject_cast(scene());
- int gridSize = customScene->gridSize();
- int xV = (newPos.x() / gridSize) * gridSize;
- int yV = (newPos.y() / gridSize) * gridSize;
- newPos = QPoint(xV, yV);
- }
- return newPos;
- }
- if (change == QGraphicsItem::ItemSelectedHasChanged) {
- if (!value.toBool()) {
- // Make sure to deselect text when item loses focus
- QTextCursor cur(document());
- cur.clearSelection();
- setTextCursor(cur);
- }
- }
- return QGraphicsItem::itemChange(change, value);
-}
-
-void MyTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *evt)
-{
- if (textInteractionFlags() == Qt::TextEditorInteraction) {
- // if editor mode is already on: pass double click events on to the editor:
- QGraphicsTextItem::mouseDoubleClickEvent(evt);
- return;
- }
- // if editor mode is off:
- // 1. turn editor mode on and set selected and focused:
- // SetTextInteraction(true);
- setTextInteractionFlags(Qt::TextEditorInteraction);
- setFocus(Qt::MouseFocusReason);
- // 2. send a single click to this QGraphicsTextItem (this will set the cursor to the mouse position):
- // create a new mouse event with the same parameters as evt
- auto *click = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress);
- click->setButton(evt->button());
- click->setPos(evt->pos());
- QGraphicsTextItem::mousePressEvent(click);
- delete click; // don't forget to delete the event
-}
-
-MyRectItem::MyRectItem(QGraphicsItem *parent)
- : QGraphicsRectItem(parent)
-{
- setCacheMode(QGraphicsItem::ItemCoordinateCache);
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-}
-
-void MyRectItem::setRect(const QRectF &rectangle)
-{
- QGraphicsRectItem::setRect(rectangle);
- if (m_rect != rectangle && !data(TitleDocument::Gradient).isNull()) {
- m_rect = rectangle;
- QLinearGradient gr = GradientWidget::gradientFromString(data(TitleDocument::Gradient).toString(), m_rect.width(), m_rect.height());
- setBrush(QBrush(gr));
- }
-}
-
-QVariant MyRectItem::itemChange(GraphicsItemChange change, const QVariant &value)
-{
- if (change == ItemPositionChange && (scene() != nullptr)) {
- QPoint newPos = value.toPoint();
- if (QApplication::mouseButtons() == Qt::LeftButton && (qobject_cast(scene()) != nullptr)) {
- GraphicsSceneRectMove *customScene = qobject_cast(scene());
- int gridSize = customScene->gridSize();
- int xV = (newPos.x() / gridSize) * gridSize;
- int yV = (newPos.y() / gridSize) * gridSize;
- newPos = QPoint(xV, yV);
- }
- return newPos;
- }
- return QGraphicsItem::itemChange(change, value);
-}
-
-MyPixmapItem::MyPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent)
- : QGraphicsPixmapItem(pixmap, parent)
-{
- setCacheMode(QGraphicsItem::ItemCoordinateCache);
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-}
-
-QVariant MyPixmapItem::itemChange(GraphicsItemChange change, const QVariant &value)
-{
- if (change == ItemPositionChange && (scene() != nullptr)) {
- QPoint newPos = value.toPoint();
- if (QApplication::mouseButtons() == Qt::LeftButton && (qobject_cast(scene()) != nullptr)) {
- GraphicsSceneRectMove *customScene = qobject_cast(scene());
- int gridSize = customScene->gridSize();
- int xV = (newPos.x() / gridSize) * gridSize;
- int yV = (newPos.y() / gridSize) * gridSize;
- newPos = QPoint(xV, yV);
- }
- return newPos;
- }
- return QGraphicsItem::itemChange(change, value);
-}
-
-MySvgItem::MySvgItem(const QString &fileName, QGraphicsItem *parent)
- : QGraphicsSvgItem(fileName, parent)
-{
- setCacheMode(QGraphicsItem::ItemCoordinateCache);
- setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
-}
-
-QVariant MySvgItem::itemChange(GraphicsItemChange change, const QVariant &value)
-{
- if (change == ItemPositionChange && (scene() != nullptr)) {
- QPoint newPos = value.toPoint();
- if (QApplication::mouseButtons() == Qt::LeftButton && (qobject_cast(scene()) != nullptr)) {
- GraphicsSceneRectMove *customScene = qobject_cast(scene());
- int gridSize = customScene->gridSize();
- int xV = (newPos.x() / gridSize) * gridSize;
- int yV = (newPos.y() / gridSize) * gridSize;
- newPos = QPoint(xV, yV);
- }
- return newPos;
- }
- return QGraphicsItem::itemChange(change, value);
-}
-GraphicsSceneRectMove::GraphicsSceneRectMove(QObject *parent)
- : QGraphicsScene(parent)
- , m_selectedItem(nullptr)
- , m_resizeMode(NoResize)
- , m_possibleAction(NoResize)
- , m_tool(TITLE_RECTANGLE)
- , m_gridSize(20)
- , m_createdText(false)
- , m_moveStarted(false)
- , m_pan(false)
-{
- // grabMouse();
- m_zoom = 1.0;
- setBackgroundBrush(QBrush(Qt::transparent));
- m_fontSize = 0;
-}
-
-void GraphicsSceneRectMove::setSelectedItem(QGraphicsItem *item)
-{
- clearSelection();
- m_selectedItem = item;
- item->setSelected(true);
- update();
-}
-
-TITLETOOL GraphicsSceneRectMove::tool() const
-{
- return m_tool;
-}
-
-void GraphicsSceneRectMove::setTool(TITLETOOL tool)
-{
- m_tool = tool;
- switch (m_tool) {
- case TITLE_RECTANGLE:
- setCursor(Qt::CrossCursor);
- break;
- case TITLE_TEXT:
- setCursor(Qt::IBeamCursor);
- break;
- default:
- setCursor(Qt::ArrowCursor);
- }
-}
-
-void GraphicsSceneRectMove::keyPressEvent(QKeyEvent *keyEvent)
-{
- if (m_selectedItem == nullptr || !(m_selectedItem->flags() & QGraphicsItem::ItemIsMovable)) {
- QGraphicsScene::keyPressEvent(keyEvent);
- return;
- }
- if (m_selectedItem->type() == QGraphicsTextItem::Type) {
- MyTextItem *t = static_cast(m_selectedItem);
- if ((t->textInteractionFlags() & static_cast((Qt::TextEditorInteraction) != 0)) != 0) {
- QGraphicsScene::keyPressEvent(keyEvent);
- return;
- }
- }
- int diff = m_gridSize;
- if ((keyEvent->modifiers() & Qt::ControlModifier) != 0u) {
- diff = m_gridSize * 5;
- }
- switch (keyEvent->key()) {
- case Qt::Key_Left:
- for (QGraphicsItem *qgi : selectedItems()) {
- qgi->moveBy(-diff, 0);
- }
- emit itemMoved();
- break;
- case Qt::Key_Right:
- for (QGraphicsItem *qgi : selectedItems()) {
- qgi->moveBy(diff, 0);
- }
- emit itemMoved();
- break;
- case Qt::Key_Up:
- for (QGraphicsItem *qgi : selectedItems()) {
- qgi->moveBy(0, -diff);
- }
- emit itemMoved();
- break;
- case Qt::Key_Down:
- for (QGraphicsItem *qgi : selectedItems()) {
- qgi->moveBy(0, diff);
- }
- emit itemMoved();
- break;
- case Qt::Key_Delete:
- case Qt::Key_Backspace:
- for (QGraphicsItem *qgi : selectedItems()) {
- if (qgi->data(-1).toInt() == -1) {
- continue;
- }
- removeItem(qgi);
- delete qgi;
- }
- m_selectedItem = nullptr;
- emit selectionChanged();
- break;
- default:
- QGraphicsScene::keyPressEvent(keyEvent);
- }
- emit actionFinished();
-}
-
-void GraphicsSceneRectMove::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e)
-{
- QPointF p = e->scenePos();
- p += QPoint(-2, -2);
- m_resizeMode = NoResize;
- m_selectedItem = nullptr;
-
- // http://www.kdenlive.org/mantis/view.php?id=1035
- QList i = items(QRectF(p, QSizeF(4, 4)).toRect());
- if (i.isEmpty()) {
- return;
- }
-
- int ix = 1;
- QGraphicsItem *g = i.constFirst();
- while (!(g->flags() & QGraphicsItem::ItemIsSelectable) && ix < i.count()) {
- g = i.at(ix);
- ix++;
- }
- if ((g != nullptr) && g->type() == QGraphicsTextItem::Type && (((g->flags() & static_cast((QGraphicsItem::ItemIsSelectable) != 0))) != 0)) {
- m_selectedItem = g;
- } else {
- emit doubleClickEvent();
- }
- QGraphicsScene::mouseDoubleClickEvent(e);
-}
-
-void GraphicsSceneRectMove::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
-{
- m_pan = false;
- if (m_tool == TITLE_RECTANGLE && (m_selectedItem != nullptr)) {
- setSelectedItem(m_selectedItem);
- }
- if (m_createdText) {
- m_selectedItem->setSelected(true);
- MyTextItem *newText = static_cast(m_selectedItem);
- QTextCursor cur(newText->document());
- cur.select(QTextCursor::Document);
- newText->setTextCursor(cur);
- m_createdText = false;
- }
- if ((e->modifiers() & Qt::ShiftModifier) != 0u) {
- e->accept();
- } else {
- QGraphicsScene::mouseReleaseEvent(e);
- }
- QList viewlist = views();
- if (!viewlist.isEmpty()) {
- viewlist.constFirst()->setDragMode(QGraphicsView::RubberBandDrag);
- }
- emit actionFinished();
-}
-
-void GraphicsSceneRectMove::mousePressEvent(QGraphicsSceneMouseEvent *e)
-{
- if ((e->buttons() & Qt::MiddleButton) != 0u) {
- clearTextSelection();
- QList viewlist = views();
- if (!viewlist.isEmpty()) {
- viewlist.constFirst()->setDragMode(QGraphicsView::ScrollHandDrag);
- m_pan = true;
- e->accept();
- QGraphicsScene::mousePressEvent(e);
- return;
- }
- }
- int xPos = ((int)e->scenePos().x() / m_gridSize) * m_gridSize;
- int yPos = ((int)e->scenePos().y() / m_gridSize) * m_gridSize;
- m_moveStarted = false;
- m_clickPoint = e->scenePos();
- m_resizeMode = m_possibleAction;
- const QList list = items(e->scenePos());
- QGraphicsItem *item = nullptr;
- if (m_tool == TITLE_SELECT) {
- QList viewlist = views();
- if ((e->modifiers() & Qt::ControlModifier) != 0u) {
- clearTextSelection();
- if (!viewlist.isEmpty()) {
- viewlist.constFirst()->setDragMode(QGraphicsView::ScrollHandDrag);
- e->ignore();
- // QGraphicsScene::mousePressEvent(e);
- return;
- }
- } else {
- if (!viewlist.isEmpty()) {
- viewlist.constFirst()->setRubberBandSelectionMode(Qt::IntersectsItemShape);
- }
- }
- bool alreadySelected = false;
- for (QGraphicsItem *g : list) {
- // qDebug() << " - - CHECKING ITEM Z:" << g->zValue() << ", TYPE: " << g->type();
- // check is there is a selected item in list
- if (!(g->flags() & QGraphicsItem::ItemIsSelectable)) {
- continue;
- }
- if (g->zValue() > -1000 /* && g->isSelected()*/) {
- alreadySelected = g->isSelected();
- if (!alreadySelected) {
- g->setSelected(true);
- }
- item = g;
- break;
- }
- }
- if (item == nullptr || (e->modifiers() != Qt::ShiftModifier && !alreadySelected)) {
- clearTextSelection();
- } else if ((e->modifiers() & Qt::ShiftModifier) != 0u) {
- clearTextSelection(false);
- }
- if ((item != nullptr) && ((item->flags() & QGraphicsItem::ItemIsMovable) != 0)) {
- m_sceneClickPoint = e->scenePos();
- m_selectedItem = item;
- // qCDebug(KDENLIVE_LOG) << "///////// ITEM TYPE: " << item->type();
- if (item->type() == QGraphicsTextItem::Type) {
- MyTextItem *t = static_cast(item);
- if (t->textInteractionFlags() == Qt::TextEditorInteraction) {
- QGraphicsScene::mousePressEvent(e);
- return;
- }
- t->setTextInteractionFlags(Qt::NoTextInteraction);
- t->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
- setCursor(Qt::ClosedHandCursor);
- } else if (item->type() == QGraphicsRectItem::Type || item->type() == QGraphicsSvgItem::Type || item->type() == QGraphicsPixmapItem::Type) {
- QRectF r1;
- if (m_selectedItem->type() == QGraphicsRectItem::Type) {
- r1 = ((QGraphicsRectItem *)m_selectedItem)->rect().normalized();
- } else {
- r1 = m_selectedItem->boundingRect().normalized();
- }
-
- r1.translate(m_selectedItem->scenePos());
- switch (m_resizeMode) {
- case BottomRight:
- case Right:
- case Down:
- m_clickPoint = r1.topLeft();
- e->accept();
- break;
- case TopLeft:
- case Left:
- case Up:
- m_clickPoint = r1.bottomRight();
- e->accept();
- break;
- case TopRight:
- m_clickPoint = r1.bottomLeft();
- e->accept();
- break;
- case BottomLeft:
- m_clickPoint = r1.topRight();
- e->accept();
- break;
- default:
- break;
- }
- }
- }
- QGraphicsScene::mousePressEvent(e);
- } else if (m_tool == TITLE_RECTANGLE) {
- clearTextSelection();
- m_sceneClickPoint = QPointF(xPos, yPos);
- m_selectedItem = nullptr;
- e->ignore();
- } else if (m_tool == TITLE_TEXT) {
- clearTextSelection();
- MyTextItem *textItem = new MyTextItem(i18n("Text"), nullptr);
- yPos = (((int)e->scenePos().y() - (int)(m_fontSize / 2)) / m_gridSize) * m_gridSize;
- textItem->setPos(xPos, yPos);
- addItem(textItem);
- textItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
- textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
- textItem->setFocus(Qt::MouseFocusReason);
- emit newText(textItem);
- m_selectedItem = textItem;
- m_selectedItem->setSelected(true);
- m_createdText = true;
- }
- // qCDebug(KDENLIVE_LOG) << "////// MOUSE CLICK, RESIZE MODE: " << m_resizeMode;
-}
-
-void GraphicsSceneRectMove::clearTextSelection(bool reset)
-{
- if ((m_selectedItem != nullptr) && m_selectedItem->type() == QGraphicsTextItem::Type) {
- // disable text editing
- MyTextItem *t = static_cast(m_selectedItem);
- t->textCursor().setPosition(0);
- QTextBlock cur = t->textCursor().block();
- t->setTextCursor(QTextCursor(cur));
- t->setTextInteractionFlags(Qt::NoTextInteraction);
- }
- if (reset) {
- m_selectedItem = nullptr;
- clearSelection();
- }
-}
-
-void GraphicsSceneRectMove::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
-{
- QList viewlist = views();
- if (viewlist.isEmpty()) {
- e->ignore();
- return;
- }
- QGraphicsView *view = viewlist.constFirst();
- if (m_pan) {
- QPoint diff = e->lastScreenPos() - e->screenPos();
- view->horizontalScrollBar()->setValue(view->horizontalScrollBar()->value() + diff.x());
- view->verticalScrollBar()->setValue(view->verticalScrollBar()->value() + diff.y());
- e->accept();
- QGraphicsScene::mouseMoveEvent(e);
- return;
- }
- if (e->buttons() != Qt::NoButton && !m_moveStarted) {
- if ((view->mapFromScene(e->scenePos()) - view->mapFromScene(m_clickPoint)).manhattanLength() < QApplication::startDragDistance()) {
- e->ignore();
- return;
- }
- m_moveStarted = true;
- }
- if ((m_selectedItem != nullptr) && ((e->buttons() & Qt::LeftButton) != 0u)) {
- if (m_selectedItem->type() == QGraphicsRectItem::Type || m_selectedItem->type() == QGraphicsSvgItem::Type ||
- m_selectedItem->type() == QGraphicsPixmapItem::Type) {
- QRectF newrect;
- if (m_selectedItem->type() == QGraphicsRectItem::Type) {
- newrect = ((QGraphicsRectItem *)m_selectedItem)->rect();
- } else {
- newrect = m_selectedItem->boundingRect();
- }
- int xPos = ((int)e->scenePos().x() / m_gridSize) * m_gridSize;
- int yPos = ((int)e->scenePos().y() / m_gridSize) * m_gridSize;
- QPointF newpoint(xPos, yPos);
- switch (m_resizeMode) {
- case BottomRight:
- case BottomLeft:
- case TopRight:
- case TopLeft:
- newrect = QRectF(m_clickPoint, newpoint).normalized();
- break;
- case Up:
- newrect = QRectF(m_clickPoint, QPointF(m_clickPoint.x() - newrect.width(), newpoint.y())).normalized();
- break;
- case Down:
- newrect = QRectF(m_clickPoint, QPointF(newrect.width() + m_clickPoint.x(), newpoint.y())).normalized();
- break;
- case Right:
- newrect = QRectF(m_clickPoint, QPointF(newpoint.x(), m_clickPoint.y() + newrect.height())).normalized();
- break;
- case Left:
- newrect = QRectF(m_clickPoint, QPointF(newpoint.x(), m_clickPoint.y() - newrect.height())).normalized();
- break;
- default:
- break;
- }
-
- if (m_selectedItem->type() == QGraphicsRectItem::Type && m_resizeMode != NoResize) {
- MyRectItem *gi = static_cast(m_selectedItem);
- // Resize using aspect ratio
- if (!m_selectedItem->data(0).isNull()) {
- // we want to keep aspect ratio
- double hRatio = (double)newrect.width() / m_selectedItem->data(0).toInt();
- double vRatio = (double)newrect.height() / m_selectedItem->data(1).toInt();
- if (hRatio < vRatio) {
- newrect.setHeight(m_selectedItem->data(1).toInt() * hRatio);
- } else {
- newrect.setWidth(m_selectedItem->data(0).toInt() * vRatio);
- }
- }
- gi->setPos(newrect.topLeft());
- gi->setRect(QRectF(QPointF(), newrect.bottomRight() - newrect.topLeft()));
- return;
- }
- QGraphicsScene::mouseMoveEvent(e);
- } else if (m_selectedItem->type() == QGraphicsTextItem::Type) {
- MyTextItem *t = static_cast(m_selectedItem);
- if ((t->textInteractionFlags() & static_cast((Qt::TextEditorInteraction) != 0)) != 0) {
- QGraphicsScene::mouseMoveEvent(e);
- return;
- }
- QGraphicsScene::mouseMoveEvent(e);
- m_sceneClickPoint = e->scenePos();
- }
- emit itemMoved();
- } else if (m_tool == TITLE_SELECT) {
- QPointF p = e->scenePos();
- p += QPoint(-2, -2);
- m_resizeMode = NoResize;
- bool itemFound = false;
- QList list = items(QRectF(p, QSizeF(4, 4)).toRect());
- for (const QGraphicsItem *g : list) {
- if (!(g->flags() & QGraphicsItem::ItemIsSelectable)) {
- continue;
- }
- if ((g->type() == QGraphicsSvgItem::Type || g->type() == QGraphicsPixmapItem::Type) && g->zValue() > -1000) {
- // image or svg item
- setCursor(Qt::OpenHandCursor);
- itemFound = true;
- break;
- } else if (g->type() == QGraphicsRectItem::Type && g->zValue() > -1000) {
- if (view == nullptr) {
- continue;
- }
- QRectF r1 = ((const QGraphicsRectItem *)g)->rect().normalized();
- itemFound = true;
-
- // Item mapped coordinates
- QPolygon r = g->deviceTransform(view->viewportTransform()).map(r1).toPolygon();
- QPainterPath top(r.point(0));
- top.lineTo(r.point(1));
- QPainterPath bottom(r.point(2));
- bottom.lineTo(r.point(3));
- QPainterPath left(r.point(0));
- left.lineTo(r.point(3));
- QPainterPath right(r.point(1));
- right.lineTo(r.point(2));
-
- // The area interested by the mouse pointer
- QPoint viewPos = view->mapFromScene(e->scenePos());
- QPainterPath mouseArea;
- QFontMetrics metrics(font());
- int box = metrics.lineSpacing() / 2;
- mouseArea.addRect(viewPos.x() - box, viewPos.y() - box, 2 * box, 2 * box);
-
- // Check for collisions between the mouse and the borders
- if (mouseArea.contains(r.point(0))) {
- m_possibleAction = TopLeft;
- setCursor(Qt::SizeFDiagCursor);
- } else if (mouseArea.contains(r.point(2))) {
- m_possibleAction = BottomRight;
- setCursor(Qt::SizeFDiagCursor);
- } else if (mouseArea.contains(r.point(1))) {
- m_possibleAction = TopRight;
- setCursor(Qt::SizeBDiagCursor);
- } else if (mouseArea.contains(r.point(3))) {
- m_possibleAction = BottomLeft;
- setCursor(Qt::SizeBDiagCursor);
- } else if (top.intersects(mouseArea)) {
- m_possibleAction = Up;
- setCursor(Qt::SizeVerCursor);
- } else if (bottom.intersects(mouseArea)) {
- m_possibleAction = Down;
- setCursor(Qt::SizeVerCursor);
- } else if (right.intersects(mouseArea)) {
- m_possibleAction = Right;
- setCursor(Qt::SizeHorCursor);
- } else if (left.intersects(mouseArea)) {
- m_possibleAction = Left;
- setCursor(Qt::SizeHorCursor);
- } else {
- setCursor(Qt::OpenHandCursor);
- m_possibleAction = NoResize;
- }
- }
- break;
- }
- if (!itemFound) {
- m_possibleAction = NoResize;
- setCursor(Qt::ArrowCursor);
- }
- QGraphicsScene::mouseMoveEvent(e);
- } else if (m_tool == TITLE_RECTANGLE && ((e->buttons() & Qt::LeftButton) != 0u)) {
- if (m_selectedItem == nullptr) {
- // create new rect item
- QRectF r(0, 0, e->scenePos().x() - m_sceneClickPoint.x(), e->scenePos().y() - m_sceneClickPoint.y());
- r = r.normalized();
- auto *rect = new MyRectItem();
- rect->setRect(QRectF(0, 0, r.width(), r.height()));
- addItem(rect);
- m_selectedItem = rect;
- m_selectedItem->setPos(m_sceneClickPoint);
- m_selectedItem->setSelected(true);
- emit newRect(rect);
- m_selectedItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
- m_resizeMode = BottomRight;
- QGraphicsScene::mouseMoveEvent(e);
- }
- }
-}
-
-void GraphicsSceneRectMove::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
-{
- if (wheelEvent->modifiers() == Qt::ControlModifier) {
- QList viewlist = views();
- ////qCDebug(KDENLIVE_LOG) << wheelEvent->delta() << ' ' << zoom;
- if (!viewlist.isEmpty()) {
- if (wheelEvent->delta() > 0) {
- emit sceneZoom(true);
- } else {
- emit sceneZoom(false);
- }
- }
- } else {
- wheelEvent->setAccepted(false);
- }
-}
-
-void GraphicsSceneRectMove::setScale(double s)
-{
- if (m_zoom < 1.0 / 7.0 && s < 1.0) {
- return;
- }
- if (m_zoom > 10.0 / 7.9 && s > 1.0) {
- return;
- }
- QList viewlist = views();
- if (!viewlist.isEmpty()) {
- viewlist[0]->scale(s, s);
- m_zoom = m_zoom * s;
- }
- ////qCDebug(KDENLIVE_LOG)<<"////////// ZOOM: "< viewlist = views();
- if (!viewlist.isEmpty()) {
- viewlist[0]->resetTransform();
- viewlist[0]->scale(s, s);
- m_zoom = s;
- }
-
- ////qCDebug(KDENLIVE_LOG)<<"////////// ZOOM: "< l = views();
- for (QGraphicsView *v : l) {
- v->setCursor(c);
- }
-}
-
-void GraphicsSceneRectMove::slotUpdateFontSize(int s)
-{
- m_fontSize = s;
-}
-
-void GraphicsSceneRectMove::drawForeground(QPainter *painter, const QRectF &rect)
-{
- // draw the grid if needed
- if (m_gridSize <= 1) {
- return;
- }
-
- QPen pen(QColor(255, 0, 0, 100));
- painter->setPen(pen);
-
- qreal left = int(rect.left()) - (int(rect.left()) % m_gridSize);
- qreal top = int(rect.top()) - (int(rect.top()) % m_gridSize);
- QVector points;
- for (qreal x = left; x < rect.right(); x += m_gridSize) {
- for (qreal y = top; y < rect.bottom(); y += m_gridSize) {
- points.append(QPointF(x, y));
- }
- }
- painter->drawPoints(points.data(), points.size());
-}
-
-int GraphicsSceneRectMove::gridSize() const
-{
- return m_gridSize;
-}
-
-void GraphicsSceneRectMove::slotUseGrid(bool enableGrid)
-{
- m_gridSize = enableGrid ? 20 : 1;
-}
-
-void GraphicsSceneRectMove::addNewItem(QGraphicsItem *item)
-{
- clearSelection();
- addItem(item);
- item->setSelected(true);
- m_selectedItem = item;
-}
diff --git a/src/effectstack/graphicsscenerectmove.h b/src/effectstack/graphicsscenerectmove.h
deleted file mode 100644
index 8b8625995..000000000
--- a/src/effectstack/graphicsscenerectmove.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/***************************************************************************
- * copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) *
- * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
- * *
- * 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 2 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, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#ifndef GRAPHICSSCENERECTMOVE_H
-#define GRAPHICSSCENERECTMOVE_H
-
-#include
-#include
-#include
-#include
-
-enum resizeModes { NoResize = 0, TopLeft, BottomLeft, TopRight, BottomRight, Left, Right, Up, Down };
-enum TITLETOOL { TITLE_SELECT = 0, TITLE_RECTANGLE = 1, TITLE_TEXT = 2, TITLE_IMAGE = 3 };
-
-class MyQGraphicsEffect : public QGraphicsEffect
-{
-public:
- explicit MyQGraphicsEffect(QObject *parent = nullptr);
- void setOffset(int xOffset, int yOffset, int blur);
- void setShadow(const QImage &image);
-
-protected:
- void draw(QPainter *painter) override;
-
-private:
- int m_xOffset;
- int m_yOffset;
- int m_blur;
- QImage m_shadow;
-};
-
-class MyTextItem : public QGraphicsTextItem
-{
- Q_OBJECT
-public:
- MyTextItem(const QString &, QGraphicsItem *parent = nullptr);
- void setAlignment(Qt::Alignment alignment);
- /** @brief returns an extended bounding containing shadow */
- QRectF boundingRect() const override;
- /** @brief returns the normal bounding rect around text */
- QRectF baseBoundingRect() const;
- Qt::Alignment alignment() const;
- void updateShadow(bool enabled, int blur, int xoffset, int yoffset, QColor color);
- QStringList shadowInfo() const;
- void loadShadow(const QStringList &info);
- void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *evt) override;
- void setTextColor(const QColor &col);
-
-protected:
- QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) override;
-
-private:
- Qt::Alignment m_alignment;
- QPoint m_shadowOffset;
- int m_shadowBlur;
- QColor m_shadowColor;
- QPainterPath m_path;
- MyQGraphicsEffect *m_shadowEffect;
- void updateShadow();
- void blurShadow(QImage &image, int radius);
- void refreshFormat();
-
-public slots:
- void updateGeometry(int, int, int);
- void updateGeometry();
-};
-
-class MyRectItem : public QGraphicsRectItem
-{
-public:
- explicit MyRectItem(QGraphicsItem *parent = nullptr);
- void setRect(const QRectF &rectangle);
-
-protected:
- QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
-
-private:
- QRectF m_rect;
-};
-
-class MyPixmapItem : public QGraphicsPixmapItem
-{
-public:
- MyPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = nullptr);
-
-protected:
- QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
-};
-
-class MySvgItem : public QGraphicsSvgItem
-{
-public:
- MySvgItem(const QString &fileName = QString(), QGraphicsItem *parent = nullptr);
-
-protected:
- QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
-};
-
-class GraphicsSceneRectMove : public QGraphicsScene
-{
- Q_OBJECT
-public:
- explicit GraphicsSceneRectMove(QObject *parent = nullptr);
- void setSelectedItem(QGraphicsItem *item);
- void setScale(double s);
- void setZoom(double s);
- void setTool(TITLETOOL tool);
- TITLETOOL tool() const;
- /** @brief Get out of text edit mode. If reset is true, we also unselect all items */
- void clearTextSelection(bool reset = true);
- int gridSize() const;
- void addNewItem(QGraphicsItem *item);
-
-public slots:
- void slotUpdateFontSize(int s);
- void slotUseGrid(bool enableGrid);
-
-protected:
- void keyPressEvent(QKeyEvent *keyEvent) override;
- void mousePressEvent(QGraphicsSceneMouseEvent *) override;
- void mouseReleaseEvent(QGraphicsSceneMouseEvent *) override;
- void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) override;
- /** @brief Resizes and moves items */
- void mouseMoveEvent(QGraphicsSceneMouseEvent *) override;
- void wheelEvent(QGraphicsSceneWheelEvent *wheelEvent) override;
- void drawForeground(QPainter *painter, const QRectF &rect) override;
-
-private:
- void setCursor(const QCursor &);
- double m_zoom;
- QGraphicsItem *m_selectedItem;
- resizeModes m_resizeMode;
- resizeModes m_possibleAction;
- QPointF m_sceneClickPoint;
- TITLETOOL m_tool;
- QPointF m_clickPoint;
- int m_fontSize;
- int m_gridSize;
- bool m_createdText;
- bool m_moveStarted;
- bool m_pan;
-
-signals:
- void itemMoved();
- void sceneZoom(bool);
- void newRect(QGraphicsRectItem *);
- void newText(MyTextItem *);
- void actionFinished();
- void doubleClickEvent();
-};
-
-#endif
diff --git a/src/effectstack/keyframehelper.cpp b/src/effectstack/keyframehelper.cpp
deleted file mode 100644
index 5f8f7441f..000000000
--- a/src/effectstack/keyframehelper.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
- * *
- * 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 2 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, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#include "keyframehelper.h"
-
-#include "definitions.h"
-#include "kdenlivesettings.h"
-
-#include
-#include
-
-#include
-#include
-#include
-
-const int margin = 5;
-
-#define SEEK_INACTIVE (-1)
-
-KeyframeHelper::KeyframeHelper(QWidget *parent)
- : QWidget(parent)
- , frameLength(1)
- , m_geom(nullptr)
- , m_position(0)
- , m_scale(0)
- , m_movingKeyframe(false)
- , m_movingItem()
- , m_hoverKeyframe(-1)
- , m_seekPosition(SEEK_INACTIVE)
- , m_offset(0)
-{
- setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
- setMouseTracking(true);
- QPalette p = palette();
- m_size = QFontInfo(font()).pixelSize() * 1.8;
- m_lineHeight = m_size / 2;
- setMinimumHeight(m_size);
- setMaximumHeight(m_size);
- KColorScheme scheme(p.currentColorGroup(), KColorScheme::Window);
- m_selected = scheme.decoration(KColorScheme::HoverColor).color();
- m_keyframe = scheme.foreground(KColorScheme::LinkText).color();
-}
-
-// virtual
-void KeyframeHelper::mousePressEvent(QMouseEvent *event)
-{
- m_hoverKeyframe = -1;
- if (event->button() != Qt::LeftButton) {
- QWidget::mousePressEvent(event);
- return;
- }
- int xPos = event->x() - margin;
- int headOffset = m_lineHeight / 1.5;
- if (m_geom != nullptr && (event->y() <= headOffset)) {
- // check if we want to move a keyframe
- int mousePos = qMax((int)(xPos / m_scale), 0) + m_offset;
- Mlt::GeometryItem item;
- if (m_geom->next_key(&item, mousePos) == 0) {
- if (qAbs((item.frame() - m_offset) * m_scale - xPos) < headOffset) {
- m_movingItem.x(item.x());
- m_movingItem.y(item.y());
- m_movingItem.w(item.w());
- m_movingItem.h(item.h());
- m_movingItem.mix(item.mix());
- m_movingItem.frame(item.frame());
-
- while (!m_extraMovingItems.isEmpty()) {
- Mlt::GeometryItem *gitem = m_extraMovingItems.takeFirst();
- delete gitem;
- }
- for (int i = 0; i < m_extraGeometries.count(); ++i) {
- if (m_extraGeometries.at(i)->next_key(item, mousePos) == 0) {
- auto *item2 = new Mlt::GeometryItem();
- item2->x(item.x());
- item2->frame(item.frame());
- m_extraMovingItems.append(item2);
- } else {
- m_extraMovingItems.append(nullptr);
- }
- }
- m_dragStart = event->pos();
- return;
- }
- }
- }
- int seekRequest = xPos / m_scale;
- if (seekRequest != m_position) {
- m_seekPosition = seekRequest;
- emit requestSeek(m_seekPosition);
- update();
- }
-}
-
-void KeyframeHelper::leaveEvent(QEvent *event)
-{
- Q_UNUSED(event)
- if (m_hoverKeyframe != -1) {
- m_hoverKeyframe = -1;
- update();
- }
-}
-
-// virtual
-void KeyframeHelper::mouseMoveEvent(QMouseEvent *event)
-{
- int xPos = event->x() - margin;
- int headOffset = m_lineHeight / 1.5;
- if (event->buttons() == Qt::NoButton) {
- int mousePos = qMax((int)(xPos / m_scale), 0) + m_offset;
- if (qAbs(m_position * m_scale - xPos) < m_lineHeight && event->y() >= m_lineHeight) {
- // Mouse over time cursor
- if (m_hoverKeyframe != -2) {
- m_hoverKeyframe = -2;
- update();
- }
- event->accept();
- return;
- }
- if (m_geom != nullptr && (event->y() < m_lineHeight)) {
- // check if we want to move a keyframe
- Mlt::GeometryItem item;
- if (m_geom->next_key(&item, mousePos) == 0) {
- if (qAbs((item.frame() - m_offset) * m_scale - xPos) < headOffset) {
- if (m_hoverKeyframe == item.frame()) {
- return;
- }
- m_hoverKeyframe = item.frame();
- setCursor(Qt::PointingHandCursor);
- update();
- event->accept();
- return;
- }
- }
- }
- if (m_hoverKeyframe != -1) {
- m_hoverKeyframe = -1;
- setCursor(Qt::ArrowCursor);
- update();
- }
- event->accept();
- return;
- }
- if (!m_dragStart.isNull() || m_movingKeyframe) {
- if (!m_movingKeyframe) {
- if ((QPoint(xPos, event->y()) - m_dragStart).manhattanLength() < QApplication::startDragDistance()) {
- return;
- }
- m_movingKeyframe = true;
- m_dragStart = QPoint();
- m_geom->remove(m_movingItem.frame());
- for (int i = 0; i < m_extraGeometries.count(); ++i) {
- m_extraGeometries[i]->remove(m_movingItem.frame());
- }
- }
- int pos = qBound(0, (int)(xPos / m_scale), frameLength);
- if (KdenliveSettings::snaptopoints() && qAbs(pos - m_position) < headOffset / m_scale) {
- pos = m_position;
- }
- m_movingItem.frame(pos + m_offset);
- for (int i = 0; i < m_extraMovingItems.count(); ++i) {
- if (m_extraMovingItems.at(i)) {
- m_extraMovingItems[i]->frame(pos);
- }
- }
- update();
- return;
- }
- m_seekPosition = (int)(xPos / m_scale);
- m_seekPosition = qMax(0, m_seekPosition);
- m_seekPosition = qMin(frameLength, m_seekPosition);
- m_hoverKeyframe = -2;
- emit requestSeek(m_seekPosition);
- update();
-}
-
-void KeyframeHelper::mouseDoubleClickEvent(QMouseEvent *event)
-{
- if (m_geom != nullptr && event->button() == Qt::LeftButton) {
- // check if we want to move a keyframe
- int xPos = event->x() - margin;
- int mousePos = qMax((int)(xPos / m_scale - 5), 0) + m_offset;
- Mlt::GeometryItem item;
- if (m_geom->next_key(&item, mousePos) == 0 && item.frame() - mousePos < 10) {
- // There is already a keyframe close to mouse click
- emit removeKeyframe(item.frame());
- return;
- }
- // add new keyframe
- emit addKeyframe((int)(xPos / m_scale) + m_offset);
- }
-}
-
-// virtual
-void KeyframeHelper::mouseReleaseEvent(QMouseEvent *event)
-{
- setCursor(Qt::ArrowCursor);
- m_hoverKeyframe = -1;
- if (m_movingKeyframe) {
- m_geom->insert(m_movingItem);
- m_movingKeyframe = false;
-
- for (int i = 0; i < m_extraGeometries.count(); ++i) {
- if (m_extraMovingItems.at(i)) {
- m_extraGeometries[i]->insert(m_extraMovingItems.at(i));
- }
- }
- m_movingKeyframe = false;
- emit keyframeMoved(m_position);
- return;
- }
- if (!m_dragStart.isNull()) {
- m_seekPosition = m_movingItem.frame();
- m_dragStart = QPoint();
- emit requestSeek(m_seekPosition);
- }
- QWidget::mouseReleaseEvent(event);
-}
-
-// virtual
-void KeyframeHelper::wheelEvent(QWheelEvent *e)
-{
- if (e->delta() < 0) {
- ++m_position;
- } else {
- --m_position;
- }
- m_position = qMax(0, m_position);
- m_position = qMin(frameLength, m_position);
- emit requestSeek(m_position);
- update();
- /* int delta = 1;
- if (e->modifiers() == Qt::ControlModifier) delta = m_timecode.fps();
- if (e->delta() < 0) delta = 0 - delta;
- m_view->moveCursorPos(delta);
- */
-}
-
-// virtual
-void KeyframeHelper::paintEvent(QPaintEvent *e)
-{
- QPainter p(this);
- p.setRenderHints(QPainter::Antialiasing);
- const QRectF clipRect = e->rect();
- p.setClipRect(clipRect);
- m_scale = (double)(width() - 2 * margin) / frameLength;
- int headOffset = m_lineHeight / 1.5;
- if (m_geom != nullptr) {
- int pos = m_offset;
- Mlt::GeometryItem item;
- while (true) {
- if (m_geom->next_key(&item, pos) == 1) {
- break;
- }
- pos = item.frame();
- int offsetPos = pos - m_offset;
- if (offsetPos < 0) {
- pos++;
- continue;
- }
- int scaledPos = margin + offsetPos * m_scale;
- // draw keyframes
- if (offsetPos == m_position || offsetPos == m_hoverKeyframe) {
- // active keyframe
- p.setBrush(m_selected);
- p.setPen(m_selected);
- } else {
- p.setPen(palette().text().color());
- p.setBrush(palette().text());
- }
- p.drawLine(scaledPos, headOffset, scaledPos, m_size);
- p.drawEllipse(scaledPos - headOffset / 2, 0, headOffset, headOffset);
- pos++;
- }
- if (m_movingKeyframe) {
- p.setBrush(m_selected);
- int scaledPos = margin + (int)((m_movingItem.frame() - m_offset) * m_scale);
- // draw keyframes
- p.drawLine(scaledPos, headOffset, scaledPos, m_size);
- p.drawEllipse(scaledPos - headOffset / 2, 0, headOffset, headOffset);
- p.setBrush(m_keyframe);
- }
- }
- p.setPen(palette().text().color());
- p.drawLine(margin, m_lineHeight + (headOffset / 2), width() - margin - 1, m_lineHeight + (headOffset / 2));
- p.drawLine(margin, m_lineHeight - headOffset, margin, m_lineHeight + headOffset);
- p.drawLine(width() - margin, m_lineHeight - headOffset, width() - margin, m_lineHeight + headOffset);
- p.setPen(Qt::NoPen);
- // draw pointer
- if (m_seekPosition != SEEK_INACTIVE) {
- p.fillRect(margin + m_seekPosition * m_scale - 1, 0, 3, height(), palette().dark());
- }
- QPolygon pa(3);
- const int cursor = margin + m_position * m_scale;
- int cursorwidth = (m_size - (m_lineHeight + headOffset / 2)) / 2 + 1;
- pa.setPoints(3, cursor - cursorwidth, m_size, cursor + cursorwidth, m_size, cursor, m_lineHeight + (headOffset / 2) + 1);
- if (m_hoverKeyframe == -2) {
- p.setBrush(palette().highlight());
- } else {
- p.setBrush(palette().text());
- }
- p.drawPolygon(pa);
-}
-
-int KeyframeHelper::value() const
-{
- if (m_seekPosition == SEEK_INACTIVE) {
- return m_position + m_offset;
- }
- return m_seekPosition;
-}
-
-void KeyframeHelper::setValue(const int pos)
-{
- if (pos == m_position || m_geom == nullptr) {
- return;
- }
- if (pos == m_seekPosition) {
- m_seekPosition = SEEK_INACTIVE;
- }
- m_position = pos;
- update();
-}
-
-void KeyframeHelper::setKeyGeometry(Mlt::Geometry *geom, int in, int out, bool useOffset)
-{
- m_geom = geom;
- m_offset = useOffset ? in : 0;
- frameLength = qMax(1, out - in);
- update();
-}
-
-void KeyframeHelper::addGeometry(Mlt::Geometry *geom)
-{
- m_extraGeometries.append(geom);
-}
diff --git a/src/effectstack/keyframehelper.h b/src/effectstack/keyframehelper.h
deleted file mode 100644
index baa3f6d63..000000000
--- a/src/effectstack/keyframehelper.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
- * *
- * 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 2 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, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#ifndef KEYFRAMEHELPER_H
-#define KEYFRAMEHELPER_H
-
-#include
-
-#include
-
-#include "timecode.h"
-
-class KeyframeHelper : public QWidget
-{
- Q_OBJECT
-public:
- explicit KeyframeHelper(QWidget *parent = nullptr);
- int value() const;
- int frameLength;
-
-protected:
- void paintEvent(QPaintEvent * /*e*/) override;
- void wheelEvent(QWheelEvent *e) override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void mouseDoubleClickEvent(QMouseEvent *event) override;
- void leaveEvent(QEvent *event) override;
-
-private:
- Mlt::Geometry *m_geom;
- int m_position;
- int m_size;
- double m_scale;
- bool m_movingKeyframe;
- Mlt::GeometryItem m_movingItem;
- QList m_extraMovingItems;
- QPoint m_dragStart;
- int m_lineHeight;
- int m_hoverKeyframe;
- QColor m_selected;
- QColor m_keyframe;
- QList m_extraGeometries;
- int m_seekPosition;
- int m_offset;
-
-public slots:
- void setKeyGeometry(Mlt::Geometry *geom, int in, int out, bool useOffset = false);
- void addGeometry(Mlt::Geometry *geom);
- void setValue(const int pos);
-
-signals:
- void requestSeek(int);
- void keyframeMoved(int);
- void addKeyframe(int);
- void removeKeyframe(int);
-};
-
-#endif
diff --git a/src/effectstack/parameterplotter.cpp b/src/effectstack/parameterplotter.cpp
deleted file mode 100644
index fa3ae65d5..000000000
--- a/src/effectstack/parameterplotter.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-/***************************************************************************
- parameterplotter.cpp - description
- -------------------
- begin : Feb 15 2008
- copyright : (C) 2008 by Marco Gittler
- email : g.marco@freenet.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "parameterplotter.h"
-#include "kdenlive_debug.h"
-#include
-#include
-#include
-#include
-#include
-
-ParameterPlotter::ParameterPlotter(QWidget *parent)
- : KPlotWidget(parent)
-{
- setAntialiasing(true);
- setLeftPadding(20);
- setRightPadding(10);
- setTopPadding(10);
- setBottomPadding(20);
- m_movepoint = NULL;
- m_colors << Qt::white << Qt::red << Qt::green << Qt::blue << Qt::magenta << Qt::gray << Qt::cyan;
- m_moveX = false;
- m_moveY = true;
- m_moveTimeline = true;
- m_newPoints = false;
- m_activeIndexPlot = -1;
- m_max_y = 0;
- m_min_y = 0;
-}
-/*
- Lines
- Lines from top to bottom
- Marco Gittler
-
-
- Num
-
-
- Width
-
-
-
-*/
-void ParameterPlotter::setPointLists(const QDomElement &d, const QString ¶mName, int startframe, int endframe)
-{
-
- // QListIterator > > nameit(params);
- m_paramName = paramName;
- m_itemParameter = d;
- QDomNodeList namenode = d.elementsByTagName(QStringLiteral("parameter"));
-
- m_max_y = 0;
- m_min_y = 0;
- removeAllPlotObjects();
- m_stretchFactors.clear();
- m_parameterNameList.clear();
- m_plotobjects.clear();
-
- QString dat;
- QTextStream stre(&dat);
- d.save(stre, 2);
- // qCDebug(KDENLIVE_LOG) << dat;
- int i = 0;
- while (!namenode.item(i).isNull() && namenode.item(i).toElement().attribute(QStringLiteral("name")) != m_paramName) {
- ++i;
- }
-
- if (namenode.count()) {
- QDomElement pa = namenode.item(i).toElement();
- // QDomNode na = pa.firstChildElement("name");
-
- m_parameterNameList << pa.attribute(QStringLiteral("namedesc")).split(';');
- emit parameterList(m_parameterNameList);
-
- // max_y=pa.attributes().namedItem("max").nodeValue().toInt();
- // int val=pa.attributes().namedItem("value").nodeValue().toInt();
- QStringList defaults;
- if (pa.attribute(QStringLiteral("start")).contains(';')) {
- defaults = pa.attribute(QStringLiteral("start")).split(';');
- } else if (pa.attribute(QStringLiteral("value")).contains(';')) {
- defaults = pa.attribute(QStringLiteral("value")).split(';');
- } else if (pa.attribute(QStringLiteral("default")).contains(';')) {
- defaults = pa.attribute(QStringLiteral("default")).split(';');
- }
- QStringList maxv = pa.attribute(QStringLiteral("max")).split(';');
- QStringList minv = pa.attribute(QStringLiteral("min")).split(';');
- for (int i = 0; i < maxv.size() && i < minv.size(); ++i) {
- if (m_max_y < maxv[i].toInt()) {
- m_max_y = maxv[i].toInt();
- }
- if (m_min_y > minv[i].toInt()) {
- m_min_y = minv[i].toInt();
- }
- }
- for (int i = 0; i < m_parameterNameList.count(); ++i) {
- KPlotObject *plot = new KPlotObject(m_colors[m_plotobjects.size() % m_colors.size()]);
- plot->setShowLines(true);
- if (!m_stretchFactors.contains(i) && i < maxv.size()) {
- if (maxv[i].toInt() != 0) {
- m_stretchFactors[i] = m_max_y / maxv[i].toInt();
- } else {
- m_stretchFactors[i] = 1.0;
- }
- }
- if (i < defaults.size() && defaults[i].toDouble() > m_max_y) {
- defaults[i] = m_max_y;
- }
- int def = 0;
- if (i < defaults.size()) {
- def = (int)(defaults[i].toInt() * m_stretchFactors[i]);
- }
- QString name = QLatin1String("");
- if (i < m_parameterNameList.size()) {
- name = m_parameterNameList[i];
- }
- plot->addPoint(startframe, def, name);
- // add keyframes here
- plot->addPoint(endframe, def);
-
- m_plotobjects.append(plot);
- }
-
- /*TODO keyframes
- while (pointit.hasNext()){
- pointit.next();
- plot->addPoint(QPointF(pointit.key(),pointit.value().toDouble()),item.first,1);
- if (pointit.value().toInt() >maxy)
- max_y=pointit.value().toInt();
- }*/
- }
- setLimits(-1, endframe + 1, m_min_y - 10, m_max_y + 10);
-
- addPlotObjects(m_plotobjects);
-}
-
-void ParameterPlotter::createParametersNew()
-{
- QList plotobjs = plotObjects();
- if (plotobjs.size() != m_parameterNameList.size()) {
- // qCDebug(KDENLIVE_LOG) << "ERROR size not equal";
- }
- QDomNodeList namenode = m_itemParameter.elementsByTagName(QStringLiteral("parameter"));
- QString paramlist;
- QTextStream txtstr(¶mlist);
- QDomNode pa = namenode.item(0);
- if (!namenode.isEmpty()) {
- for (int i = 0; i < plotobjs.count(); ++i) {
- QList points = plotobjs.at(i)->points();
- for (const KPlotPoint *o : points) {
- txtstr << (int)o->y();
- break; // first no keyframes
- }
- if (i + 1 != plotobjs.count()) {
- txtstr << ';';
- }
- }
- }
- pa.attributes().namedItem(QStringLiteral("value")).setNodeValue(paramlist);
- pa.attributes().namedItem(QStringLiteral("start")).setNodeValue(paramlist);
- emit parameterChanged(m_itemParameter);
-}
-
-void ParameterPlotter::mouseMoveEvent(QMouseEvent *event)
-{
-
- if (m_movepoint != NULL) {
- QList list = pointsUnderPoint(event->pos() - QPoint(leftPadding(), topPadding()));
- int i = 0;
- for (KPlotObject *o : plotObjects()) {
- QList points = o->points();
- for (int p = 0; p < points.size(); ++p) {
- if (points[p] == m_movepoint && (m_activeIndexPlot == -1 || m_activeIndexPlot == i)) {
- QPoint delta = event->pos() - m_oldmousepoint;
- double newy = m_movepoint->y() - delta.y() * dataRect().height() / pixRect().height();
- if (m_moveY && newy > m_min_y && newy < m_max_y) {
- m_movepoint->setY(newy);
- }
- if (p > 0 && p < points.size() - 1) {
- double newx = m_movepoint->x() + delta.x() * dataRect().width() / pixRect().width();
- if (newx > points[p - 1]->x() && newx < points[p + 1]->x() && m_moveX) {
- m_movepoint->setX(m_movepoint->x() + delta.x() * dataRect().width() / pixRect().width());
- }
- }
- if (m_moveTimeline && (m_moveX || m_moveY)) {
- emit updateFrame(0);
- }
- replacePlotObject(i, o);
- m_oldmousepoint = event->pos();
- }
- }
- ++i;
- }
- createParametersNew();
- }
-}
-
-void ParameterPlotter::replot(const QString &name)
-{
-
- // removeAllPlotObjects();
- int i = 0;
- bool drawAll = name.isEmpty() || name == QLatin1String("all");
- m_activeIndexPlot = -1;
-
- for (KPlotObject *p : plotObjects()) {
- QString selectedName = QStringLiteral("none");
- if (i < m_parameterNameList.size()) {
- selectedName = m_parameterNameList[i];
- }
- p->setShowPoints(drawAll || selectedName == name);
- p->setShowLines(drawAll || selectedName == name);
- QPen pen = (drawAll || selectedName == name ? QPen(Qt::SolidLine) : QPen(Qt::NoPen));
- pen.setColor(p->linePen().color());
- p->setLabelPen(pen);
- if (selectedName == name) {
- m_activeIndexPlot = i;
- }
- replacePlotObject(++i, p);
- }
-}
-
-void ParameterPlotter::mousePressEvent(QMouseEvent *event)
-{
- // topPadding and other padding can be wrong and this (i hope) will be corrected in newer kde versions
- QPoint inPlot = event->pos() - QPoint(leftPadding(), topPadding());
- QList list = pointsUnderPoint(inPlot);
- if (event->button() == Qt::LeftButton) {
- if (list.size() > 0) {
- m_movepoint = list[0];
- m_oldmousepoint = event->pos();
- } else {
- if (m_newPoints && m_activeIndexPlot >= 0) {
- // setup new points
- KPlotObject *p = plotObjects().at(m_activeIndexPlot);
- QList points = p->points();
- QVector newpoints;
-
- double newx = inPlot.x() * dataRect().width() / pixRect().width();
- double newy = (height() - inPlot.y() - bottomPadding() - topPadding()) * dataRect().height() / pixRect().height();
- bool inserted = false;
- for (const KPlotPoint *pt : points) {
- if (pt->x() > newx && !inserted) {
- newpoints.append(QPointF(newx, newy));
- inserted = true;
- }
- newpoints.append(QPointF(pt->x(), pt->y()));
- }
- p->clearPoints();
- for (const QPointF qf : newpoints) {
- p->addPoint(qf);
- }
- replacePlotObject(m_activeIndexPlot, p);
- }
- m_movepoint = NULL;
- }
- }
-}
-
-void ParameterPlotter::setMoveX(bool b)
-{
- m_moveX = b;
-}
-
-void ParameterPlotter::setMoveY(bool b)
-{
- m_moveY = b;
-}
-
-void ParameterPlotter::setMoveTimeLine(bool b)
-{
- m_moveTimeline = b;
-}
-
-void ParameterPlotter::setNewPoints(bool b)
-{
- m_newPoints = b;
-}
-
-bool ParameterPlotter::isMoveX() const
-{
- return m_moveX;
-}
-
-bool ParameterPlotter::isMoveY() const
-{
- return m_moveY;
-}
-
-bool ParameterPlotter::isMoveTimeline() const
-{
- return m_moveTimeline;
-}
-
-bool ParameterPlotter::isNewPoints() const
-{
- return m_newPoints;
-}
diff --git a/src/effectstack/parameterplotter.h b/src/effectstack/parameterplotter.h
deleted file mode 100644
index 034dcf9f8..000000000
--- a/src/effectstack/parameterplotter.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/***************************************************************************
- parameterplotter.h - description
- -------------------
- begin : Feb 15 2008
- copyright : (C) 2008 by Marco Gittler
- email : g.marco@freenet.de
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef PARAMETERPLOTTER_H
-#define PARAMETERPLOTTER_H
-
-#include
-#include
-#include
-
-class ParameterPlotter : public KPlotWidget
-{
- Q_OBJECT
-public:
- explicit ParameterPlotter(QWidget *parent = nullptr);
- ~ParameterPlotter() {}
- void setMoveX(bool);
- void setMoveY(bool);
- void setMoveTimeLine(bool);
- void setNewPoints(bool);
- bool isMoveX() const;
- bool isMoveY() const;
- bool isMoveTimeline() const;
- bool isNewPoints() const;
- void replot(const QString &name = QString());
-
-private:
- KPlotPoint *m_movepoint;
- int m_activeIndexPlot;
- bool m_moveX, m_moveY, m_moveTimeline, m_newPoints;
- QPoint m_oldmousepoint;
- QStringList m_parameterNameList;
- void createParametersNew();
- QList m_plotobjects;
- QMap m_stretchFactors;
- QList m_colors;
- QDomElement m_itemParameter;
- int m_max_y, m_min_y;
- QString m_paramName;
-
-protected:
- void mouseMoveEvent(QMouseEvent *event);
- void mousePressEvent(QMouseEvent *event);
-public slots:
- void setPointLists(const QDomElement &, const QString ¶mName, int, int);
-signals:
- void parameterChanged(const QDomElement &);
- void updateFrame(int);
- void parameterList(const QStringList &);
-};
-
-#endif
diff --git a/src/effectstack/widgets/colorwheel.cpp b/src/effectstack/widgets/colorwheel.cpp
deleted file mode 100644
index deaa44d89..000000000
--- a/src/effectstack/widgets/colorwheel.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (c) 2013 Meltytech, LLC
- * Author: Dan Dennedy
- * Some ideas came from Qt-Plus: https://github.com/liuyanghejerry/Qt-Plus
- * and Steinar Gunderson's Movit demo app.
- *
- * 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 "colorwheel.h"
-#include
-
-NegQColor NegQColor::fromHsvF(qreal h, qreal s, qreal l, qreal a)
-{
- NegQColor color;
- color.qcolor = QColor::fromHsvF(h, s, l < 0 ? -l : l, a);
- color.sign_r = l < 0 ? -1 : 1;
- color.sign_g = l < 0 ? -1 : 1;
- color.sign_b = l < 0 ? -1 : 1;
- return color;
-}
-
-NegQColor NegQColor::fromRgbF(qreal r, qreal g, qreal b, qreal a)
-{
- NegQColor color;
- color.qcolor = QColor::fromRgbF(r < 0 ? -r : r, g < 0 ? -g : g, b < 0 ? -b : b, a);
- color.sign_r = r < 0 ? -1 : 1;
- color.sign_g = g < 0 ? -1 : 1;
- color.sign_b = b < 0 ? -1 : 1;
- return color;
-}
-
-qreal NegQColor::redF()
-{
- return qcolor.redF() * sign_r;
-}
-
-qreal NegQColor::greenF()
-{
- return qcolor.greenF() * sign_g;
-}
-
-qreal NegQColor::blueF()
-{
- return qcolor.blueF() * sign_b;
-}
-
-qreal NegQColor::valueF()
-{
- return qcolor.valueF() * sign_g;
-}
-
-int NegQColor::hue()
-{
- return qcolor.hue();
-}
-
-qreal NegQColor::hueF()
-{
- return qcolor.hueF();
-}
-
-qreal NegQColor::saturationF()
-{
- return qcolor.saturationF();
-}
-
-ColorWheel::ColorWheel(const QString &id, const QString &name, const NegQColor &color, QWidget *parent)
- : QWidget(parent)
- , m_id(id)
- , m_isMouseDown(false)
- , m_margin(5)
- , m_color(color)
- , m_isInWheel(false)
- , m_isInSquare(false)
- , m_name(name)
-{
- QFontInfo info(font());
- m_unitSize = info.pixelSize();
- m_initialSize = QSize(m_unitSize * 11.5, m_unitSize * 11);
- m_sliderWidth = m_unitSize * 1.5;
- resize(m_initialSize);
- setMinimumSize(100, 100);
- setMaximumSize(m_initialSize);
- setCursor(Qt::CrossCursor);
-}
-
-void ColorWheel::setFactorDefaultZero(qreal factor, qreal defvalue, qreal zero)
-{
- m_sizeFactor = factor;
- m_defaultValue = defvalue;
- m_zeroShift = zero;
-}
-
-NegQColor ColorWheel::color()
-{
- return m_color;
-}
-
-void ColorWheel::setColor(const NegQColor &color)
-{
- m_color = color;
-}
-
-int ColorWheel::wheelSize() const
-{
- return qMin(width() - m_sliderWidth, height() - m_unitSize);
-}
-
-NegQColor ColorWheel::colorForPoint(const QPoint &point)
-{
- if (!m_image.valid(point)) {
- return QColor();
- }
- if (m_isInWheel) {
- qreal w = wheelSize();
- qreal xf = qreal(point.x()) / w;
- qreal yf = 1.0 - qreal(point.y()) / w;
- qreal xp = 2.0 * xf - 1.0;
- qreal yp = 2.0 * yf - 1.0;
- qreal rad = qMin(hypot(xp, yp), 1.0);
- qreal theta = qAtan2(yp, xp);
- theta -= 105.0 / 360.0 * 2.0 * M_PI;
- if (theta < 0.0) {
- theta += 2.0 * M_PI;
- }
- qreal hue = (theta * 180.0 / M_PI) / 360.0;
- return NegQColor::fromHsvF(hue, rad, m_color.valueF());
- }
- if (m_isInSquare) {
- qreal value = 1.0 - qreal(point.y() - m_margin) / (wheelSize() - m_margin * 2);
- if (m_zeroShift != 0) {
- value = value - m_zeroShift;
- }
-
- return NegQColor::fromHsvF(m_color.hueF(), m_color.saturationF(), value);
- }
- return NegQColor();
-}
-
-QSize ColorWheel::sizeHint() const
-{
- return QSize(width(), height());
-}
-
-QSize ColorWheel::minimumSizeHint() const
-{
- return QSize(100, 100);
-}
-
-void ColorWheel::mousePressEvent(QMouseEvent *event)
-{
- m_lastPoint = event->pos();
- if (m_wheelRegion.contains(m_lastPoint)) {
- m_isInWheel = true;
- m_isInSquare = false;
- if (event->button() == Qt::LeftButton) {
- changeColor(colorForPoint(m_lastPoint));
- } else {
- // reset to default on middle button
- qreal r = m_color.redF();
- qreal b = m_color.blueF();
- qreal g = m_color.greenF();
- qreal max = qMax(r, b);
- max = qMax(max, g);
- changeColor(NegQColor::fromRgbF(max, max, max));
- }
- } else if (m_sliderRegion.contains(m_lastPoint)) {
- m_isInWheel = false;
- m_isInSquare = true;
- if (event->button() == Qt::LeftButton) {
- changeColor(colorForPoint(m_lastPoint));
- } else {
- NegQColor c;
- c = NegQColor::fromRgbF(m_defaultValue / m_sizeFactor, m_defaultValue / m_sizeFactor, m_defaultValue / m_sizeFactor);
- changeColor(c);
- }
- }
- m_isMouseDown = true;
-}
-
-void ColorWheel::mouseMoveEvent(QMouseEvent *event)
-{
- m_lastPoint = event->pos();
- if (!m_isMouseDown) {
- return;
- }
- if (m_wheelRegion.contains(m_lastPoint) && m_isInWheel) {
- const NegQColor color = colorForPoint(m_lastPoint);
- changeColor(color);
- } else if (m_sliderRegion.contains(m_lastPoint) && m_isInSquare) {
- const NegQColor color = colorForPoint(m_lastPoint);
- changeColor(color);
- }
-}
-
-void ColorWheel::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_UNUSED(event)
- m_isMouseDown = false;
- m_isInWheel = false;
- m_isInSquare = false;
-}
-
-void ColorWheel::resizeEvent(QResizeEvent *event)
-{
- m_image = QImage(event->size(), QImage::Format_ARGB32_Premultiplied);
- m_image.fill(palette().background().color().rgb());
-
- drawWheel();
- drawSlider();
- update();
-}
-
-QString ColorWheel::getParamValues()
-{
- if (m_id == QLatin1String("gamma")) {
- return QString::number(m_color.redF() * 2, 'g', 2) + QLatin1Char(',') + QString::number(m_color.greenF() * 2, 'g', 2) + QLatin1Char(',') +
- QString::number(m_color.blueF() * 2, 'g', 2);
- }
- if (m_id == QLatin1String("gain")) {
- return QString::number(m_color.redF() * 4, 'g', 2) + QLatin1Char(',') + QString::number(m_color.greenF() * 4, 'g', 2) + QLatin1Char(',') +
- QString::number(m_color.blueF() * 4, 'g', 2);
- }
- // default (lift)
- return QString::number(m_color.redF(), 'g', 2) + QLatin1Char(',') + QString::number(m_color.greenF(), 'g', 2) + QLatin1Char(',') +
- QString::number(m_color.blueF(), 'g', 2);
-}
-
-void ColorWheel::paintEvent(QPaintEvent *event)
-{
- Q_UNUSED(event)
- QPainter painter(this);
- // QStyleOption opt;
- // opt.init(this);
- painter.setRenderHint(QPainter::Antialiasing);
- painter.drawImage(0, 0, m_image);
- // painter.drawRect(0, 0, width(), height());
- painter.drawText(m_margin, wheelSize() + m_unitSize - m_margin, m_name + QLatin1Char(' ') + getParamValues());
- drawWheelDot(painter);
- drawSliderBar(painter);
- // style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
-}
-
-void ColorWheel::drawWheel()
-{
- int r = wheelSize();
- QPainter painter(&m_image);
- painter.setRenderHint(QPainter::Antialiasing);
- m_image.fill(0); // transparent
-
- QConicalGradient conicalGradient;
- conicalGradient.setColorAt(0.0, Qt::red);
- conicalGradient.setColorAt(60.0 / 360.0, Qt::yellow);
- conicalGradient.setColorAt(135.0 / 360.0, Qt::green);
- conicalGradient.setColorAt(180.0 / 360.0, Qt::cyan);
- conicalGradient.setColorAt(240.0 / 360.0, Qt::blue);
- conicalGradient.setColorAt(315.0 / 360.0, Qt::magenta);
- conicalGradient.setColorAt(1.0, Qt::red);
-
- QRadialGradient radialGradient(0.0, 0.0, r / 2);
- radialGradient.setColorAt(0.0, Qt::white);
- radialGradient.setColorAt(1.0, Qt::transparent);
-
- painter.translate(r / 2, r / 2);
- painter.rotate(-105);
-
- QBrush hueBrush(conicalGradient);
- painter.setPen(Qt::NoPen);
- painter.setBrush(hueBrush);
- painter.drawEllipse(QPoint(0, 0), r / 2 - m_margin, r / 2 - m_margin);
-
- QBrush saturationBrush(radialGradient);
- painter.setBrush(saturationBrush);
- painter.drawEllipse(QPoint(0, 0), r / 2 - m_margin, r / 2 - m_margin);
-
- m_wheelRegion = QRegion(r / 2, r / 2, r - 2 * m_margin, r - 2 * m_margin, QRegion::Ellipse);
- m_wheelRegion.translate(-(r - 2 * m_margin) / 2, -(r - 2 * m_margin) / 2);
-}
-
-void ColorWheel::drawSlider()
-{
- QPainter painter(&m_image);
- painter.setRenderHint(QPainter::Antialiasing);
- int ws = wheelSize();
- qreal scale = qreal(ws + m_sliderWidth) / maximumWidth();
- int w = m_sliderWidth * scale;
- int h = ws - m_margin * 2;
- QLinearGradient gradient(0, 0, w, h);
- gradient.setColorAt(0.0, Qt::white);
- gradient.setColorAt(1.0, Qt::black);
- QBrush brush(gradient);
- painter.setPen(Qt::NoPen);
- painter.setBrush(brush);
- painter.translate(ws, m_margin);
- painter.drawRect(0, 0, w, h);
- m_sliderRegion = QRegion(ws, m_margin, w, h);
-}
-
-void ColorWheel::drawWheelDot(QPainter &painter)
-{
- int r = wheelSize() / 2;
- QPen pen(Qt::white);
- pen.setWidth(2);
- painter.setPen(pen);
- painter.setBrush(Qt::black);
- painter.translate(r, r);
- painter.rotate(360.0 - m_color.hue());
- painter.rotate(-105);
- // r -= margin;
- painter.drawEllipse(QPointF(m_color.saturationF() * r, 0.0), 4, 4);
- painter.resetTransform();
-}
-
-void ColorWheel::drawSliderBar(QPainter &painter)
-{
- qreal value = 1.0 - m_color.valueF();
- if (m_id == QLatin1String("lift")) {
- value -= m_zeroShift;
- }
-
- int ws = wheelSize();
- qreal scale = qreal(ws + m_sliderWidth) / maximumWidth();
- int w = m_sliderWidth * scale;
- int h = ws - m_margin * 2;
- QPen pen(Qt::white);
- pen.setWidth(2);
- painter.setPen(pen);
- painter.setBrush(Qt::black);
- painter.translate(ws, m_margin + value * h);
- painter.drawRect(0, 0, w, 4);
- painter.resetTransform();
-}
-
-void ColorWheel::changeColor(const NegQColor &color)
-{
- m_color = color;
- drawWheel();
- drawSlider();
- update();
- emit colorChange(m_color);
-}
diff --git a/src/effectstack/widgets/colorwheel.h b/src/effectstack/widgets/colorwheel.h
deleted file mode 100644
index 13ecdc0a9..000000000
--- a/src/effectstack/widgets/colorwheel.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013 Meltytech, LLC
- * Author: Dan Dennedy
- *
- * 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 COLORWHEEL_H
-#define COLORWHEEL_H
-
-#include
-#include
-#include
-
-class NegQColor
-{
-public:
- int8_t sign_r = 1;
- int8_t sign_g = 1;
- int8_t sign_b = 1;
- QColor qcolor;
- static NegQColor fromHsvF(qreal h, qreal s, qreal l, qreal a = 1.0);
- static NegQColor fromRgbF(qreal r, qreal g, qreal b, qreal a = 1.0);
- qreal redF();
- qreal greenF();
- qreal blueF();
- qreal valueF();
- int hue();
- qreal hueF();
- qreal saturationF();
-};
-
-class ColorWheel : public QWidget
-{
- Q_OBJECT
-public:
- explicit ColorWheel(const QString &id, const QString &name, const NegQColor &color, QWidget *parent = nullptr);
-
- QSize sizeHint() const override;
- QSize minimumSizeHint() const override;
- QColor color();
- void setColor(const QColor &color);
-
-signals:
- void colorChange(const NegQColor &color);
-
-public slots:
- void changeColor(const NegQColor &color);
-
-protected:
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseReleaseEvent(QMouseEvent *event) override;
- void resizeEvent(QResizeEvent *event) override;
- void paintEvent(QPaintEvent *event) override;
-
-private:
- QString m_id;
- QSize m_initialSize;
- QImage m_image;
- bool m_isMouseDown;
- QPoint m_lastPoint;
- int m_margin;
- int m_sliderWidth;
- QRegion m_wheelRegion;
- QRegion m_sliderRegion;
- NegQColor m_color;
- bool m_isInWheel;
- bool m_isInSquare;
- int m_unitSize;
- QString m_name;
-
- qreal m_sizeFactor = 1;
- qreal m_defaultValue = 1;
- qreal m_zeroShift = 0;
-
- int wheelSize() const;
- NegQColor colorForPoint(const QPoint &point);
- void drawWheel();
- void drawWheelDot(QPainter &painter);
- void drawSliderBar(QPainter &painter);
- void drawSlider();
- QString getParamValues();
-};
-
-#endif // COLORWHEEL_H
diff --git a/src/effectstack/widgets/curves/CMakeLists.txt b/src/effectstack/widgets/curves/CMakeLists.txt
deleted file mode 100644
index 7389d3daa..000000000
--- a/src/effectstack/widgets/curves/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-set(kdenlive_SRCS
- ${kdenlive_SRCS}
- effectstack/widgets/curves/abstractcurvewidget.h
- effectstack/widgets/curves/bezier/beziersplineeditor.cpp
- effectstack/widgets/curves/bezier/bpoint.cpp
- effectstack/widgets/curves/bezier/cubicbezierspline.cpp
- effectstack/widgets/curves/cubic/kis_curve_widget.cpp
- effectstack/widgets/curves/cubic/kis_cubic_curve.cpp
- PARENT_SCOPE
-)
diff --git a/src/effectstack/widgets/curves/abstractcurvewidget.h b/src/effectstack/widgets/curves/abstractcurvewidget.h
deleted file mode 100644
index 295d80848..000000000
--- a/src/effectstack/widgets/curves/abstractcurvewidget.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by Nicolas Carion *
- * This file is part of Kdenlive. See www.kdenlive.org. *
- * *
- * 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 2 of the License, or *
- * (at your option) version 3 or any later version accepted by the *
- * membership of KDE e.V. (or its successor approved by the membership *
- * of KDE e.V.), which shall act as a proxy defined in Section 14 of *
- * version 3 of the license. *
- * *
- * 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 ABSTRACTCURVEWIDGET_H
-#define ABSTRACTCURVEWIDGET_H
-
-#include "bezier/bpoint.h"
-#include
-#include
-
-#include
-
-/** State of a point being moved */
-enum class State_t { NORMAL, DRAG };
-
-/** This class is a workaround to be able to use templating in the actual class
- Note that Qt doesn't support templated signals, so we have to define a signal for
- all possible Point type
-*/
-class __dummy_AbstractCurveWidget : public QWidget
-{
- Q_OBJECT
-public:
- __dummy_AbstractCurveWidget(QWidget *parent)
- : QWidget(parent)
- {
- }
-
-signals:
- /**
- * Emitted whenever a control point has changed position.
- */
- void modified(void);
- /**
- Signal sent when the current point changes. The point is returned, as well as a flag that determines if the point is the first or last.
- */
- void currentPoint(const QPointF &p, bool extremal);
- void currentPoint(const BPoint &p, bool extremal);
- void resized(const QSize &s);
-
-public slots:
- /** @brief Delete current spline point if it is not a extremal point (first or last)
- */
- virtual void slotDeleteCurrentPoint() = 0;
- virtual void slotZoomIn() = 0;
- virtual void slotZoomOut() = 0;
- virtual void reset() = 0;
-};
-
-/** @brief Base class of all the widgets representing a curve of points
-
- */
-template class AbstractCurveWidget : public __dummy_AbstractCurveWidget
-{
-public:
- typedef typename Curve_t::Point_t Point_t;
- virtual ~AbstractCurveWidget(){};
-
- /** @param parent Optional parent of the widget
- */
- AbstractCurveWidget(QWidget *parent = nullptr);
-
- /** @brief Returns whether the points are controlled with additional handles
- */
- virtual bool hasHandles() { return false; }
-
- /** @brief Sets the maximal number of points of the curve
- */
- void setMaxPoints(int max);
-
- /** @brief Sets the background pixmap to @param pixmap.
- The background pixmap will be drawn under the grid and the curve*/
- void setPixmap(const QPixmap &pixmap);
-
- /** @brief Number of lines used in grid. */
- int gridLines() const;
-
- /** @brief Sets the number of grid lines to draw (in one direction) to @param lines. */
- void setGridLines(int lines);
-
- /** @brief Constructs the curve from @param string
- */
- void setFromString(const QString &string);
-
- /** @brief Resets the curve to an empty one
- */
- void reset();
-
- /** @brief Returns a string corresponding to the curve
- */
- QString toString();
-
- /** @brief Replaces current point with @param p (index stays the same).
- * @param final (default = true) emit signal modified? */
- void updateCurrentPoint(const Point_t &p, bool final = true);
-
- /** @brief Returns the selected point or else empty point. */
- Point_t getCurrentPoint();
-
- /** @brief Returns the list of all the points. */
- virtual QList getPoints() const = 0;
-
-public:
- /** @brief Delete current spline point if it is not a extremal point (first or last)
- */
- void slotDeleteCurrentPoint();
- void slotZoomIn();
- void slotZoomOut();
-
-protected:
- void paintBackground(QPainter *p);
- int heightForWidth(int w) const override;
- void resizeEvent(QResizeEvent *event) override;
- void leaveEvent(QEvent *) override;
- void mouseReleaseEvent(QMouseEvent *e) override;
- void keyPressEvent(QKeyEvent *) override;
- /**
- Utility function to check if current selected point is the first or the last
- */
- bool isCurrentPointExtremal();
-
- int m_zoomLevel;
- int m_gridLines;
- /** Background */
- QPixmap m_pixmap;
- /** A copy of m_pixmap but scaled to fit the size of the edit region */
- std::shared_ptr m_pixmapCache;
- /** Whether we have to regenerate the pixmap cache because the pixmap or the size of the edit region changed. */
- bool m_pixmapIsDirty;
-
- int m_currentPointIndex;
- int m_maxPoints;
- int m_wWidth, m_wHeight;
-
- State_t m_state;
- Curve_t m_curve;
-
- double m_grabRadius;
-};
-
-#include "abstractcurvewidget.ipp"
-
-#endif
diff --git a/src/effectstack/widgets/curves/abstractcurvewidget.ipp b/src/effectstack/widgets/curves/abstractcurvewidget.ipp
deleted file mode 100644
index 9158c72c6..000000000
--- a/src/effectstack/widgets/curves/abstractcurvewidget.ipp
+++ /dev/null
@@ -1,250 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by Nicolas Carion *
- * *
- * 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 2 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, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-#include
-#include
-#include
-
-template
-AbstractCurveWidget::AbstractCurveWidget(QWidget *parent)
- : __dummy_AbstractCurveWidget(parent)
- , m_zoomLevel(0)
- , m_gridLines(3)
- , m_pixmapCache(nullptr)
- , m_pixmapIsDirty(true)
- , m_currentPointIndex(-1)
- , m_maxPoints(1000000)
- , m_state(State_t::NORMAL)
- , m_grabRadius(10)
-{
- setMouseTracking(true);
- setAutoFillBackground(false);
- setAttribute(Qt::WA_OpaquePaintEvent);
- setMinimumSize(150, 150);
- setMaximumSize(500, 500);
- QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred);
- sp.setHeightForWidth(true); // force widget to have a height dependent on width;
- setSizePolicy(sp);
- setFocusPolicy(Qt::StrongFocus);
-}
-
-template void AbstractCurveWidget::paintBackground(QPainter *p)
-{
- /*
- * Zoom
- */
- m_wWidth = width() - 1;
- m_wHeight = height() - 1;
- int offsetX = 1 / 8. * m_zoomLevel * m_wWidth;
- int offsetY = 1 / 8. * m_zoomLevel * m_wHeight;
- m_wWidth -= 2 * offsetX;
- m_wHeight -= 2 * offsetY;
-
- p->translate(offsetX, offsetY);
-
- /*
- * Background
- */
- p->fillRect(rect().translated(-offsetX, -offsetY), palette().background());
- if (!m_pixmap.isNull()) {
- if (m_pixmapIsDirty || !m_pixmapCache) {
- m_pixmapCache = std::make_shared(m_wWidth + 1, m_wHeight + 1);
- QPainter cachePainter(m_pixmapCache.get());
-
- cachePainter.scale(1.0 * (m_wWidth + 1) / m_pixmap.width(), 1.0 * (m_wHeight + 1) / m_pixmap.height());
- cachePainter.drawPixmap(0, 0, m_pixmap);
- m_pixmapIsDirty = false;
- }
- p->drawPixmap(0, 0, *m_pixmapCache);
- }
-
- // select color of the grid, depending on whether we have a palette or not
- if (!m_pixmap.isNull()) {
- p->setPen(QPen(palette().mid().color(), 1, Qt::SolidLine));
- } else {
- int h, s, l, a;
- auto bg = palette().color(QPalette::Window);
- bg.getHsl(&h, &s, &l, &a);
- l = (l > 128) ? l - 30 : l + 30;
- bg.setHsl(h, s, l, a);
- p->setPen(QPen(bg, 1, Qt::SolidLine));
- }
-
- /*
- * Borders
- */
- p->drawRect(0, 0, m_wWidth, m_wHeight);
-
- /*
- * Grid
- */
- if (m_gridLines != 0) {
- double stepH = m_wWidth / (double)(m_gridLines + 1);
- double stepV = m_wHeight / (double)(m_gridLines + 1);
- for (int i = 1; i <= m_gridLines; ++i) {
- p->drawLine(QLineF(i * stepH, 0, i * stepH, m_wHeight));
- p->drawLine(QLineF(0, i * stepV, m_wWidth, i * stepV));
- }
- }
-
- p->setRenderHint(QPainter::Antialiasing);
-
- /*
- * Standard line
- */
- p->drawLine(QLineF(0, m_wHeight, m_wWidth, 0));
-}
-
-template void AbstractCurveWidget::setMaxPoints(int max)
-{
- Q_ASSERT(max >= 2);
- m_maxPoints = max;
-}
-
-template void AbstractCurveWidget::setPixmap(const QPixmap &pix)
-{
- m_pixmap = pix;
- m_pixmapIsDirty = true;
- update();
-}
-
-template int AbstractCurveWidget::gridLines() const
-{
- return m_gridLines;
-}
-
-template void AbstractCurveWidget::setGridLines(int lines)
-{
- m_gridLines = qBound(0, lines, 8);
- update();
-}
-
-template void AbstractCurveWidget::slotZoomIn()
-{
- m_zoomLevel = qMax(m_zoomLevel - 1, 0);
- m_pixmapIsDirty = true;
- update();
-}
-
-template void AbstractCurveWidget::slotZoomOut()
-{
- m_zoomLevel = qMin(m_zoomLevel + 1, 3);
- m_pixmapIsDirty = true;
- update();
-}
-
-template void AbstractCurveWidget::setFromString(const QString &str)
-{
- m_curve.fromString(str);
- m_currentPointIndex = -1;
- emit currentPoint(Point_t(), true);
- emit modified();
- update();
-}
-
-template void AbstractCurveWidget::reset()
-{
- setFromString(Curve_t().toString());
- m_currentPointIndex = -1;
- emit currentPoint(Point_t(), true);
- emit modified();
- update();
-}
-
-template QString AbstractCurveWidget::toString()
-{
- return m_curve.toString();
-}
-
-template void AbstractCurveWidget::updateCurrentPoint(const Point_t &p, bool final)
-{
- if (m_currentPointIndex >= 0) {
- m_curve.setPoint(m_currentPointIndex, p);
- // during validation the point might have changed
- emit currentPoint(m_curve.getPoint(m_currentPointIndex), isCurrentPointExtremal());
- if (final) {
- emit modified();
- }
- update();
- }
-}
-
-template typename AbstractCurveWidget::Point_t AbstractCurveWidget::getCurrentPoint()
-{
- if (m_currentPointIndex >= 0) {
- return m_curve.getPoint(m_currentPointIndex);
- } else {
- return Point_t();
- }
-}
-
-template bool AbstractCurveWidget::isCurrentPointExtremal()
-{
- return m_currentPointIndex == 0 || m_currentPointIndex == m_curve.points().size() - 1;
-}
-
-template void AbstractCurveWidget::slotDeleteCurrentPoint()
-{
- if (m_currentPointIndex > 0 && m_currentPointIndex < m_curve.points().size() - 1) {
- m_curve.removePoint(m_currentPointIndex);
- m_currentPointIndex--;
- emit currentPoint(m_curve.getPoint(m_currentPointIndex), isCurrentPointExtremal());
- update();
- emit modified();
- setCursor(Qt::ArrowCursor);
- m_state = State_t::NORMAL;
- }
-}
-
-template void AbstractCurveWidget::resizeEvent(QResizeEvent *e)
-{
- m_pixmapIsDirty = true;
- QWidget::resizeEvent(e);
-}
-
-template void AbstractCurveWidget::leaveEvent(QEvent *event)
-{
- QWidget::leaveEvent(event);
-}
-
-template void AbstractCurveWidget::mouseReleaseEvent(QMouseEvent *event)
-{
- if (event->button() != Qt::LeftButton) {
- return;
- }
-
- setCursor(Qt::ArrowCursor);
- m_state = State_t::NORMAL;
-
- emit modified();
-}
-
-template void AbstractCurveWidget::keyPressEvent(QKeyEvent *e)
-{
- if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
- slotDeleteCurrentPoint();
- } else {
- QWidget::keyPressEvent(e);
- }
-}
-
-template int AbstractCurveWidget::heightForWidth(int w) const
-{
- return w;
-}
diff --git a/src/effectstack/widgets/curves/bezier/beziersplineeditor.cpp b/src/effectstack/widgets/curves/bezier/beziersplineeditor.cpp
deleted file mode 100644
index c753e9378..000000000
--- a/src/effectstack/widgets/curves/bezier/beziersplineeditor.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2010 by Till Theato (root@ttill.de) *
- * This file is part of Kdenlive (www.kdenlive.org). *
- * *
- * Kdenlive 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- * Kdenlive 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 Kdenlive. If not, see . *
- ***************************************************************************/
-
-#include "beziersplineeditor.h"
-#include "cubicbezierspline.h"
-#include "kdenlivesettings.h"
-
-#include "complex"
-
-#include
-#include
-
-BezierSplineEditor::BezierSplineEditor(QWidget *parent)
- : AbstractCurveWidget(parent)
- , m_showAllHandles(true)
- , m_currentPointType(BPoint::PointType::P)
- , m_grabOffsetX(0)
- , m_grabOffsetY(0)
-{
- m_curve = CubicBezierSpline();
-}
-
-BezierSplineEditor::~BezierSplineEditor() {}
-
-void BezierSplineEditor::paintEvent(QPaintEvent *event)
-{
- Q_UNUSED(event)
-
- QPainter p(this);
-
- paintBackground(&p);
-
- /*
- * Prepare Spline, Points
- */
- int max = m_curve.count() - 1;
- if (max < 1) {
- return;
- }
- BPoint point(m_curve.getPoint(0, m_wWidth, m_wHeight, true));
-
- /*
- * Spline
- */
- BPoint next;
-
- QPainterPath splinePath(QPointF(point.p.x(), point.p.y()));
- for (int i = 0; i < max; ++i) {
- point = m_curve.getPoint(i, m_wWidth, m_wHeight, true);
- next = m_curve.getPoint(i + 1, m_wWidth, m_wHeight, true);
- splinePath.cubicTo(point.h2, next.h1, next.p);
- }
- p.setPen(QPen(palette().text().color(), 1, Qt::SolidLine));
- p.drawPath(splinePath);
-
- /*
- * Points + Handles
- */
- p.setPen(QPen(Qt::red, 1, Qt::SolidLine));
-
- QPolygonF handle = QPolygonF() << QPointF(0, -3) << QPointF(3, 0) << QPointF(0, 3) << QPointF(-3, 0);
-
- for (int i = 0; i <= max; ++i) {
- point = m_curve.getPoint(i, m_wWidth, m_wHeight, true);
-
- if (i == m_currentPointIndex) {
- // selected point: fill p and handles
- p.setBrush(QBrush(QColor(Qt::red), Qt::SolidPattern));
- // connect p and handles with lines
- if (i != 0) {
- p.drawLine(QLineF(point.h1.x(), point.h1.y(), point.p.x(), point.p.y()));
- }
- if (i != max) {
- p.drawLine(QLineF(point.p.x(), point.p.y(), point.h2.x(), point.h2.y()));
- }
- }
-
- p.drawEllipse(QRectF(point.p.x() - 3, point.p.y() - 3, 6, 6));
- if (i != 0 && (i == m_currentPointIndex || m_showAllHandles)) {
- p.drawConvexPolygon(handle.translated(point.h1.x(), point.h1.y()));
- }
- if (i != max && (i == m_currentPointIndex || m_showAllHandles)) {
- p.drawConvexPolygon(handle.translated(point.h2.x(), point.h2.y()));
- }
-
- if (i == m_currentPointIndex) {
- p.setBrush(QBrush(Qt::NoBrush));
- }
- }
-}
-
-void BezierSplineEditor::mousePressEvent(QMouseEvent *event)
-{
- int wWidth = width() - 1;
- int wHeight = height() - 1;
- int offsetX = 1 / 8. * m_zoomLevel * wWidth;
- int offsetY = 1 / 8. * m_zoomLevel * wHeight;
- wWidth -= 2 * offsetX;
- wHeight -= 2 * offsetY;
-
- double x = (event->pos().x() - offsetX) / (double)(wWidth);
- double y = 1.0 - (event->pos().y() - offsetY) / (double)(wHeight);
-
- BPoint::PointType selectedPoint;
- int closestPointIndex = nearestPointInRange(QPointF(x, y), wWidth, wHeight, &selectedPoint);
-
- if (event->button() == Qt::RightButton && closestPointIndex > 0 && closestPointIndex < m_curve.count() - 1 && selectedPoint == BPoint::PointType::P) {
- m_currentPointIndex = closestPointIndex;
- slotDeleteCurrentPoint();
- return;
- }
- if (event->button() != Qt::LeftButton) {
- return;
- }
-
- if (closestPointIndex < 0) {
- if (m_curve.count() < m_maxPoints) {
- m_currentPointIndex = m_curve.addPoint(QPointF(x, y));
- m_currentPointType = BPoint::PointType::P;
- }
- } else {
- m_currentPointIndex = closestPointIndex;
- m_currentPointType = selectedPoint;
- }
-
- BPoint point = m_curve.getPoint(m_currentPointIndex);
-
- m_grabPOriginal = point;
- if (m_currentPointIndex > 0) {
- m_grabPPrevious = m_curve.getPoint(m_currentPointIndex - 1);
- }
- if (m_currentPointIndex < m_curve.count() - 1) {
- m_grabPNext = m_curve.getPoint(m_currentPointIndex + 1);
- }
- m_grabOffsetX = point[(int)m_currentPointType].x() - x;
- m_grabOffsetY = point[(int)m_currentPointType].y() - y;
-
- point[(int)m_currentPointType] = QPointF(x + m_grabOffsetX, y + m_grabOffsetY);
-
- m_curve.setPoint(m_currentPointIndex, point);
-
- m_state = State_t::DRAG;
-
- emit currentPoint(point, isCurrentPointExtremal());
- emit modified();
- update();
-}
-
-void BezierSplineEditor::mouseMoveEvent(QMouseEvent *event)
-{
- int wWidth = width() - 1;
- int wHeight = height() - 1;
- int offsetX = 1 / 8. * m_zoomLevel * wWidth;
- int offsetY = 1 / 8. * m_zoomLevel * wHeight;
- wWidth -= 2 * offsetX;
- wHeight -= 2 * offsetY;
-
- double x = (event->pos().x() - offsetX) / (double)(wWidth);
- double y = 1.0 - (event->pos().y() - offsetY) / (double)(wHeight);
-
- if (m_state == State_t::NORMAL) {
- // If no point is selected set the cursor shape if on top
- BPoint::PointType type;
- int nearestPointIndex = nearestPointInRange(QPointF(x, y), wWidth, wHeight, &type);
-
- if (nearestPointIndex < 0) {
- setCursor(Qt::ArrowCursor);
- } else {
- setCursor(Qt::CrossCursor);
- }
- } else {
- // Else, drag the selected point
- setCursor(Qt::CrossCursor);
-
- x += m_grabOffsetX;
- y += m_grabOffsetY;
-
- double leftX = 0.;
- double rightX = 1.;
- BPoint point = m_curve.getPoint(m_currentPointIndex);
- switch (m_currentPointType) {
- case BPoint::PointType::H1:
- rightX = point.p.x();
- if (m_currentPointIndex == 0) {
- leftX = -4;
- } else {
- leftX = m_curve.getPoint(m_currentPointIndex - 1).p.x();
- }
-
- x = qBound(leftX, x, rightX);
- point.setH1(QPointF(x, y));
- break;
-
- case BPoint::PointType::P:
- if (m_currentPointIndex == 0) {
- rightX = 0.0;
- } else if (m_currentPointIndex == m_curve.count() - 1) {
- leftX = 1.0;
- }
-
- x = qBound(leftX, x, rightX);
- y = qBound(0., y, 1.);
-
- // handles might have changed because we neared another point
- // try to restore
- point.h1 = m_grabPOriginal.h1;
- point.h2 = m_grabPOriginal.h2;
- // and move by same offset
- // (using update handle in point.setP won't work because the offset between new and old point is very small)
- point.h1 += QPointF(x, y) - m_grabPOriginal.p;
- point.h2 += QPointF(x, y) - m_grabPOriginal.p;
-
- point.setP(QPointF(x, y), false);
- break;
-
- case BPoint::PointType::H2:
- leftX = point.p.x();
- if (m_currentPointIndex == m_curve.count() - 1) {
- rightX = 5;
- } else {
- rightX = m_curve.getPoint(m_currentPointIndex + 1).p.x();
- }
-
- x = qBound(leftX, x, rightX);
- point.setH2(QPointF(x, y));
- };
-
- int index = m_currentPointIndex;
- m_currentPointIndex = m_curve.setPoint(m_currentPointIndex, point);
-
- if (m_currentPointType == BPoint::PointType::P) {
- // we might have changed the handles of other points
- // try to restore
- if (index == m_currentPointIndex) {
- if (m_currentPointIndex > 0) {
- m_curve.setPoint(m_currentPointIndex - 1, m_grabPPrevious);
- }
- if (m_currentPointIndex < m_curve.count() - 1) {
- m_curve.setPoint(m_currentPointIndex + 1, m_grabPNext);
- }
- } else {
- if (m_currentPointIndex < index) {
- m_curve.setPoint(index, m_grabPPrevious);
- m_grabPNext = m_grabPPrevious;
- if (m_currentPointIndex > 0) {
- m_grabPPrevious = m_curve.getPoint(m_currentPointIndex - 1);
- }
- } else {
- m_curve.setPoint(index, m_grabPNext);
- m_grabPPrevious = m_grabPNext;
- if (m_currentPointIndex < m_curve.count() - 1) {
- m_grabPNext = m_curve.getPoint(m_currentPointIndex + 1);
- }
- }
- }
- }
-
- emit currentPoint(point, isCurrentPointExtremal());
- if (KdenliveSettings::dragvalue_directupdate()) {
- emit modified();
- }
- update();
- }
-}
-
-void BezierSplineEditor::mouseDoubleClickEvent(QMouseEvent * /*event*/)
-{
- if (m_currentPointIndex >= 0) {
- BPoint p = m_curve.getPoint(m_currentPointIndex);
- p.handlesLinked = !p.handlesLinked;
- m_curve.setPoint(m_currentPointIndex, p);
- emit currentPoint(p, isCurrentPointExtremal());
- }
-}
-
-int BezierSplineEditor::nearestPointInRange(const QPointF &p, int wWidth, int wHeight, BPoint::PointType *sel)
-{
-
- auto nearest = m_curve.closestPoint(p);
- int nearestIndex = nearest.first;
- BPoint::PointType pointType = nearest.second;
-
- if (nearestIndex >= 0 && (nearestIndex == m_currentPointIndex || pointType == BPoint::PointType::P || m_showAllHandles)) {
- // a point was found and it is not a hidden handle
- BPoint point = m_curve.getPoint(nearestIndex);
- double dx = (p.x() - point[(int)pointType].x()) * wWidth;
- double dy = (p.y() - point[(int)pointType].y()) * wHeight;
- if (dx * dx + dy * dy <= m_grabRadius * m_grabRadius) {
- *sel = pointType;
- return nearestIndex;
- }
- }
-
- return -1;
-}
-
-void BezierSplineEditor::setShowAllHandles(bool show)
-{
- if (m_showAllHandles != show) {
- m_showAllHandles = show;
- update();
- }
-}
-
-QList BezierSplineEditor::getPoints() const
-{
- return m_curve.getPoints();
-}
diff --git a/src/effectstack/widgets/curves/bezier/beziersplineeditor.h b/src/effectstack/widgets/curves/bezier/beziersplineeditor.h
deleted file mode 100644
index 84428d533..000000000
--- a/src/effectstack/widgets/curves/bezier/beziersplineeditor.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2010 by Till Theato (root@ttill.de) *
- * This file is part of Kdenlive (www.kdenlive.org). *
- * *
- * Kdenlive 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- * Kdenlive 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 Kdenlive. If not, see . *
- ***************************************************************************/
-
-#ifndef BEZIERSPLINEEDITOR_H
-#define BEZIERSPLINEEDITOR_H
-
-#include "bpoint.h"
-#include "colortools.h"
-#include "cubicbezierspline.h"
-#include "effectstack/widgets/curves/abstractcurvewidget.h"
-
-#include
-
-class BezierSplineEditor : public AbstractCurveWidget
-{
- Q_OBJECT
-
-public:
- typedef BPoint Point_t;
- explicit BezierSplineEditor(QWidget *parent = nullptr);
- ~BezierSplineEditor();
-
- /** @brief Sets the property showAllHandles to @param show.
- *
- * showAllHandles: Whether to show only handles for the selected point for all points.
- */
- void setShowAllHandles(bool show);
- QList getPoints() const override;
-
-public slots:
-
-protected:
- void paintEvent(QPaintEvent *event) override;
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- void mouseDoubleClickEvent(QMouseEvent *event) override;
-
-private:
- /** Whether to show handles for all points or only for the selected one. */
- bool m_showAllHandles;
-
- BPoint::PointType m_currentPointType;
- double m_grabOffsetX;
- double m_grabOffsetY;
- /** selected point before it was modified by dragging (at the time of the mouse press) */
- BPoint m_grabPOriginal;
- /** point with the index currentPointIndex + 1 at the time of the mouse press */
- BPoint m_grabPNext;
- /** point with the index currentPointIndex - 1 at the time of the mouse press */
- BPoint m_grabPPrevious;
-
- /** @brief Finds the point nearest to @param p and returns it's index.
- * @param sel Is filled with the type of the closest point (h1, p, h2)
- *
- * If no point is near enough -1 is returned. */
- int nearestPointInRange(const QPointF &p, int wWidth, int wHeight, BPoint::PointType *sel);
-};
-
-#endif
diff --git a/src/effectstack/widgets/curves/bezier/bpoint.cpp b/src/effectstack/widgets/curves/bezier/bpoint.cpp
deleted file mode 100644
index 9baddd164..000000000
--- a/src/effectstack/widgets/curves/bezier/bpoint.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2011 by Till Theato (root@ttill.de) *
- * This file is part of Kdenlive (www.kdenlive.org). *
- * *
- * Kdenlive 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- * Kdenlive 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 Kdenlive. If not, see . *
- ***************************************************************************/
-
-#include "bpoint.h"
-
-#include
-
-BPoint::BPoint()
- : h1(-1, -1)
- , p(-1, -1)
- , h2(-1, -1)
- , handlesLinked(true)
-{
-}
-
-BPoint::BPoint(const QPointF &handle1, const QPointF &point, const QPointF &handle2)
- : h1(handle1)
- , p(point)
- , h2(handle2)
-{
- autoSetLinked();
-}
-
-QPointF &BPoint::operator[](int i)
-{
- return i == 0 ? h1 : (i == 1 ? p : h2);
-}
-
-const QPointF &BPoint::operator[](int i) const
-{
- return i == 0 ? h1 : (i == 1 ? p : h2);
-}
-
-bool BPoint::operator==(const BPoint &point) const
-{
- return point.h1 == h1 && point.p == p && point.h2 == h2;
-}
-
-void BPoint::setP(const QPointF &point, bool updateHandles)
-{
- QPointF offset = point - p;
- p = point;
- if (updateHandles) {
- h1 += offset;
- h2 += offset;
- }
-}
-
-void BPoint::setH1(const QPointF &handle1)
-{
- h1 = handle1;
- if (handlesLinked) {
- qreal angle = QLineF(h1, p).angle();
- QLineF l = QLineF(p, h2);
- l.setAngle(angle);
- h2 = l.p2();
- }
-}
-
-void BPoint::setH2(const QPointF &handle2)
-{
- h2 = handle2;
- if (handlesLinked) {
- qreal angle = QLineF(h2, p).angle();
- QLineF l = QLineF(p, h1);
- l.setAngle(angle);
- h1 = l.p2();
- }
-}
-
-void BPoint::autoSetLinked()
-{
- // sometimes the angle is returned as 360°
- // due to rounding problems the angle is sometimes not quite 0
- qreal angle = QLineF(h1, p).angleTo(QLineF(p, h2));
- handlesLinked = angle < 1e-3 || qRound(angle) == 360;
-}
-
-void BPoint::setHandlesLinked(bool linked)
-{
- handlesLinked = linked;
- if (linked) {
- // we force recomputing one of the handles
- setH1(h1);
- }
-}
diff --git a/src/effectstack/widgets/curves/bezier/bpoint.h b/src/effectstack/widgets/curves/bezier/bpoint.h
deleted file mode 100644
index eefaf2f5a..000000000
--- a/src/effectstack/widgets/curves/bezier/bpoint.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2011 by Till Theato (root@ttill.de) *
- * This file is part of Kdenlive (www.kdenlive.org). *
- * *
- * Kdenlive 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- * Kdenlive 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 Kdenlive. If not, see . *
- ***************************************************************************/
-
-#ifndef BPOINT_H
-#define BPOINT_H
-
-#include
-
-/**
- * @brief Represents a point in a cubic Bézier spline.
- */
-
-class BPoint
-{
-public:
- enum class PointType { H1 = 0, P = 1, H2 = 2 };
- /** @brief Sets the point to -1, -1 to mark it as unusable (until point + handles have proper values) */
- BPoint();
- /** @brief Sets up according to the params. Linking detecting is done using autoSetLinked(). */
- BPoint(const QPointF &handle1, const QPointF &point, const QPointF &handle2);
-
- bool operator==(const BPoint &point) const;
- /** @brief Returns h1 if i = 0, p if i = 1, h2 if i = 2. */
- QPointF &operator[](int i);
- /** @brief Returns h1 if i = 0, p if i = 1, h2 if i = 2. */
- const QPointF &operator[](int i) const;
-
- /** @brief Sets p to @param point.
- * @param updateHandles (default = true) Whether to make sure the handles keep their position relative to p. */
- void setP(const QPointF &point, bool updateHandles = true);
-
- /** @brief Sets h1 to @param handle1.
- *
- * If handlesLinked is true h2 is updated. */
- void setH1(const QPointF &handle1);
-
- /** @brief Sets h2 to @param handle2.
- * If handlesLinked is true h1 is updated. */
- void setH2(const QPointF &handle2);
-
- /** @brief Sets handlesLinked to true if the handles are in a linked state (line through h1, p, h2) otherwise to false. */
- void autoSetLinked();
-
- /** @brief Toggles the link of the handles to @param linked*/
- void setHandlesLinked(bool linked);
-
- /** handle 1 */
- QPointF h1;
- /** point */
- QPointF p;
- /** handle 2 */
- QPointF h2;
- /** handles are linked to achieve a natural locking spline => PH1 = -r*PH2 ; a line can be drawn through h1, p, h2 */
- bool handlesLinked;
-};
-
-#endif
diff --git a/src/effectstack/widgets/curves/bezier/cubicbezierspline.cpp b/src/effectstack/widgets/curves/bezier/cubicbezierspline.cpp
deleted file mode 100644
index 6230c5f7d..000000000
--- a/src/effectstack/widgets/curves/bezier/cubicbezierspline.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2010 by Till Theato (root@ttill.de) *
- * This file is part of Kdenlive (www.kdenlive.org). *
- * *
- * Kdenlive 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- * Kdenlive 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 Kdenlive. If not, see . *
- ***************************************************************************/
-
-#include "cubicbezierspline.h"
-#include
-#include
-#include
-#include
-
-/** @brief For sorting a Bezier spline. Whether a is before b. */
-static bool pointLessThan(const BPoint &a, const BPoint &b)
-{
- return a.p.x() < b.p.x();
-}
-
-CubicBezierSpline::CubicBezierSpline()
-{
- m_points.append(BPoint(QPointF(0, 0), QPointF(0, 0), QPointF(.1, .1)));
- m_points.append(BPoint(QPointF(.9, .9), QPointF(1, 1), QPointF(1, 1)));
-}
-
-CubicBezierSpline::CubicBezierSpline(const CubicBezierSpline &spline)
-{
- m_points = spline.m_points;
-}
-
-CubicBezierSpline &CubicBezierSpline::operator=(const CubicBezierSpline &spline) = default;
-
-void CubicBezierSpline::fromString(const QString &spline)
-{
- m_points.clear();
- QLocale locale;
- const QStringList bpoints = spline.split(QLatin1Char('|'));
- for (const QString &bpoint : bpoints) {
- const QStringList points = bpoint.split(QLatin1Char('#'));
- QVector values;
- for (const QString &point : points) {
- const QStringList xy = point.split(QLatin1Char(';'));
- if (xy.count() == 2) {
- values.append(QPointF(locale.toDouble(xy.at(0)), locale.toDouble(xy.at(1))));
- }
- }
- if (values.count() == 3) {
- m_points.append(BPoint(values.at(0), values.at(1), values.at(2)));
- }
- }
-
- keepSorted();
- validatePoints();
-}
-
-QString CubicBezierSpline::toString() const
-{
- QStringList spline;
- QLocale locale;
- locale.setNumberOptions(QLocale::OmitGroupSeparator);
- for (const BPoint &p : m_points) {
- spline << QStringLiteral("%1;%2#%3;%4#%5;%6")
- .arg(locale.toString(p.h1.x()), locale.toString(p.h1.y()), locale.toString(p.p.x()), locale.toString(p.p.y()), locale.toString(p.h2.x()),
- locale.toString(p.h2.y()));
- }
- return spline.join(QLatin1Char('|'));
-}
-
-int CubicBezierSpline::setPoint(int ix, const BPoint &point)
-{
- m_points[ix] = point;
- keepSorted();
- validatePoints();
- return indexOf(point); // in case it changed
-}
-
-QList CubicBezierSpline::points() const
-{
- return m_points;
-}
-
-void CubicBezierSpline::removePoint(int ix)
-{
- m_points.removeAt(ix);
-}
-
-int CubicBezierSpline::addPoint(const BPoint &point)
-{
- m_points.append(point);
- keepSorted();
- validatePoints();
- return indexOf(point);
-}
-
-int CubicBezierSpline::addPoint(const QPointF &point)
-{
- // Check if point is in range
- if (point.x() < m_points[0].p.x() || point.x() > m_points.back().p.x()) {
- return -1;
- }
- // first we find by dichotomy the previous and next points on the curve
- int prev = 0, next = m_points.size() - 1;
- while (prev < next - 1) {
- int mid = (prev + next) / 2;
- if (point.x() < m_points[mid].p.x()) {
- next = mid;
- } else {
- prev = mid;
- }
- }
-
- // compute vector between adjacent points
- QPointF vec = m_points[next].p - m_points[prev].p;
- // normalize
- vec /= 10. * sqrt(vec.x() * vec.x() + vec.y() * vec.y());
- // add resulting point
- return addPoint(BPoint(point - vec, point, point + vec));
-}
-
-BPoint CubicBezierSpline::getPoint(int ix, int normalisedWidth, int normalisedHeight, bool invertHeight)
-{
- BPoint p = m_points.at(ix);
- for (int i = 0; i < 3; ++i) {
- p[i].rx() *= normalisedWidth;
- p[i].ry() *= normalisedHeight;
- if (invertHeight) {
- p[i].ry() = normalisedHeight - p[i].y();
- }
- }
- return p;
-}
-
-void CubicBezierSpline::validatePoints()
-{
- BPoint p1, p2;
- for (int i = 0; i < m_points.count() - 1; ++i) {
- p1 = m_points.at(i);
- p2 = m_points.at(i + 1);
- p1.h2.setX(qBound(p1.p.x(), p1.h2.x(), p2.p.x()));
- p2.h1.setX(qBound(p1.p.x(), p2.h1.x(), p2.p.x()));
- m_points[i] = p1;
- m_points[i + 1] = p2;
- }
-}
-
-void CubicBezierSpline::keepSorted()
-{
- qSort(m_points.begin(), m_points.end(), pointLessThan);
-}
-
-int CubicBezierSpline::indexOf(const BPoint &p)
-{
- if (m_points.indexOf(p) == -1) {
- // point changed during validation process
- for (int i = 0; i < m_points.count(); ++i) {
- // this condition should be sufficient, too
- if (m_points.at(i).p == p.p) {
- return i;
- }
- }
- } else {
- return m_points.indexOf(p);
- }
- return -1;
-}
-
-int CubicBezierSpline::count() const
-{
- return m_points.size();
-}
-
-QList CubicBezierSpline::getPoints() const
-{
- return m_points;
-}
-
-std::pair CubicBezierSpline::closestPoint(const QPointF &p) const
-{
- double nearestDistanceSquared = 1e100;
- BPoint::PointType selectedPoint = BPoint::PointType::P;
- int nearestIndex = -1;
- int i = 0;
-
- // find out distance using the Pythagorean theorem
- for (const auto &point : m_points) {
- for (int j = 0; j < 3; ++j) {
- double dx = point[j].x() - p.x();
- double dy = point[j].y() - p.y();
- double distanceSquared = dx * dx + dy * dy;
- if (distanceSquared < nearestDistanceSquared) {
- nearestIndex = i;
- nearestDistanceSquared = distanceSquared;
- selectedPoint = (BPoint::PointType)j;
- }
- }
- ++i;
- }
- return {nearestIndex, selectedPoint};
-}
diff --git a/src/effectstack/widgets/curves/bezier/cubicbezierspline.h b/src/effectstack/widgets/curves/bezier/cubicbezierspline.h
deleted file mode 100644
index adce1a1f9..000000000
--- a/src/effectstack/widgets/curves/bezier/cubicbezierspline.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2010 by Till Theato (root@ttill.de) *
- * This file is part of Kdenlive (www.kdenlive.org). *
- * *
- * Kdenlive 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 2 of the License, or *
- * (at your option) any later version. *
- * *
- * Kdenlive 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 Kdenlive. If not, see . *
- ***************************************************************************/
-
-#ifndef CUBICBEZIERSPLINE_H
-#define CUBICBEZIERSPLINE_H
-
-#include "bpoint.h"
-
-#include
-#include
-#include
-
-class CubicBezierSpline
-{
-
-public:
- typedef BPoint Point_t;
- explicit CubicBezierSpline();
- CubicBezierSpline(const CubicBezierSpline &spline);
- CubicBezierSpline &operator=(const CubicBezierSpline &spline);
-
- /** @brief Loads the points from the string @param spline.
- *
- * x, y values have to be separated with a ';'
- * handles and points with a '#'
- * and the nodes with a '|'
- * So that you get: h1x;h1y#px;py#h2x;h2y|h1x;h1y#... */
- void fromString(const QString &spline);
- /** @brief Returns the points stored in a string.
- *
- * x, y values have are separated with a ';'
- * handles and points with a '#'
- * and the nodes with a '|'
- * So that you get: h1x;h1y#px;py#h2x;h2y|h1x;h1y#... */
- QString toString() const;
-
- /** @brief Returns a list of the points defining the spline. */
- QList points() const;
-
- /** @brief Returns the number of points in the spline.*/
- int count() const;
-
- /** @brief Sets the point at index @param ix to @param point and returns its index (it might have changed during validation). */
- int setPoint(int ix, const BPoint &point);
- /** @brief Adds @param point and returns its index. */
- int addPoint(const BPoint &point);
- /** @brief Add a point based on a position @param point only
- This will try to compute relevant handles based on neihbouring points
- Return the index of the added point.
- */
- int addPoint(const QPointF &point);
- /** @brief Removes the point at @param ix. */
- void removePoint(int ix);
-
- /** @brief Returns the point at @param ix.
- * @param ix Index of the point
- * @param normalisedWidth (default = 1) Will be multiplied will all x values to change the range from 0-1 into another one
- * @param normalisedHeight (default = 1) Will be multiplied will all y values to change the range from 0-1 into another one
- * @param invertHeight (default = false) true => y = 0 is at the very top
- */
- BPoint getPoint(int ix, int normalisedWidth = 1, int normalisedHeight = 1, bool invertHeight = false);
-
- /** @brief Returns the closest point to @param p, represented by its index and type (center or handle)
- */
- std::pair closestPoint(const QPointF &p) const;
-
- QList getPoints() const;
-
-private:
- void validatePoints();
- void keepSorted();
- int indexOf(const BPoint &p);
-
- QList m_points;
-};
-
-#endif
diff --git a/src/effectstack/widgets/curves/cubic/kis_cubic_curve.cpp b/src/effectstack/widgets/curves/cubic/kis_cubic_curve.cpp
deleted file mode 100644
index baa551c18..000000000
--- a/src/effectstack/widgets/curves/cubic/kis_cubic_curve.cpp
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (c) 2005 Casper Boemann
- * Copyright (c) 2009 Dmitry Kazakov
- * Copyright (c) 2010 Cyrille Berger
- *
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "kis_cubic_curve.h"
-
-#include
-#include
-#include
-#include
-#include
-
-template class KisTridiagonalSystem
-{
- /*
- * e.g.
- * |b0 c0 0 0 0| |x0| |f0|
- * |a0 b1 c1 0 0| |x1| |f1|
- * |0 a1 b2 c2 0|*|x2|=|f2|
- * |0 0 a2 b3 c3| |x3| |f3|
- * |0 0 0 a3 b4| |x4| |f4|
- */
-
-public:
- /**
- * @return - vector that is storing x[]
- */
- static QVector calculate(QList &a, QList &b, QList &c, QList &f)
- {
- QVector x;
- QVector alpha;
- QVector beta;
-
- int i;
- int size = b.size();
-
- Q_ASSERT(a.size() == size - 1 && c.size() == size - 1 && f.size() == size);
-
- x.resize(size);
-
- /**
- * Check for special case when
- * order of the matrix is equal to 1
- */
- if (size == 1) {
- x[0] = f[0] / b[0];
- return x;
- }
-
- /**
- * Common case
- */
-
- alpha.resize(size);
- beta.resize(size);
-
- alpha[1] = -c[0] / b[0];
- beta[1] = f[0] / b[0];
-
- for (i = 1; i < size - 1; ++i) {
- alpha[i + 1] = -c[i] / (a[i - 1] * alpha[i] + b[i]);
-
- beta[i + 1] = (f[i] - a[i - 1] * beta[i]) / (a[i - 1] * alpha[i] + b[i]);
- }
-
- x.last() = (f.last() - a.last() * beta.last()) / (b.last() + a.last() * alpha.last());
-
- for (i = size - 2; i >= 0; --i) {
- x[i] = alpha[i + 1] * x[i + 1] + beta[i + 1];
- }
-
- return x;
- }
-};
-
-template class KisCubicSpline
-{
- /**
- * s[i](x)=a[i] +
- * b[i] * (x-x[i]) +
- * 1/2 * c[i] * (x-x[i])^2 +
- * 1/6 * d[i] * (x-x[i])^3
- *
- * h[i]=x[i+1]-x[i]
- *
- */
-
-protected:
- QList m_a;
- QVector m_b;
- QVector m_c;
- QVector m_d;
-
- QVector m_h;
- T m_begin;
- T m_end;
- int m_intervals;
-
-public:
- KisCubicSpline()
- : m_begin(0)
- , m_end(0)
- , m_intervals(0)
- {
- }
- explicit KisCubicSpline(const QList &a)
- : m_begin(0)
- , m_end(0)
- , m_intervals(0)
- {
- createSpline(a);
- }
-
- /**
- * Create new spline and precalculate some values
- * for future
- *
- * @a - base points of the spline
- */
- void createSpline(const QList &a)
- {
- int intervals = m_intervals = a.size() - 1;
- int i;
- m_begin = a.constFirst().x();
- m_end = a.last().x();
-
- m_a.clear();
- m_b.resize(intervals);
- m_c.clear();
- m_d.resize(intervals);
- m_h.resize(intervals);
-
- for (i = 0; i < intervals; ++i) {
- m_h[i] = a[i + 1].x() - a[i].x();
- m_a.append(a[i].y());
- }
- m_a.append(a.last().y());
-
- QList tri_b;
- QList tri_f;
- QList tri_a; /* equals to @tri_c */
-
- for (i = 0; i < intervals - 1; ++i) {
- tri_b.append(2. * (m_h[i] + m_h[i + 1]));
-
- tri_f.append(6. * ((m_a[i + 2] - m_a[i + 1]) / m_h[i + 1] - (m_a[i + 1] - m_a[i]) / m_h[i]));
- }
- for (i = 1; i < intervals - 1; ++i) {
- tri_a.append(m_h[i]);
- }
-
- if (intervals > 1) {
- KisTridiagonalSystem tridia;
- m_c = tridia.calculate(tri_a, tri_b, tri_a, tri_f);
- }
- m_c.prepend(0);
- m_c.append(0);
-
- for (i = 0; i < intervals; ++i) {
- m_d[i] = (m_c[i + 1] - m_c[i]) / m_h[i];
- }
-
- for (i = 0; i < intervals; ++i) {
- m_b[i] = -0.5 * (m_c[i] * m_h[i]) - (1 / 6.0) * (m_d[i] * m_h[i] * m_h[i]) + (m_a[i + 1] - m_a[i]) / m_h[i];
- }
- }
-
- /**
- * Get value of precalculated spline in the point @x
- */
- T getValue(T x) const
- {
- T x0;
- int i = findRegion(x, x0);
- /* TODO: check for asm equivalent */
- return m_a[i] + m_b[i] * (x - x0) + 0.5 * m_c[i] * (x - x0) * (x - x0) + (1 / 6.0) * m_d[i] * (x - x0) * (x - x0) * (x - x0);
- }
-
- T begin() const { return m_begin; }
-
- T end() const { return m_end; }
-
-protected:
- /**
- * findRegion - Searches for the region containing @x
- * @x0 - out parameter, containing beginning of the region
- * @return - index of the region
- */
- int findRegion(T x, T &x0) const
- {
- int i;
- x0 = m_begin;
- for (i = 0; i < m_intervals; ++i) {
- if (x >= x0 && x < x0 + m_h[i]) {
- return i;
- }
- x0 += m_h[i];
- }
- if (x >= x0) {
- x0 -= m_h[m_intervals - 1];
- return m_intervals - 1;
- }
-
- qDebug("X value: %f\n", x);
- qDebug("m_begin: %f\n", m_begin);
- qDebug("m_end : %f\n", m_end);
- Q_ASSERT_X(0, "findRegion", "X value is outside regions");
- /* **never reached** */
- return -1;
- }
-};
-
-static bool pointLessThan(const QPointF &a, const QPointF &b)
-{
- return a.x() < b.x();
-}
-
-struct KisCubicCurve::Data : public QSharedData
-{
- Data() { init(); }
- Data(const Data &data)
- : QSharedData()
- {
- init();
- points = data.points;
- }
- void init()
- {
- validSpline = false;
- validU16Transfer = false;
- validFTransfer = false;
- }
- ~Data() = default;
- mutable KisCubicSpline spline;
- QList points;
- mutable bool validSpline;
- mutable QVector u16Transfer;
- mutable bool validU16Transfer;
- mutable QVector fTransfer;
- mutable bool validFTransfer;
- void updateSpline();
- void keepSorted();
- qreal value(qreal x);
- void invalidate();
- template void updateTransfer(QVector<_T_> *transfer, bool &valid, _T2_ min, _T2_ max, int size);
-};
-
-void KisCubicCurve::Data::updateSpline()
-{
- if (validSpline) {
- return;
- }
- validSpline = true;
- spline.createSpline(points);
-}
-
-void KisCubicCurve::Data::invalidate()
-{
- validSpline = false;
- validFTransfer = false;
- validU16Transfer = false;
-}
-
-void KisCubicCurve::Data::keepSorted()
-{
- qSort(points.begin(), points.end(), pointLessThan);
-}
-
-qreal KisCubicCurve::Data::value(qreal x)
-{
- updateSpline();
- /* Automatically extend non-existing parts of the curve
- * (e.g. before the first point) and cut off big y-values
- */
- x = qBound(spline.begin(), x, spline.end());
- qreal y = spline.getValue(x);
- return qBound((qreal)0.0, y, (qreal)1.0);
-}
-
-template void KisCubicCurve::Data::updateTransfer(QVector<_T_> *transfer, bool &valid, _T2_ min, _T2_ max, int size)
-{
- if (!valid || transfer->size() != size) {
- if (transfer->size() != size) {
- transfer->resize(size);
- }
- qreal end = 1.0 / (size - 1);
- for (int i = 0; i < size; ++i) {
- /* Direct uncached version */
- _T2_ val = value(i * end) * max;
- val = qBound(min, val, max);
- (*transfer)[i] = val;
- }
- valid = true;
- }
-}
-
-struct KisCubicCurve::Private
-{
- QSharedDataPointer data;
-};
-
-KisCubicCurve::KisCubicCurve()
- : d(new Private)
-{
- d->data = new Data;
- QPointF p;
- p.rx() = 0.0;
- p.ry() = 0.0;
- d->data->points.append(p);
- p.rx() = 1.0;
- p.ry() = 1.0;
- d->data->points.append(p);
-}
-
-KisCubicCurve::KisCubicCurve(const QList &points)
- : d(new Private)
-{
- d->data = new Data;
- d->data->points = points;
- d->data->keepSorted();
-}
-
-KisCubicCurve::KisCubicCurve(const KisCubicCurve &curve)
- : d(new Private(*curve.d))
-{
-}
-
-KisCubicCurve::~KisCubicCurve()
-{
- delete d;
-}
-
-KisCubicCurve &KisCubicCurve::operator=(const KisCubicCurve &curve)
-{
- *d = *curve.d;
- return *this;
-}
-
-bool KisCubicCurve::operator==(const KisCubicCurve &curve) const
-{
- if (d->data == curve.d->data) {
- return true;
- }
- return d->data->points == curve.d->data->points;
-}
-
-qreal KisCubicCurve::value(qreal x) const
-{
- return d->data->value(x);
-}
-
-QList KisCubicCurve::points() const
-{
- return d->data->points;
-}
-
-void KisCubicCurve::setPoints(const QList &points)
-{
- d->data.detach();
- d->data->points = points;
- d->data->invalidate();
-}
-
-int KisCubicCurve::setPoint(int idx, const QPointF &point)
-{
- d->data.detach();
- d->data->points[idx] = point;
- d->data->keepSorted();
- d->data->invalidate();
- return idx;
-}
-
-int KisCubicCurve::addPoint(const QPointF &point)
-{
- d->data.detach();
- d->data->points.append(point);
- d->data->keepSorted();
- d->data->invalidate();
- return d->data->points.indexOf(point);
-}
-
-void KisCubicCurve::removePoint(int idx)
-{
- d->data.detach();
- d->data->points.removeAt(idx);
- d->data->invalidate();
-}
-
-QString KisCubicCurve::toString() const
-{
- QString sCurve;
- QLocale locale;
- locale.setNumberOptions(QLocale::OmitGroupSeparator);
- for (const QPointF &pair : d->data->points) {
- sCurve += locale.toString(pair.x());
- sCurve += '/';
- sCurve += locale.toString(pair.y());
- sCurve += ';';
- }
- return sCurve;
-}
-
-void KisCubicCurve::fromString(const QString &string)
-{
- const QStringList data = string.split(QLatin1Char(';'));
-
- QList points;
- QLocale locale;
- for (const QString &pair : data) {
- if (pair.indexOf('/') > -1) {
- QPointF p;
- p.rx() = locale.toDouble(pair.section(QLatin1Char('/'), 0, 0));
- p.ry() = locale.toDouble(pair.section(QLatin1Char('/'), 1, 1));
- points.append(p);
- }
- }
- setPoints(points);
-}
-
-int KisCubicCurve::count() const
-{
- return d->data->points.size();
-}
-
-QPointF KisCubicCurve::getPoint(int ix, int normalisedWidth, int normalisedHeight, bool invertHeight)
-{
- QPointF p = d->data->points.at(ix);
- p.rx() *= normalisedWidth;
- p.ry() *= normalisedHeight;
- if (invertHeight) {
- p.ry() = normalisedHeight - p.y();
- }
- return p;
-}
diff --git a/src/effectstack/widgets/curves/cubic/kis_cubic_curve.h b/src/effectstack/widgets/curves/cubic/kis_cubic_curve.h
deleted file mode 100644
index 0308780a6..000000000
--- a/src/effectstack/widgets/curves/cubic/kis_cubic_curve.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2010 Cyrille Berger
- *
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef KIS_CUBIC_CURVE_H
-#define KIS_CUBIC_CURVE_H
-
-#include
-#include
-
-class QPointF;
-
-/**
- * Hold the data for a cubic curve.
- */
-class KisCubicCurve
-{
-public:
- typedef QPointF Point_t;
- KisCubicCurve();
- explicit KisCubicCurve(const QList &points);
- explicit KisCubicCurve(const QVector &points);
- KisCubicCurve(const KisCubicCurve &curve);
- ~KisCubicCurve();
- KisCubicCurve &operator=(const KisCubicCurve &curve);
- bool operator==(const KisCubicCurve &curve) const;
-
-public:
- qreal value(qreal x) const;
- QList points() const;
- void setPoints(const QList &points);
- int setPoint(int idx, const QPointF &point);
- /**
- * Add a point to the curve, the list of point is always sorted.
- * @return the index of the inserted point
- */
- int addPoint(const QPointF &point);
- void removePoint(int idx);
- /** @brief Returns the number of points on the curve
- */
- int count() const;
- /** @brief Returns the point at @param ix.
- * @param ix Index of the point
- * @param normalisedWidth (default = 1) Will be multiplied will all x values to change the range from 0-1 into another one
- * @param normalisedHeight (default = 1) Will be multiplied will all y values to change the range from 0-1 into another one
- * @param invertHeight (default = false) true => y = 0 is at the very top
- */
- QPointF getPoint(int ix, int normalisedWidth = 1, int normalisedHeight = 1, bool invertHeight = false);
-
-public:
- QVector uint16Transfer(int size = 256) const;
- QVector floatTransfer(int size = 256) const;
-
-public:
- QString toString() const;
- void fromString(const QString &);
-
-private:
- struct Data;
- struct Private;
- Private *const d;
-};
-
-#endif
diff --git a/src/effectstack/widgets/curves/cubic/kis_curve_widget.cpp b/src/effectstack/widgets/curves/cubic/kis_curve_widget.cpp
deleted file mode 100644
index 348c664c0..000000000
--- a/src/effectstack/widgets/curves/cubic/kis_curve_widget.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (c) 2005 C. Boemann
- * Copyright (c) 2009 Dmitry Kazakov
- *
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-// Local includes.
-
-#include "kis_curve_widget.h"
-#include "kdenlivesettings.h"
-// C++ includes.
-
-#include
-#include
-
-// Qt includes.
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#define bounds(x, a, b) (x < a ? a : (x > b ? b : x))
-#define MOUSE_AWAY_THRES 15
-#define POINT_AREA 1E-4
-#define CURVE_AREA 1E-4
-
-// static bool pointLessThan(const QPointF &a, const QPointF &b);
-
-KisCurveWidget::KisCurveWidget(QWidget *parent)
- : AbstractCurveWidget(parent)
-{
- setObjectName(QStringLiteral("KisCurveWidget"));
- m_guideVisible = false;
-
- m_maxPoints = -1;
-
- m_grabOffsetX = 0;
- m_grabOffsetY = 0;
- m_grabOriginalX = 0;
- m_grabOriginalY = 0;
- m_draggedAwayPointIndex = 0;
- m_pixmapIsDirty = 0;
- m_pixmapCache = nullptr;
- m_maxPoints = 0;
- m_curve = KisCubicCurve();
- update();
- emit modified();
-}
-
-KisCurveWidget::~KisCurveWidget() {}
-
-QSize KisCurveWidget::sizeHint() const
-{
- return QSize(500, 500);
-}
-
-void KisCurveWidget::addPointInTheMiddle()
-{
- QPointF pt(0.5, m_curve.value(0.5));
-
- if (!jumpOverExistingPoints(pt, -1)) {
- return;
- }
-
- m_currentPointIndex = m_curve.addPoint(pt);
-
- update();
- emit modified();
-}
-
-void KisCurveWidget::paintEvent(QPaintEvent *)
-{
- QPainter p(this);
- paintBackground(&p);
-
- // Draw curve.
- int x;
- QPolygonF poly;
-
- p.setPen(QPen(palette().text().color(), 1, Qt::SolidLine));
- poly.reserve(m_wWidth);
- for (x = 0; x < m_wWidth; ++x) {
- double normalizedX = double(x) / m_wWidth;
- double curY = m_wHeight - m_curve.value(normalizedX) * m_wHeight;
- poly.append(QPointF(x, curY));
- }
- poly.append(QPointF(x, m_wHeight - m_curve.value(1.0) * m_wHeight));
- p.drawPolyline(poly);
-
- // Drawing curve handles.
- for (int i = 0; i < m_curve.points().count(); ++i) {
- double curveX = m_curve.points().at(i).x();
- double curveY = m_curve.points().at(i).y();
-
- if (i == m_currentPointIndex) {
- p.setPen(QPen(Qt::red, 3, Qt::SolidLine));
- p.drawEllipse(QRectF(curveX * m_wWidth - 2, m_wHeight - 2 - curveY * m_wHeight, 4, 4));
- } else {
- p.setPen(QPen(Qt::red, 1, Qt::SolidLine));
- p.drawEllipse(QRectF(curveX * m_wWidth - 3, m_wHeight - 3 - curveY * m_wHeight, 6, 6));
- }
- }
-}
-
-void KisCurveWidget::mousePressEvent(QMouseEvent *e)
-{
- int wWidth = width() - 1;
- int wHeight = height() - 1;
- int offsetX = 1 / 8. * m_zoomLevel * wWidth;
- int offsetY = 1 / 8. * m_zoomLevel * wHeight;
- wWidth -= 2 * offsetX;
- wHeight -= 2 * offsetY;
- double x = (e->pos().x() - offsetX) / (double)(wWidth);
- double y = 1.0 - (e->pos().y() - offsetY) / (double)(wHeight);
-
- int closest_point_index = nearestPointInRange(QPointF(x, y), width(), height());
-
- if (e->button() == Qt::RightButton && closest_point_index > 0 && closest_point_index < m_curve.points().count() - 1) {
- m_currentPointIndex = closest_point_index;
- slotDeleteCurrentPoint();
- } else if (e->button() != Qt::LeftButton) {
- return;
- }
-
- if (closest_point_index < 0) {
- if (m_maxPoints > 0 && m_curve.points().count() >= m_maxPoints) {
- return;
- }
- QPointF newPoint(x, y);
- if (!jumpOverExistingPoints(newPoint, -1)) {
- return;
- }
- m_currentPointIndex = m_curve.addPoint(newPoint);
- } else {
- m_currentPointIndex = closest_point_index;
- }
-
- m_grabOriginalX = m_curve.points().at(m_currentPointIndex).x();
- m_grabOriginalY = m_curve.points().at(m_currentPointIndex).y();
- m_grabOffsetX = m_curve.points().at(m_currentPointIndex).x() - x;
- m_grabOffsetY = m_curve.points().at(m_currentPointIndex).y() - y;
- QPointF point(x + m_grabOffsetX, y + m_grabOffsetY);
- m_curve.setPoint(m_currentPointIndex, point);
-
- m_draggedAwayPointIndex = -1;
- m_state = State_t::DRAG;
-
- update();
- emit modified();
- emit currentPoint(point, isCurrentPointExtremal());
-}
-
-void KisCurveWidget::mouseMoveEvent(QMouseEvent *e)
-{
- int wWidth = width() - 1;
- int wHeight = height() - 1;
- int offsetX = 1 / 8. * m_zoomLevel * wWidth;
- int offsetY = 1 / 8. * m_zoomLevel * wHeight;
- wWidth -= 2 * offsetX;
- wHeight -= 2 * offsetY;
- double x = (e->pos().x() - offsetX) / (double)(wWidth);
- double y = 1.0 - (e->pos().y() - offsetY) / (double)(wHeight);
-
- if (m_state == State_t::NORMAL) { // If no point is selected set the cursor shape if on top
- int nearestPointIndex = nearestPointInRange(QPointF(x, y), width(), height());
-
- if (nearestPointIndex < 0) {
- setCursor(Qt::ArrowCursor);
- } else {
- setCursor(Qt::CrossCursor);
- }
- } else { // Else, drag the selected point
- bool crossedHoriz = e->pos().x() - width() > MOUSE_AWAY_THRES || e->pos().x() < -MOUSE_AWAY_THRES;
- bool crossedVert = e->pos().y() - height() > MOUSE_AWAY_THRES || e->pos().y() < -MOUSE_AWAY_THRES;
-
- bool removePoint = (crossedHoriz || crossedVert);
-
- if (!removePoint && m_draggedAwayPointIndex >= 0) {
- // point is no longer dragged away so reinsert it
- QPointF newPoint(m_draggedAwayPoint);
- m_currentPointIndex = m_curve.addPoint(newPoint);
- m_draggedAwayPointIndex = -1;
- }
-
- if (removePoint && (m_draggedAwayPointIndex >= 0)) {
- return;
- }
-
- setCursor(Qt::CrossCursor);
-
- x += m_grabOffsetX;
- y += m_grabOffsetY;
-
- double leftX;
- double rightX;
- if (m_currentPointIndex == 0) {
- leftX = 0.0;
- rightX = 0.0;
- /*if (m_curve.points().count() > 1)
- rightX = m_curve.points().at(m_currentPointIndex + 1).x() - POINT_AREA;
- else
- rightX = 1.0;*/
- } else if (m_currentPointIndex == m_curve.points().count() - 1) {
- leftX = m_curve.points().at(m_currentPointIndex - 1).x() + POINT_AREA;
- rightX = 1.0;
- } else {
- Q_ASSERT(m_currentPointIndex > 0 && m_currentPointIndex < m_curve.points().count() - 1);
-
- // the 1E-4 addition so we can grab the dot later.
- leftX = m_curve.points().at(m_currentPointIndex - 1).x() + POINT_AREA;
- rightX = m_curve.points().at(m_currentPointIndex + 1).x() - POINT_AREA;
- }
-
- x = bounds(x, leftX, rightX);
- y = bounds(y, 0., 1.);
- QPointF point(x, y);
-
- m_curve.setPoint(m_currentPointIndex, point);
-
- if (removePoint && m_curve.points().count() > 2) {
- m_draggedAwayPoint = m_curve.points().at(m_currentPointIndex);
- m_draggedAwayPointIndex = m_currentPointIndex;
- m_curve.removePoint(m_currentPointIndex);
- m_currentPointIndex = bounds(m_currentPointIndex, 0, m_curve.points().count() - 1);
- }
-
- update();
- emit currentPoint(point, isCurrentPointExtremal());
- if (KdenliveSettings::dragvalue_directupdate()) {
- emit modified();
- }
- }
-}
-
-double KisCurveWidget::io2sp(int x) const
-{
- int rangeLen = m_inOutMax - m_inOutMin;
- return double(x - m_inOutMin) / rangeLen;
-}
-
-int KisCurveWidget::sp2io(double x) const
-{
- int rangeLen = m_inOutMax - m_inOutMin;
- return int(x * rangeLen + 0.5) + m_inOutMin;
-}
-
-bool KisCurveWidget::jumpOverExistingPoints(QPointF &pt, int skipIndex)
-{
- for (const QPointF &it : m_curve.points()) {
- if (m_curve.points().indexOf(it) == skipIndex) {
- continue;
- }
- if (fabs(it.x() - pt.x()) < POINT_AREA) pt.rx() = pt.x() >= it.x() ? it.x() + POINT_AREA : it.x() - POINT_AREA;
- }
- return (pt.x() >= 0 && pt.x() <= 1.);
-}
-
-int KisCurveWidget::nearestPointInRange(QPointF pt, int wWidth, int wHeight) const
-{
- double nearestDistanceSquared = 1000;
- int nearestIndex = -1;
- int i = 0;
-
- for (const QPointF &point : m_curve.points()) {
- double distanceSquared = (pt.x() - point.x()) * (pt.x() - point.x()) + (pt.y() - point.y()) * (pt.y() - point.y());
-
- if (distanceSquared < nearestDistanceSquared) {
- nearestIndex = i;
- nearestDistanceSquared = distanceSquared;
- }
- ++i;
- }
-
- if (nearestIndex >= 0) {
- double dx = (pt.x() - m_curve.points().at(nearestIndex).x()) * wWidth;
- double dy = (pt.y() - m_curve.points().at(nearestIndex).y()) * wHeight;
- if (dx * dx + dy * dy <= m_grabRadius * m_grabRadius) {
- return nearestIndex;
- }
- }
-
- return -1;
-}
-
-// void KisCurveWidget::syncIOControls()
-// {
-// if (!m_intIn || !m_intOut) {
-// return;
-// }
-
-// bool somethingSelected = (m_currentPointIndex >= 0);
-
-// m_intIn->setEnabled(somethingSelected);
-// m_intOut->setEnabled(somethingSelected);
-
-// if (m_currentPointIndex >= 0) {
-// m_intIn->blockSignals(true);
-// m_intOut->blockSignals(true);
-
-// m_intIn->setValue(sp2io(m_curve.points().at(m_currentPointIndex).x()));
-// m_intOut->setValue(sp2io(m_curve.points().at(m_currentPointIndex).y()));
-
-// m_intIn->blockSignals(false);
-// m_intOut->blockSignals(false);
-// } else {
-// /*FIXME: Ideally, these controls should hide away now */
-// }
-// }
-void KisCurveWidget::setCurve(KisCubicCurve &&curve)
-{
- m_curve = std::move(curve);
-}
-
-QList KisCurveWidget::getPoints() const
-{
- return m_curve.points();
-}
diff --git a/src/effectstack/widgets/curves/cubic/kis_curve_widget.h b/src/effectstack/widgets/curves/cubic/kis_curve_widget.h
deleted file mode 100644
index 99e7bfec3..000000000
--- a/src/effectstack/widgets/curves/cubic/kis_curve_widget.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2005 Casper Boemann
- * Copyright (c) 2009 Dmitry Kazakov
- *
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-#ifndef KIS_CURVE_WIDGET_H
-#define KIS_CURVE_WIDGET_H
-
-// Qt includes.
-
-#include
-
-#include "colortools.h"
-#include "effectstack/widgets/curves/abstractcurvewidget.h"
-#include "kis_cubic_curve.h"
-
-class QEvent;
-class QMouseEvent;
-class QObject;
-class QPaintEvent;
-class QPixmap;
-
-class QSpinBox;
-
-/**
- * KisCurveWidget is a widget that shows a single curve that can be edited
- * by the user. The user can grab the curve and move it; this creates
- * a new control point. Control points can be deleted by selecting a point
- * and pressing the delete key.
- *
- * (From: http://techbase.kde.org/Projects/Widgets_and_Classes#KisCurveWidget)
- * KisCurveWidget allows editing of spline based y=f(x) curves. Handy for cases
- * where you want the user to control such things as tablet pressure
- * response, color transformations, acceleration by time, aeroplane lift
- *by angle of attack.
- */
-class KisCurveWidget : public AbstractCurveWidget
-{
- Q_OBJECT
-
-public:
- typedef QPointF Point_t;
-
- /**
- * Create a new curve widget with a default curve, that is a straight
- * line from bottom-left to top-right.
- */
- explicit KisCurveWidget(QWidget *parent = nullptr);
-
- virtual ~KisCurveWidget();
-
- QSize sizeHint() const override;
-
-protected:
- void paintEvent(QPaintEvent *) override;
- void mousePressEvent(QMouseEvent *e) override;
- void mouseMoveEvent(QMouseEvent *e) override;
-
-public:
- /**
- * Handy function that creates new point in the middle
- * of the curve and sets focus on the m_intIn field,
- * so the user can move this point anywhere in a moment
- */
- void addPointInTheMiddle();
-
- void setCurve(KisCubicCurve &&curve);
-
- QList getPoints() const override;
-
-private:
- double io2sp(int x) const;
- int sp2io(double x) const;
- bool jumpOverExistingPoints(QPointF &pt, int skipIndex);
- int nearestPointInRange(QPointF pt, int wWidth, int wHeight) const;
-
- /* Dragging variables */
- double m_grabOffsetX;
- double m_grabOffsetY;
- double m_grabOriginalX;
- double m_grabOriginalY;
- QPointF m_draggedAwayPoint;
- int m_draggedAwayPointIndex;
-
- bool m_guideVisible;
- QColor m_colorGuide;
-
- /* Working range of them */
- int m_inOutMin;
- int m_inOutMax;
-};
-
-#endif /* KIS_CURVE_WIDGET_H */
diff --git a/src/effectstack/widgets/curves/curveparamwidget.h b/src/effectstack/widgets/curves/curveparamwidget.h
deleted file mode 100644
index dc96b8a4e..000000000
--- a/src/effectstack/widgets/curves/curveparamwidget.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by Nicolas Carion *
- * This file is part of Kdenlive. See www.kdenlive.org. *
- * *
- * 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 2 of the License, or *
- * (at your option) version 3 or any later version accepted by the *
- * membership of KDE e.V. (or its successor approved by the membership *
- * of KDE e.V.), which shall act as a proxy defined in Section 14 of *
- * version 3 of the license. *
- * *
- * 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 CURVEPARAMWIDGET_H
-#define CURVEPARAMWIDGET_H
-
-#include "../abstractparamwidget.h"
-#include "bezier/beziersplineeditor.h"
-#include "cubic/kis_curve_widget.h"
-#include "ui_bezierspline_ui.h"
-
-template class ValueLabel;
-
-/** @brief Class representing a curve and some additional controls
- */
-template class CurveParamWidget : public AbstractParamWidget
-{
-public:
- virtual ~CurveParamWidget(){};
- CurveParamWidget(const QString &spline, QWidget *parent);
-
- enum class CurveModes { Red = 0, Green = 1, Blue = 2, Luma = 3, Alpha = 4, RGB = 5, Hue = 6, Saturation = 7 };
- /** @brief sets the mode of the curve. This affects the background that is displayed.
- * The list of available modes depends on the CurveWidget that we have
- */
- void setMode(CurveModes mode);
-
- /** @brief Stringify the content of the curve
- */
- QString toString() const;
-
- using Point_t = typename CurveWidget_t::Point_t;
- /** @brief returns the list of points on the curve
- */
- QList getPoints() { return m_edit->getPoints(); }
-
- /** @brief Set the maximal number of points on the curve. This function is only available for KisCurveWidget.
- */
- void setMaxPoints(int max);
-
- /** @brief Helper function to convert a mode to the corresponding ColorsRGB value.
- This avoids using potentially non consistent intermediate cast to int
- */
- static ColorTools::ColorsRGB modeToColorsRGB(CurveModes mode);
-
-protected:
- void deleteIrrelevantItems();
- void setupLayoutPoint();
- void setupLayoutHandles();
- void slotGridChange();
- void slotShowPixmap(bool show);
- void slotUpdatePointEntries(const BPoint &p, bool extremal);
- void slotUpdatePointEntries(const QPointF &p, bool extremal);
- void slotUpdatePointP(double /*value*/, bool final);
- void slotUpdatePointH1(double /*value*/, bool final);
- void slotUpdatePointH2(double /*value*/, bool final);
- void slotSetHandlesLinked(bool linked);
- void slotShowAllHandles(bool show);
-
-public:
- /** @brief Toggle the comments on or off
- */
- void slotShowComment(bool) override;
-
-private:
- Ui::BezierSpline_UI m_ui;
- DragValue *m_pX;
- DragValue *m_pY;
- DragValue *m_h1X;
- DragValue *m_h1Y;
- DragValue *m_h2X;
- DragValue *m_h2Y;
- CurveWidget_t *m_edit;
- CurveModes m_mode;
- bool m_showPixmap;
-
- ValueLabel *m_leftParam, *m_bottomParam;
-};
-
-#include "curveparamwidget.ipp"
-
-#endif
diff --git a/src/effectstack/widgets/curves/curveparamwidget.ipp b/src/effectstack/widgets/curves/curveparamwidget.ipp
deleted file mode 100644
index 23a0d6451..000000000
--- a/src/effectstack/widgets/curves/curveparamwidget.ipp
+++ /dev/null
@@ -1,399 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2016 by Nicolas Carion *
- * This file is part of Kdenlive. See www.kdenlive.org. *
- * *
- * 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 2 of the License, or *
- * (at your option) version 3 or any later version accepted by the *
- * membership of KDE e.V. (or its successor approved by the membership *
- * of KDE e.V.), which shall act as a proxy defined in Section 14 of *
- * version 3 of the license. *
- * *
- * 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 "bezier/beziersplineeditor.h"
-#include "colortools.h"
-#include "cubic/kis_curve_widget.h"
-#include "effectstack/dragvalue.h"
-#include "utils/KoIconUtils.h"
-#include
-
-/*@brief this label is a pixmap corresponding to a legend of the axis*/
-template class ValueLabel : public QLabel
-{
-public:
- /**@brief Creates the widget
- @param isVert This parameter is true if the widget is vertical
- @param mode This is the original mode
- @param parent Parent of the widget
- */
- ValueLabel(bool isVert, typename CurveParamWidget