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::CurveModes mode, QWidget *parent) - : QLabel(parent) - , m_mode(mode) - , m_isVert(isVert) - { - if (m_isVert) { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - setMaximumSize(10, 500); - setFixedWidth(10); - } else { - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - setFixedHeight(10); - } - setScaledContents(true); - } - -public slots: - void setMode(typename CurveParamWidget::CurveModes m) - { - m_mode = m; - createPixmap(); - } - -private: - using CurveModes = typename CurveParamWidget::CurveModes; - void createPixmap() - { - QTransform t; - QSize s = size(); - if (!m_isVert) { - t.rotate(90); - s.setHeight(size().width()); - s.setWidth(size().height()); - } - if (m_mode == CurveModes::Hue) { - setPixmap(QPixmap::fromImage(ColorTools::hsvCurvePlane(s, QColor::fromHsv(200, 200, 200), ColorTools::COM_H, ColorTools::COM_H)).transformed(t)); - } else if (m_mode == CurveModes::Saturation) { - setPixmap(QPixmap()); - } else { - auto color = CurveParamWidget::modeToColorsRGB(m_mode); - setPixmap(QPixmap::fromImage(ColorTools::rgbCurveLine(s, color, palette().background().color().rgb())).transformed(t)); - } - } - - typename CurveParamWidget::CurveModes m_mode; - bool m_isVert; -}; - -template <> void CurveParamWidget::slotUpdatePointP(double, bool final) -{ - m_edit->updateCurrentPoint(QPointF(m_pX->value(), m_pY->value()), final); -} - -template <> void CurveParamWidget::slotUpdatePointP(double, bool final) -{ - BPoint p = m_edit->getCurrentPoint(); - p.setP(QPointF(m_pX->value(), m_pY->value())); - m_edit->updateCurrentPoint(p, final); -} - -template <> void CurveParamWidget::slotUpdatePointH1(double /*value*/, bool final) -{ - BPoint p = m_edit->getCurrentPoint(); - p.setH1(QPointF(m_h1X->value(), m_h1Y->value())); - m_edit->updateCurrentPoint(p, final); -} -template void CurveParamWidget::slotUpdatePointH1(double /*value*/, bool /*final*/) {} - -template <> void CurveParamWidget::slotUpdatePointH2(double /*value*/, bool final) -{ - BPoint p = m_edit->getCurrentPoint(); - p.setH2(QPointF(m_h2X->value(), m_h2Y->value())); - m_edit->updateCurrentPoint(p, final); -} -template void CurveParamWidget::slotUpdatePointH2(double /*value*/, bool /*final*/) {} - -template <> void CurveParamWidget::slotSetHandlesLinked(bool linked) -{ - BPoint p = m_edit->getCurrentPoint(); - p.setHandlesLinked(linked); - m_edit->updateCurrentPoint(p); -} -template void CurveParamWidget::slotSetHandlesLinked(bool /*linked*/) {} - -template <> void CurveParamWidget::slotShowAllHandles(bool show) -{ - m_edit->setShowAllHandles(show); - KdenliveSettings::setBezier_showallhandles(show); -} -template void CurveParamWidget::slotShowAllHandles(bool /*show*/) {} -template -CurveParamWidget::CurveParamWidget(const QString &spline, QWidget *parent) - : AbstractParamWidget(parent) - , m_mode(CurveModes::Luma) - , m_showPixmap(KdenliveSettings::bezier_showpixmap()) -{ - // construct curve editor - m_edit = new CurveWidget_t(this); - connect(m_edit, &CurveWidget_t::modified, this, &AbstractParamWidget::valueChanged); - using Point_t = typename CurveWidget_t::Point_t; - connect(m_edit, static_cast(&CurveWidget_t::currentPoint), this, - static_cast::*)(const Point_t &, bool)>(&CurveParamWidget::slotUpdatePointEntries)); - - // construct and fill layout - QVBoxLayout *layout = new QVBoxLayout(this); - - // grid layout containing the curve and the optional param values - QGridLayout *curve_layout = new QGridLayout(); - curve_layout->addWidget(m_edit, 0, 1); - - m_leftParam = new ValueLabel(true, m_mode, this); - m_leftParam->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); - m_leftParam->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - curve_layout->addWidget(m_leftParam, 0, 0); - - m_bottomParam = new ValueLabel(false, m_mode, this); - m_bottomParam->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); - m_bottomParam->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - curve_layout->addWidget(m_bottomParam, 1, 1); - - // horizontal layout to make sure that everything is centered - QHBoxLayout *horiz_layout = new QHBoxLayout; - horiz_layout->addLayout(curve_layout); - - layout->addLayout(horiz_layout); - QWidget *widget = new QWidget(this); - m_ui.setupUi(widget); - layout->addWidget(widget); - - // set up icons and initial button states - m_ui.buttonLinkHandles->setIcon(KoIconUtils::themedIcon(QStringLiteral("edit-link"))); - m_ui.buttonDeletePoint->setIcon(KoIconUtils::themedIcon(QStringLiteral("list-remove"))); - m_ui.buttonZoomIn->setIcon(KoIconUtils::themedIcon(QStringLiteral("zoom-in"))); - m_ui.buttonZoomOut->setIcon(KoIconUtils::themedIcon(QStringLiteral("zoom-out"))); - m_ui.buttonGridChange->setIcon(KoIconUtils::themedIcon(QStringLiteral("view-grid"))); - m_ui.buttonShowPixmap->setIcon(QIcon(QPixmap::fromImage(ColorTools::rgbCurvePlane(QSize(16, 16), ColorTools::ColorsRGB::Luma, 0.8)))); - m_ui.buttonResetSpline->setIcon(KoIconUtils::themedIcon(QStringLiteral("view-refresh"))); - m_ui.buttonShowAllHandles->setIcon(KoIconUtils::themedIcon(QStringLiteral("draw-bezier-curves"))); - m_ui.widgetPoint->setEnabled(false); - m_edit->setGridLines(KdenliveSettings::bezier_gridlines()); - m_ui.buttonShowPixmap->setChecked(KdenliveSettings::bezier_showpixmap()); - m_ui.buttonShowAllHandles->setChecked(KdenliveSettings::bezier_showallhandles()); - slotShowAllHandles(KdenliveSettings::bezier_showallhandles()); - - // connect buttons to their slots - connect(m_ui.buttonLinkHandles, &QAbstractButton::toggled, this, &CurveParamWidget::slotSetHandlesLinked); - connect(m_ui.buttonDeletePoint, &QAbstractButton::clicked, m_edit, &CurveWidget_t::slotDeleteCurrentPoint); - connect(m_ui.buttonZoomIn, &QAbstractButton::clicked, m_edit, &CurveWidget_t::slotZoomIn); - connect(m_ui.buttonZoomOut, &QAbstractButton::clicked, m_edit, &CurveWidget_t::slotZoomOut); - connect(m_ui.buttonGridChange, &QAbstractButton::clicked, this, &CurveParamWidget::slotGridChange); - connect(m_ui.buttonShowPixmap, &QAbstractButton::toggled, this, &CurveParamWidget::slotShowPixmap); - connect(m_ui.buttonResetSpline, &QAbstractButton::clicked, m_edit, &CurveWidget_t::reset); - connect(m_ui.buttonShowAllHandles, &QAbstractButton::toggled, this, &CurveParamWidget::slotShowAllHandles); - - setupLayoutPoint(); - setupLayoutHandles(); - m_edit->setFromString(spline); - - deleteIrrelevantItems(); - emit valueChanged(); -} - -template <> void CurveParamWidget::deleteIrrelevantItems() -{ - m_ui.gridLayout->removeWidget(m_ui.buttonShowAllHandles); - delete m_ui.buttonShowAllHandles; -} - -template void CurveParamWidget::deleteIrrelevantItems() -{ - // Nothing to do in general -} - -template void CurveParamWidget::setupLayoutPoint() -{ - m_pX = new DragValue(i18n("In"), 0, 3, 0, 1, -1, QString(), false, this); - m_pX->setStep(0.001); - m_pY = new DragValue(i18n("Out"), 0, 3, 0, 1, -1, QString(), false, this); - m_pY->setStep(0.001); - m_ui.layoutP->addWidget(m_pX); - m_ui.layoutP->addWidget(m_pY); - connect(m_pX, &DragValue::valueChanged, this, &CurveParamWidget::slotUpdatePointP); - connect(m_pY, &DragValue::valueChanged, this, &CurveParamWidget::slotUpdatePointP); -} - -template <> void CurveParamWidget::setupLayoutHandles() -{ - m_h1X = new DragValue(i18n("X"), 0, 3, -2, 2, -1, QString(), false, this); - m_h1X->setStep(0.001); - m_h1Y = new DragValue(i18n("Y"), 0, 3, -2, 2, -1, QString(), false, this); - m_h1Y->setStep(0.001); - m_h2X = new DragValue(i18n("X"), 0, 3, -2, 2, -1, QString(), false, this); - m_h2X->setStep(0.001); - m_h2Y = new DragValue(i18n("Y"), 0, 3, -2, 2, -1, QString(), false, this); - m_h2Y->setStep(0.001); - m_ui.layoutH1->addWidget(new QLabel(i18n("Handle 1:"))); - m_ui.layoutH1->addWidget(m_h1X); - m_ui.layoutH1->addWidget(m_h1Y); - m_ui.layoutH2->addWidget(new QLabel(i18n("Handle 2:"))); - m_ui.layoutH2->addWidget(m_h2X); - m_ui.layoutH2->addWidget(m_h2Y); - connect(m_h1X, &DragValue::valueChanged, this, &CurveParamWidget::slotUpdatePointH1); - connect(m_h1Y, &DragValue::valueChanged, this, &CurveParamWidget::slotUpdatePointH1); - connect(m_h2X, &DragValue::valueChanged, this, &CurveParamWidget::slotUpdatePointH2); - connect(m_h2Y, &DragValue::valueChanged, this, &CurveParamWidget::slotUpdatePointH2); -} - -template void CurveParamWidget::setupLayoutHandles() -{ - // Nothing to do in general -} - -template QString CurveParamWidget::toString() const -{ - return m_edit->toString(); -} - -template void CurveParamWidget::setMode(CurveModes mode) -{ - if (m_mode != mode) { - m_mode = mode; - if (m_showPixmap) { - slotShowPixmap(true); - } - m_leftParam->setMode(mode); - m_bottomParam->setMode(mode); - } -} - -template void CurveParamWidget::slotGridChange() -{ - m_edit->setGridLines((m_edit->gridLines() + 1) % 9); - KdenliveSettings::setBezier_gridlines(m_edit->gridLines()); -} - -template ColorTools::ColorsRGB CurveParamWidget::modeToColorsRGB(CurveModes mode) -{ - switch (mode) { - case CurveModes::Red: - return ColorTools::ColorsRGB::R; - case CurveModes::Green: - return ColorTools::ColorsRGB::G; - case CurveModes::Blue: - return ColorTools::ColorsRGB::B; - case CurveModes::Luma: - return ColorTools::ColorsRGB::Luma; - case CurveModes::Alpha: - return ColorTools::ColorsRGB::A; - case CurveModes::RGB: - case CurveModes::Hue: - case CurveModes::Saturation: - default: - return ColorTools::ColorsRGB::RGB; - } - return ColorTools::ColorsRGB::RGB; -} -template void CurveParamWidget::slotShowPixmap(bool show) -{ - m_showPixmap = show; - KdenliveSettings::setBezier_showpixmap(show); - if (show) { - if (m_mode == CurveModes::Hue) { - m_edit->setPixmap( - QPixmap::fromImage(ColorTools::hsvCurvePlane(m_edit->size(), QColor::fromHsv(200, 200, 200), ColorTools::COM_H, ColorTools::COM_H))); - } else if (m_mode == CurveModes::Saturation) { - m_edit->setPixmap(QPixmap()); - } else { - auto color = modeToColorsRGB(m_mode); - m_edit->setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(m_edit->size(), color, 1, palette().background().color().rgb()))); - } - } else { - m_edit->setPixmap(QPixmap()); - } -} - -template <> void CurveParamWidget::slotUpdatePointEntries(const BPoint &p, bool extremal) -{ - blockSignals(true); - if (p == BPoint()) { - m_ui.widgetPoint->setEnabled(false); - } else { - m_ui.widgetPoint->setEnabled(true); - // disable irrelevant buttons if the point is extremal - m_pX->setEnabled(!extremal); - m_ui.buttonDeletePoint->setEnabled(!extremal); - m_ui.buttonLinkHandles->setEnabled(!extremal); - if (extremal && p.p.x() + 1e-4 >= 1.00) { // last point - m_h2X->setEnabled(false); - m_h2Y->setEnabled(false); - } else { - m_h2X->setEnabled(true); - m_h2Y->setEnabled(true); - } - if (extremal && p.p.x() <= 0.01) { // first point - m_h1X->setEnabled(false); - m_h1Y->setEnabled(false); - } else { - m_h1X->setEnabled(true); - m_h1Y->setEnabled(true); - } - - for (auto elem : {m_pX, m_pY, m_h1X, m_h1Y, m_h2X, m_h2Y}) { - elem->blockSignals(true); - } - m_pX->setValue(p.p.x()); - m_pY->setValue(p.p.y()); - m_h1X->setValue(p.h1.x()); - m_h1Y->setValue(p.h1.y()); - m_h2X->setValue(p.h2.x()); - m_h2Y->setValue(p.h2.y()); - for (auto elem : {m_pX, m_pY, m_h1X, m_h1Y, m_h2X, m_h2Y}) { - elem->blockSignals(false); - } - m_ui.buttonLinkHandles->setChecked(p.handlesLinked); - } - blockSignals(false); -} - -template void CurveParamWidget::slotUpdatePointEntries(const BPoint &p, bool extremal) -{ - // Wrong slot called in curve widget - Q_ASSERT(false); -} - -template <> void CurveParamWidget::slotUpdatePointEntries(const QPointF &p, bool extremal) -{ - blockSignals(true); - if (p == QPointF()) { - m_ui.widgetPoint->setEnabled(false); - } else { - m_ui.widgetPoint->setEnabled(true); - // disable irrelevant buttons if the point is extremal - m_pX->setEnabled(!extremal); - m_ui.buttonDeletePoint->setEnabled(!extremal); - - for (auto elem : {m_pX, m_pY}) { - elem->blockSignals(true); - } - m_pX->setValue(p.x()); - m_pY->setValue(p.y()); - for (auto elem : {m_pX, m_pY}) { - elem->blockSignals(false); - } - } - blockSignals(false); -} - -template void CurveParamWidget::slotUpdatePointEntries(const QPointF &p, bool extremal) -{ - // Wrong slot called in curve widget - Q_ASSERT(false); -} - -template void CurveParamWidget::slotShowComment(bool show) -{ - Q_UNUSED(show); -} - -template void CurveParamWidget::setMaxPoints(int max) -{ - m_edit->setMaxPoints(max); -} diff --git a/src/effectstack/widgets/draggablelabel.cpp b/src/effectstack/widgets/draggablelabel.cpp deleted file mode 100644 index ba47651e3..000000000 --- a/src/effectstack/widgets/draggablelabel.cpp +++ /dev/null @@ -1,66 +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 "draggablelabel.h" -#include "klocalizedstring.h" -#include -#include - -DraggableLabel::DraggableLabel(const QString &text, QWidget *parent) - : QLabel(text, parent) - , m_dragStarted(false) -{ - setContextMenuPolicy(Qt::NoContextMenu); - setToolTip(i18n("Click to copy data to clipboard")); -} - -void DraggableLabel::mousePressEvent(QMouseEvent *ev) -{ - QLabel::mousePressEvent(ev); - if (ev->button() == Qt::LeftButton) { - m_clickStart = ev->pos(); - m_dragStarted = false; - } -} - -void DraggableLabel::mouseReleaseEvent(QMouseEvent *ev) -{ - // Don't call mouserelease in case of drag because label might be deleted by a drop - if (!m_dragStarted) - QLabel::mouseReleaseEvent(ev); - else - ev->ignore(); - m_clickStart = QPoint(); -} - -void DraggableLabel::mouseMoveEvent(QMouseEvent *ev) -{ - if (m_dragStarted) { - ev->ignore(); - return; - } - QLabel::mouseMoveEvent(ev); - if (!m_clickStart.isNull() && (m_clickStart - ev->pos()).manhattanLength() >= QApplication::startDragDistance()) { - emit startDrag(objectName()); - m_dragStarted = true; - m_clickStart = QPoint(); - } -} diff --git a/src/effectstack/widgets/draggablelabel.h b/src/effectstack/widgets/draggablelabel.h deleted file mode 100644 index ced99bc0b..000000000 --- a/src/effectstack/widgets/draggablelabel.h +++ /dev/null @@ -1,47 +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 DRAGGABLELABEL_H -#define DRAGGABLELABEL_H - -#include -#include -#include - -class DraggableLabel : public QLabel -{ - Q_OBJECT -public: - explicit DraggableLabel(const QString &text, QWidget *parent = nullptr); - -protected: - void mousePressEvent(QMouseEvent *ev) Q_DECL_OVERRIDE; - void mouseReleaseEvent(QMouseEvent *ev) Q_DECL_OVERRIDE; - void mouseMoveEvent(QMouseEvent *ev) Q_DECL_OVERRIDE; -signals: - void startDrag(const QString &); - -private: - QPoint m_clickStart; - bool m_dragStarted; -}; - -#endif diff --git a/src/effectstack/widgets/lumaliftgain.cpp b/src/effectstack/widgets/lumaliftgain.cpp deleted file mode 100644 index 90e4bcbb7..000000000 --- a/src/effectstack/widgets/lumaliftgain.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Jean-Baptiste Mardelle (jb@kdenlive.org) * - * Some code was borrowed from shotcut * - * * - * 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 "effectstack/widgets/lumaliftgain.h" -#include "effectstack/widgets/colorwheel.h" -#include "utils/flowlayout.h" - -#include - -static const double LIFT_FACTOR = 2.0; -static const double GAMMA_FACTOR = 2.0; -static const double GAIN_FACTOR = 4.0; - -LumaLiftGain::LumaLiftGain(const QDomNodeList &nodes, QWidget *parent) - : QWidget(parent) -{ - auto *flowLayout = new FlowLayout(this, 2, 2, 2); - /*QVBoxLayout *layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0);*/ - - QMap values; - for (int i = 0; i < nodes.count(); ++i) { - QDomElement pa = nodes.item(i).toElement(); - if (pa.tagName() != QLatin1String("parameter")) { - continue; - } - double val = m_locale.toDouble(pa.attribute(QStringLiteral("value"))) / m_locale.toDouble(pa.attribute(QStringLiteral("factor"))); - values.insert(pa.attribute(QStringLiteral("name")), val); - } - - QColor lift = QColor::fromRgbF(values.value(QStringLiteral("lift_r")), values.value(QStringLiteral("lift_g")), values.value(QStringLiteral("lift_b"))); - QColor gamma = QColor::fromRgbF(values.value(QStringLiteral("gamma_r")) / GAMMA_FACTOR, values.value(QStringLiteral("gamma_g")) / GAMMA_FACTOR, - values.value(QStringLiteral("gamma_b")) / GAMMA_FACTOR); - QColor gain = QColor::fromRgbF(values.value(QStringLiteral("gain_r")) / GAIN_FACTOR, values.value(QStringLiteral("gain_g")) / GAIN_FACTOR, - values.value(QStringLiteral("gain_b")) / GAIN_FACTOR); - - m_lift = new ColorWheel(QStringLiteral("lift"), i18n("Lift"), lift, this); - m_lift->setFactorDefaultZero(LIFT_FACTOR, 0, 0.5); - connect(m_lift, &ColorWheel::colorChange, this, &LumaLiftGain::valueChanged); - m_gamma = new ColorWheel(QStringLiteral("gamma"), i18n("Gamma"), gamma, this); - m_gamma->setFactorDefaultZero(GAMMA_FACTOR, 1, 0); - connect(m_gamma, &ColorWheel::colorChange, this, &LumaLiftGain::valueChanged); - m_gain = new ColorWheel(QStringLiteral("gain"), i18n("Gain"), gain, this); - m_gain->setFactorDefaultZero(GAIN_FACTOR, 1, 0); - connect(m_gain, &ColorWheel::colorChange, this, &LumaLiftGain::valueChanged); - - flowLayout->addWidget(m_lift); - flowLayout->addWidget(m_gamma); - flowLayout->addWidget(m_gain); - setLayout(flowLayout); - - /*layout->addWidget(label); - layout->addWidget(m_lift); - layout->addWidget(label2); - layout->addWidget(m_gamma); - layout->addWidget(label3); - layout->addWidget(m_gain); - setLayout(layout);*/ -} - -void LumaLiftGain::updateEffect(QDomElement &effect) -{ - NegQColor lift = m_lift->color(); - NegQColor gamma = m_gamma->color(); - NegQColor gain = m_gain->color(); - QMap values; - values.insert(QStringLiteral("lift_r"), lift.redF() * LIFT_FACTOR); - values.insert(QStringLiteral("lift_g"), lift.greenF() * LIFT_FACTOR); - values.insert(QStringLiteral("lift_b"), lift.blueF() * LIFT_FACTOR); - - values.insert(QStringLiteral("gamma_r"), gamma.redF() * GAMMA_FACTOR); - values.insert(QStringLiteral("gamma_g"), gamma.greenF() * GAMMA_FACTOR); - values.insert(QStringLiteral("gamma_b"), gamma.blueF() * GAMMA_FACTOR); - - values.insert(QStringLiteral("gain_r"), gain.redF() * GAIN_FACTOR); - values.insert(QStringLiteral("gain_g"), gain.greenF() * GAIN_FACTOR); - values.insert(QStringLiteral("gain_b"), gain.blueF() * GAIN_FACTOR); - - QDomNodeList namenode = effect.childNodes(); - for (int i = 0; i < namenode.count(); ++i) { - QDomElement pa = namenode.item(i).toElement(); - if (pa.tagName() != QLatin1String("parameter")) { - continue; - } - if (values.contains(pa.attribute(QStringLiteral("name")))) { - pa.setAttribute(QStringLiteral("value"), (int)(values.value(pa.attribute(QStringLiteral("name"))) * - m_locale.toDouble(pa.attribute(QStringLiteral("factor"), QStringLiteral("1"))))); - } - } -} diff --git a/src/effectstack/widgets/lumaliftgain.h b/src/effectstack/widgets/lumaliftgain.h deleted file mode 100644 index f172158f3..000000000 --- a/src/effectstack/widgets/lumaliftgain.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 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 LUMALIFTGAINWIDGET_H -#define LUMALIFTGAINWIDGET_H - -#include -#include -#include - -class ColorWheel; - -/** - * @class ChooseColorWidget - * @brief Provides options to choose 3 colors. - * @author Jean-Baptiste Mardelle - */ - -class LumaLiftGain : public QWidget -{ - Q_OBJECT -public: - /** @brief Sets up the widget. - * @param text (optional) What the color will be used for - * @param color (optional) initial color - * @param alphaEnabled (optional) Should transparent colors be enabled */ - explicit LumaLiftGain(const QDomNodeList &nodes, QWidget *parent = nullptr); - void updateEffect(QDomElement &effect); - -private: - QLocale m_locale; - ColorWheel *m_lift; - ColorWheel *m_gamma; - ColorWheel *m_gain; - -signals: - /** @brief Emitted whenever a different color was chosen. */ - void valueChanged(); -}; - -#endif diff --git a/src/effectstack/widgets/selectivecolor.cpp b/src/effectstack/widgets/selectivecolor.cpp deleted file mode 100644 index 5d9dfa15e..000000000 --- a/src/effectstack/widgets/selectivecolor.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright (C) 2016 Jean-Baptiste Mardelle -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 "effectstack/widgets/selectivecolor.h" - -#include - -SelectiveColor::SelectiveColor(const QDomElement &effect, QWidget *parent) - : QWidget(parent) -{ - setupUi(this); - QDomNodeList namenode = effect.elementsByTagName(QStringLiteral("parameter")); - for (int i = 0; i < namenode.count(); ++i) { - QDomElement pa = namenode.item(i).toElement(); - QDomElement na = pa.firstChildElement(QStringLiteral("name")); - QString type = pa.attribute(QStringLiteral("type")); - QString paramName = na.isNull() ? pa.attribute(QStringLiteral("name")) : i18n(na.text().toUtf8().data()); - if (type == QLatin1String("cmyk")) { - addParam(pa, paramName); - } else if (pa.attribute(QStringLiteral("name")) == QLatin1String("av.correction_method")) { - if (pa.attribute(QStringLiteral("value")).toInt() == 1) { - relative->setChecked(true); - } else { - absolute->setChecked(true); - } - } - } - connect(range, SIGNAL(currentIndexChanged(int)), this, SLOT(updateValues())); - connect(slider_black, &QAbstractSlider::valueChanged, this, &SelectiveColor::effectChanged); - connect(slider_yell, &QAbstractSlider::valueChanged, this, &SelectiveColor::effectChanged); - connect(slider_mag, &QAbstractSlider::valueChanged, this, &SelectiveColor::effectChanged); - connect(slider_cyan, &QAbstractSlider::valueChanged, this, &SelectiveColor::effectChanged); - connect(relative, &QAbstractButton::toggled, this, &SelectiveColor::effectChanged); - updateValues(); -} - -SelectiveColor::~SelectiveColor() {} - -void SelectiveColor::addParam(QDomElement &effect, QString name) -{ - QString tag = effect.attribute(QStringLiteral("name")); - if (name.isEmpty()) { - name = tag; - } - QString value = effect.attribute(QStringLiteral("value")); - if (value.isEmpty()) { - value = effect.attribute(QStringLiteral("default")); - } - QIcon icon; - if (!value.isEmpty()) { - icon = QIcon::fromTheme(QStringLiteral("dialog-ok-apply")); - } - range->addItem(icon, name, QStringList() << effect.attribute(QStringLiteral("name")) << value); -} - -void SelectiveColor::updateValues() -{ - QStringList values = range->currentData().toStringList(); - if (values.count() < 2) { - // Something is wrong, abort - return; - } - blockSignals(true); - spin_black->setValue(0); - spin_yell->setValue(0); - spin_mag->setValue(0); - spin_cyan->setValue(0); - QStringList vals = values.at(1).split(QLatin1Char(' ')); - switch (vals.count()) { - case 4: - spin_black->setValue(vals.at(3).toDouble() * 100); - case 3: - spin_yell->setValue(vals.at(2).toDouble() * 100); - case 2: - spin_mag->setValue(vals.at(1).toDouble() * 100); - case 1: - spin_cyan->setValue(vals.at(0).toDouble() * 100); - break; - default: - break; - } - blockSignals(false); -} - -void SelectiveColor::effectChanged() -{ - int vBlack = spin_black->value(); - int vYell = spin_yell->value(); - int vMag = spin_mag->value(); - int vCyan = spin_cyan->value(); - QString result; - if (vBlack == 0 && vYell == 0 && vMag == 0 && vCyan == 0) { - // default empty val - } else { - result = QStringLiteral("%1 %2 %3 %4").arg(vCyan / 100.0).arg(vMag / 100.0).arg(vYell / 100.0).arg(vBlack / 100.0); - } - QStringList values = range->currentData().toStringList(); - if (values.isEmpty()) { - // Something is wrong, abort - return; - } - if (values.at(1).isEmpty() && !result.isEmpty()) { - range->setItemIcon(range->currentIndex(), QIcon::fromTheme(QStringLiteral("dialog-ok-apply"))); - } else if (!values.at(1).isEmpty() && result.isEmpty()) { - range->setItemIcon(range->currentIndex(), QIcon()); - } - QStringList newData = QStringList() << values.at(0) << result; - range->setItemData(range->currentIndex(), newData); - emit valueChanged(); -} - -void SelectiveColor::updateEffect(QDomElement &effect) -{ - QMap values; - for (int i = 0; i < range->count(); i++) { - QStringList vals = range->itemData(i).toStringList(); - values.insert(vals.at(0), vals.at(1)); - } - QDomNodeList namenode = effect.childNodes(); - for (int i = 0; i < namenode.count(); ++i) { - QDomElement pa = namenode.item(i).toElement(); - if (pa.tagName() != QLatin1String("parameter")) { - continue; - } - QString paramName = pa.attribute(QStringLiteral("name")); - const QString val = values.value(paramName); - if (!val.isEmpty()) { - pa.setAttribute(QStringLiteral("value"), val); - } else if (paramName == QLatin1String("av.correction_method")) { - pa.setAttribute(QStringLiteral("value"), relative->isChecked() ? QStringLiteral("1") : QStringLiteral("0")); - } - } -} diff --git a/src/effectstack/widgets/selectivecolor.h b/src/effectstack/widgets/selectivecolor.h deleted file mode 100644 index 898c8e049..000000000 --- a/src/effectstack/widgets/selectivecolor.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright (C) 2016 Jean-Baptiste Mardelle -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 SELECTIVECOLORWIDGET_H -#define SELECTIVECOLORWIDGET_H - -#include "ui_selectivecolor_ui.h" - -#include -#include -#include - -/** - * @class SelectiveColor - * @brief Provides options to adjust CMYK factor of a color range. - * @author Jean-Baptiste Mardelle - */ - -class SelectiveColor : public QWidget, public Ui::SelectiveColor -{ - Q_OBJECT -public: - /** @brief Sets up the widget. - * @param text (optional) What the color will be used for - * @param color (optional) initial color - * @param alphaEnabled (optional) Should transparent colors be enabled */ - explicit SelectiveColor(const QDomElement &effect, QWidget *parent = nullptr); - ~SelectiveColor(); - void addParam(QDomElement &effect, QString name); - void updateEffect(QDomElement &effect); - -private: - QLocale m_locale; - -private slots: - void updateValues(); - void effectChanged(); - -signals: - /** @brief Emitted whenever a different color was chosen. */ - void valueChanged(); -}; - -#endif diff --git a/src/project/transitionsettings.cpp b/src/project/transitionsettings.cpp index 96ad0d2aa..45a1976ff 100644 --- a/src/project/transitionsettings.cpp +++ b/src/project/transitionsettings.cpp @@ -1,348 +1,347 @@ /*************************************************************************** effecstackedit.cpp - description ------------------- begin : Mar 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 "transitionsettings.h" #include "core.h" #include "doc/kdenlivedoc.h" -#include "effectslist/effectslist.h" #include "kdenlivesettings.h" #include "mainwindow.h" #include "project/projectmanager.h" #include "klocalizedstring.h" #include TransitionSettings::TransitionSettings(Monitor *monitor, QWidget *parent) : QWidget(parent) , m_usedTransition(nullptr) , m_autoTrackTransition(0) { setupUi(this); auto *vbox1 = new QVBoxLayout(frame); m_effectEdit = new EffectStackEdit(monitor, frame); vbox1->setContentsMargins(0, 0, 0, 0); vbox1->setSpacing(0); vbox1->addWidget(m_effectEdit); frame->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); connect(m_effectEdit, &EffectStackEdit::seekTimeline, this, &TransitionSettings::slotSeekTimeline); connect(m_effectEdit, &EffectStackEdit::importClipKeyframes, this, &TransitionSettings::prepareImportClipKeyframes); setEnabled(false); setAcceptDrops(true); QList transitionsList; int max = MainWindow::transitions.effectNames().count(); QStringList transitionInfo; int ix = 0; for (; ix < max; ++ix) { transitionInfo = MainWindow::transitions.effectIdInfo(ix); if (transitionInfo.isEmpty()) { continue; } transitionInfo << QString::number(ix); transitionsList.append(transitionInfo); } ix = 0; for (const QStringList &value : transitionsList) { QStringList list = value; if (!list.isEmpty()) { list.removeLast(); } transitionList->addItem(value.at(0), list); transitionList->setItemData(ix, MainWindow::transitions.getInfoFromIndex(value.last().toInt()), Qt::ToolTipRole); ++ix; } connect(transitionList, SIGNAL(activated(int)), this, SLOT(slotTransitionChanged())); connect(transitionTrack, SIGNAL(activated(int)), this, SLOT(slotTransitionTrackChanged())); connect(m_effectEdit, &EffectStackEdit::parameterChanged, this, &TransitionSettings::slotUpdateEffectParams); } void TransitionSettings::prepareImportClipKeyframes(GraphicsRectItem, const QMap &keyframes) { emit importClipKeyframes(TransitionWidget, m_usedTransition->info(), m_usedTransition->toXML(), keyframes); } void TransitionSettings::refreshIcons() { QList allMenus = this->findChildren(); for (int i = 0; i < allMenus.count(); i++) { QAction *m = allMenus.at(i); QIcon ic = m->icon(); if (ic.isNull() || ic.name().isEmpty()) { continue; } QIcon newIcon = QIcon::fromTheme(ic.name()); m->setIcon(newIcon); } QList allButtons = this->findChildren(); for (int i = 0; i < allButtons.count(); i++) { QToolButton *m = allButtons.at(i); QIcon ic = m->icon(); if (ic.isNull() || ic.name().isEmpty()) { continue; } QIcon newIcon = QIcon::fromTheme(ic.name()); m->setIcon(newIcon); } } void TransitionSettings::dragEnterEvent(QDragEnterEvent *event) { if (m_effectEdit->doesAcceptDrops() && event->mimeData()->hasFormat(QStringLiteral("kdenlive/geometry"))) { event->setDropAction(Qt::CopyAction); event->setAccepted(true); } else { QWidget::dragEnterEvent(event); } } void TransitionSettings::dropEvent(QDropEvent *event) { if (event->mimeData()->hasFormat(QStringLiteral("kdenlive/geometry"))) { QString itemData = QString::fromLatin1(event->mimeData()->data(QStringLiteral("kdenlive/geometry"))); QMap keyframes; keyframes.insert(i18n("Geometry"), itemData); emit importClipKeyframes(TransitionWidget, m_usedTransition->info(), m_usedTransition->toXML(), keyframes); } } void TransitionSettings::updateProjectFormat() { // TODO REFAC: get tracks list // m_tracks = pCore->projectManager()->currentTimeline()->getTracksInfo(); // updateTrackList(); } void TransitionSettings::updateTimecodeFormat() { m_effectEdit->updateTimecodeFormat(); } void TransitionSettings::updateTrackList() { transitionTrack->blockSignals(true); int current = transitionTrack->itemData(transitionTrack->currentIndex()).toInt(); transitionTrack->clear(); transitionTrack->addItem(i18n("Auto"), -1); int limit = 1; if (m_usedTransition) { limit = m_usedTransition->track() - 1; } QIcon videoIcon = QIcon::fromTheme(QStringLiteral("kdenlive-show-video")); QIcon audioIcon = QIcon::fromTheme(QStringLiteral("kdenlive-show-audio")); for (int i = limit; i > 0; i--) { transitionTrack->addItem(m_tracks.at(i).type == VideoTrack ? videoIcon : audioIcon, m_tracks.at(i).trackName.isEmpty() ? QString::number(i) : m_tracks.at(i).trackName, i); } transitionTrack->addItem(i18n("Black"), 0); transitionTrack->setCurrentIndex(transitionTrack->findData(current)); transitionTrack->blockSignals(false); } void TransitionSettings::slotTransitionChanged(bool reinit, bool updateCurrent) { QDomElement e = m_usedTransition->toXML().cloneNode().toElement(); if (reinit) { // Reset the transition parameters to the default one disconnect(m_effectEdit->monitor(), &Monitor::seekPosition, this, &TransitionSettings::slotRenderPos); QDomElement newTransition = MainWindow::transitions.getEffectByName(transitionList->currentText()).cloneNode().toElement(); pCore->projectManager()->currentTimeline()->transitionHandler->initTransition(newTransition); slotUpdateEffectParams(e, newTransition); m_effectEdit->transferParamDesc(newTransition, m_usedTransition->info(), false); if (m_effectEdit->needsMonitorEffectScene() != 0u) { connect(m_effectEdit->monitor(), &Monitor::seekPosition, this, &TransitionSettings::slotRenderPos, Qt::UniqueConnection); } } else if (!updateCurrent) { // Transition changed, update parameters dialog // slotUpdateEffectParams(e, e); m_effectEdit->transferParamDesc(e, m_usedTransition->info(), false); } else { // Same transition, we just want to update the parameters value int ix = transitionList->findData(m_usedTransition->transitionInfo(), Qt::UserRole, Qt::MatchExactly); if (ix != transitionList->currentIndex()) { // Transition type changed, reload params transitionList->blockSignals(true); transitionList->setCurrentIndex(ix); transitionList->blockSignals(false); m_effectEdit->transferParamDesc(e, m_usedTransition->info(), false); } else { slotUpdateEffectParams(e, e); if (m_usedTransition->hasGeometry()) { m_effectEdit->transferParamDesc(m_usedTransition->toXML(), m_usedTransition->info(), false); } } if (m_effectEdit->needsMonitorEffectScene() != 0u) { connect(m_effectEdit->monitor(), &Monitor::seekPosition, this, &TransitionSettings::slotRenderPos, Qt::UniqueConnection); } } // slotCheckMonitorPosition(m_effectEdit->monitor()->render->seekFramePosition()); } void TransitionSettings::slotTransitionTrackChanged() { if (m_usedTransition == nullptr) { return; } int ix = 0; QDomElement oldxml = m_usedTransition->toXML().cloneNode().toElement(); if (transitionTrack->currentIndex() > 0) { ix = transitionTrack->itemData(transitionTrack->currentIndex()).toInt(); m_usedTransition->setForcedTrack(true, ix); m_effectEdit->updateParameter(QStringLiteral("force_track"), QStringLiteral("1")); } else { ix = m_autoTrackTransition; m_usedTransition->setForcedTrack(false, ix); m_effectEdit->updateParameter(QStringLiteral("force_track"), QStringLiteral("0")); } emit transitionUpdated(m_usedTransition, oldxml); m_effectEdit->updateParameter(QStringLiteral("transition_btrack"), QString::number(ix)); } void TransitionSettings::slotTransitionItemSelected(Transition *t, int nextTrack, const QPoint &p, bool update) { setEnabled(t != nullptr); m_effectEdit->setFrameSize(p); m_autoTrackTransition = nextTrack; disconnect(m_effectEdit->monitor(), &Monitor::seekPosition, this, &TransitionSettings::slotRenderPos); if (t == m_usedTransition) { if (t == nullptr) { return; } if (update) { transitionTrack->blockSignals(true); updateTrackList(); if (t->forcedTrack()) { transitionTrack->setCurrentIndex(transitionTrack->findData(t->transitionEndTrack())); } else { transitionTrack->setCurrentIndex(0); } transitionTrack->blockSignals(false); } if (update || t->cropDuration() != m_transitionDuration || t->startPos() != m_transitionStart) { m_transitionDuration = t->cropDuration(); m_transitionStart = t->startPos(); slotTransitionChanged(false, true); } if (m_effectEdit->needsMonitorEffectScene() != 0u) { slotRenderPos(m_effectEdit->monitor()->position()); connect(m_effectEdit->monitor(), &Monitor::seekPosition, this, &TransitionSettings::slotRenderPos, Qt::UniqueConnection); } return; } if (update) { return; } if (t) { m_transitionDuration = t->cropDuration(); m_transitionStart = t->startPos(); transitionTrack->blockSignals(true); m_usedTransition = t; updateTrackList(); if (!t->forcedTrack()) { transitionTrack->setCurrentIndex(0); } else { transitionTrack->setCurrentIndex(transitionTrack->findData(t->transitionEndTrack())); } transitionTrack->blockSignals(false); int ix = transitionList->findData(t->transitionInfo(), Qt::UserRole, Qt::MatchExactly); if (ix != -1) { transitionList->blockSignals(true); transitionList->setCurrentIndex(ix); slotTransitionChanged(false, false); transitionList->blockSignals(false); } if (m_effectEdit->needsMonitorEffectScene() != 0u) { slotRenderPos(m_effectEdit->monitor()->position()); connect(m_effectEdit->monitor(), &Monitor::seekPosition, this, &TransitionSettings::slotRenderPos, Qt::UniqueConnection); } } else { // null transition selected m_usedTransition = nullptr; ItemInfo info; m_effectEdit->transferParamDesc(QDomElement(), info, false); m_effectEdit->monitor()->slotShowEffectScene(MonitorSceneDefault); } } void TransitionSettings::slotUpdateEffectParams(const QDomElement &oldparam, const QDomElement ¶m) { if (m_usedTransition) { m_usedTransition->setTransitionParameters(param); } // oldparam must be also first given to Transition and then return the toXML() if (oldparam != param) { emit transitionUpdated(m_usedTransition, oldparam); } } void TransitionSettings::raiseWindow(QWidget *dock) { if ((dock != nullptr) && (m_usedTransition != nullptr)) { dock->raise(); } } void TransitionSettings::slotRenderPos(int pos) { if (m_usedTransition) { m_effectEdit->slotSyncEffectsPos(pos - m_usedTransition->startPos().frames(KdenliveSettings::project_fps())); if (isEnabled()) { slotCheckMonitorPosition(pos); } } } void TransitionSettings::slotSeekTimeline(int pos) { if (m_usedTransition) { emit seekTimeline(m_usedTransition->startPos().frames(KdenliveSettings::project_fps()) + pos); } } void TransitionSettings::slotCheckMonitorPosition(int renderPos) { if (!isEnabled()) { return; } MonitorSceneType sceneType = m_effectEdit->needsMonitorEffectScene(); if (sceneType != MonitorSceneDefault) { if (renderPos >= m_usedTransition->startPos().frames(KdenliveSettings::project_fps()) && renderPos < m_usedTransition->endPos().frames(KdenliveSettings::project_fps())) { if (!m_effectEdit->monitor()->effectSceneDisplayed(sceneType)) { m_effectEdit->monitor()->slotShowEffectScene(sceneType); m_effectEdit->initEffectScene(renderPos - m_usedTransition->startPos().frames(KdenliveSettings::project_fps())); } } else { m_effectEdit->monitor()->slotShowEffectScene(MonitorSceneDefault); } } else { m_effectEdit->monitor()->slotShowEffectScene(MonitorSceneDefault); } } void TransitionSettings::setKeyframes(const QString &tag, const QString &keyframes) { m_effectEdit->setKeyframes(tag, keyframes); } void TransitionSettings::updatePalette() { // We need to reset current stylesheet if we want to change the palette! m_effectEdit->updatePalette(); }