Add Qt6 Support (#7339)

* Rebase against master

Co-authored-by: michaelgregorius <michael.gregorius.git@arcor.de>
Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com>

* Fix Qt6 DMG on Apple (#7240)

- Fix linking issues with Qt Framework files
- Fix qmake detection

* Fixes after rebase

* Fix embed.cpp compilation

Fix implicit conversion from int when using QString.arg(...)

* Fix Qt6 signature change for nativeEventFilter (#7254)

* Adds win32EventFilter a wrapper for nativeEventFilter on Windows
* win32EventFilter is currently used to intercept top-level Window events (currently, to avoid VSTs setting transparency of the parent application)

* fix broken signal slot connections (#7274)

QComboBox activated() replaced with textActivated() since Qt 5.14

* Enabled VSTs on Qt 6 (#7273)

* enabled VST support for Qt 6 builds
* Note : Embedding on QT6 will be buggy on linux as a result of using qt embedding, which unfortunately is a qt bug which hasn't been resolved.

* Changed bar lines to follow snap size (#7034)

* Added lines in between bars
* Changed bar lines to follow snap size
* Changed default zoom and quantization value
* Added constants for line widths
* Added QSS configuration for new grid line colors
* Tied line widths to QSS properties
* Changed default quantization to 1/4
* Removed clear() from destructor model
* Removed destructor in ComboBoxModel.h
* Changed member set/get functions to pass by value
* Updated signal connection with newer syntax

* Fix compilation

* Fix MSVC builds

* fix nullptr deref in AudioFileProcessor (qt6 branch) (#7532)

* ensured mouse event != nullptr before deref

* separation of concerns: AFP WaveView updateCursor

extract check to pointerCloseToStartEndOrLoop()

* marked some function parameters as const

* Remove Core5Compat usage

* Fix bad merge

* Fixes after rebase

* Simplify QTX_WRAP_CPP call

* Remove comments that are obvious to a developer

* Whitespace

* Try using Qt 6 for MSVC CI

I chose Qt 6.5 because it's the last Qt LTS release with declared
support for Visual Studio 2019. Once we upgrade to Visual Studio 2022,
we could upgrade Qt as well.

* Fix MSVC build

Also fixes two memory leaks in MidiWinMM

* Fix GuiApplication on MSVC

* Fix interpolateInRgb

* Try building with patched Calf

* Fix submodule

* Fix OpulenZ build

* Try to fix zyn

* Fix comment

* Ty to fix zyn (again)

* Ty to fix RemotePluginBase

* Revert "Ty to fix RemotePluginBase"

This reverts commit 92dac44ffb11e19d1d5a21d9155369f017bd59e9.

* Update plugins/ZynAddSubFx/CMakeLists.txt

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>

* Fix vertical & horizontal scroll wheel in SongEditor

* AppImage: Fix finding of Qt6 libs

* Fix implicit QString --> QFileInfo conversion

* Point submodule to lmms

* Fix multiple deprecation warnings

* Fix for Clang compiler

* Build with latest Qt LTS version now that we use MSVC 2022

* Update jurplel/install-qt-action to v4.3.0

* Bump minimum Qt6 version for MSVC

* Fix incorrect Qt version checks

Some comparisons were using ">" rather than ">="

* `QSize()` != `QSize(0, 0)`

* Fix more deprecation warnings

* Fix style

* Simplify Spectrum Analyzer mouse events

The Qt bug that used to be present appears to have been fixed, so the
workaround can be removed

* Minor changes

* Fix deprecated QCheckBox signal

* Fix setContent helper functions

* Remove QMultiMap usage from ControlLayout

* Remove SIGNAL and SLOT macros

* Revert TrackView.cpp changes

* Remove Q_DISABLE_MOVE usage since it does not seem to be available in Qt6

---------

Co-authored-by: michaelgregorius <michael.gregorius.git@arcor.de>
Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com>
Co-authored-by: BoredGuy1 <66702733+BoredGuy1@users.noreply.github.com>
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
Co-authored-by: Lisa Magdalena Riedler <git@riedler.wien>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
This commit is contained in:
Tres Finocchiaro
2025-11-03 12:58:15 -05:00
committed by GitHub
parent fcb356df3d
commit 51529cefb1
76 changed files with 798 additions and 457 deletions

View File

@@ -372,10 +372,10 @@ jobs:
- name: Install tools
run: choco install ccache
- name: Install Qt
uses: jurplel/install-qt-action@b3ea5275e37b734d027040e2c7fe7a10ea2ef946
uses: jurplel/install-qt-action@d325aaf2a8baeeda41ad0b5d39f84a6af9bcf005
with:
version: '5.15.2'
arch: "win64_msvc2019_64"
version: '6.8.*'
arch: "win64_msvc2022_64"
archives: qtbase qtsvg qttools
cache: true
- name: Set up build environment
@@ -392,6 +392,7 @@ jobs:
--toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake `
-Werror=dev `
-DCMAKE_BUILD_TYPE=RelWithDebInfo `
-DWANT_QT6=ON `
-DUSE_COMPILE_CACHE=ON `
-DUSE_WERROR=ON `
-DVCPKG_TARGET_TRIPLET="x64-windows" `

View File

@@ -107,6 +107,7 @@ option(WANT_DEBUG_GPROF "Enable gprof profiler" OFF)
OPTION(BUNDLE_QT_TRANSLATIONS "Install Qt translation files for LMMS" OFF)
option(WANT_DEBUG_CPACK "Show detailed logs for packaging commands" OFF)
option(WANT_CPACK_TARBALL "Request CPack to create a tarball instead of an installer" OFF)
option(WANT_QT6 "Build with experimental Qt6 support" OFF)
IF(LMMS_BUILD_APPLE)
@@ -174,31 +175,45 @@ check_library_exists(rt shm_open "" LMMS_HAVE_LIBRT)
LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}")
FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Core Gui Widgets Xml Svg REQUIRED)
FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET)
if(WANT_QT6)
set(QT_VERSION_MAJOR 6)
if(MSVC)
set(LMMS_QT_MIN_VERSION 6.8.0)
else()
set(LMMS_QT_MIN_VERSION 6.0.0)
endif()
set(STATUS_QT6 "Enabled")
else()
set(QT_VERSION_MAJOR 5)
set(LMMS_QT_MIN_VERSION 5.9.0)
set(STATUS_QT6 "Disabled")
endif()
find_package(Qt${QT_VERSION_MAJOR} ${LMMS_QT_MIN_VERSION} COMPONENTS Core Gui Widgets Xml Svg REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET)
include_directories(SYSTEM
${Qt5Core_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS}
${Qt5Xml_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Gui_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS}
${Qt${QT_VERSION_MAJOR}Xml_INCLUDE_DIRS}
)
SET(QT_LIBRARIES
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::Xml
Qt5::Svg
set(QT_LIBRARIES
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Gui
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Xml
Qt${QT_VERSION_MAJOR}::Svg
)
IF(LMMS_BUILD_LINUX AND WANT_VST)
IF(LMMS_BUILD_LINUX AND WANT_VST AND NOT WANT_QT6)
FIND_PACKAGE(Qt5 COMPONENTS X11Extras REQUIRED)
LIST(APPEND QT_LIBRARIES Qt5::X11Extras)
ENDIF()
# Resolve Qt5::qmake to full path for use in packaging scripts
GET_TARGET_PROPERTY(QT_QMAKE_EXECUTABLE "${Qt5Core_QMAKE_EXECUTABLE}" IMPORTED_LOCATION)
# Resolve qmake to full path for use in packaging scripts
get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
# Find the location of Qt translation files
execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
@@ -211,8 +226,8 @@ IF(EXISTS "${QT_TRANSLATIONS_DIR}")
ADD_DEFINITIONS("-DQT_TRANSLATIONS_DIR=\"${QT_TRANSLATIONS_DIR}\"")
ENDIF()
FIND_PACKAGE(Qt5Test)
SET(QT_QTTEST_LIBRARY Qt5::Test)
FIND_PACKAGE(Qt${QT_VERSION_MAJOR}Test)
SET(QT_QTTEST_LIBRARY Qt${QT_VERSION_MAJOR}::Test)
# check for libsndfile
FIND_PACKAGE(SndFile REQUIRED)
@@ -878,6 +893,7 @@ MESSAGE(
"* Debug packaging commands : ${STATUS_DEBUG_CPACK}\n"
"* Profile using GNU profiler : ${STATUS_GPROF}\n"
"* Debug assertions : ${STATUS_ASSERTIONS}\n"
"* Experimental Qt6 support : ${STATUS_QT6}\n"
)
MESSAGE(

View File

@@ -1,9 +1,9 @@
SET(PLUGIN_FILES "")
IF(LMMS_BUILD_WIN32)
INSTALL(FILES $<TARGET_FILE:Qt5::QWindowsIntegrationPlugin> DESTINATION platforms)
INSTALL(FILES $<TARGET_FILE:Qt5::QSvgIconPlugin> DESTINATION iconengines)
INSTALL(FILES $<TARGET_FILE:Qt5::QSvgPlugin> DESTINATION imageformats)
INSTALL(FILES $<TARGET_FILE:Qt5::Svg> DESTINATION .)
INSTALL(FILES $<TARGET_FILE:Qt${QT_VERSION_MAJOR}::QWindowsIntegrationPlugin> DESTINATION platforms)
INSTALL(FILES $<TARGET_FILE:Qt${QT_VERSION_MAJOR}::QSvgIconPlugin> DESTINATION iconengines)
INSTALL(FILES $<TARGET_FILE:Qt${QT_VERSION_MAJOR}::QSvgPlugin> DESTINATION imageformats)
INSTALL(FILES $<TARGET_FILE:Qt${QT_VERSION_MAJOR}::Svg> DESTINATION .)
ENDIF()
IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES)

View File

@@ -128,6 +128,10 @@ set(ENV{PATH} "${QTBIN}:$ENV{PATH}")
# Promote finding our own libraries first
set(ENV{LD_LIBRARY_PATH} "${APP}/usr/lib/${lmms}/:${APP}/usr/lib/${lmms}/optional:$ENV{LD_LIBRARY_PATH}")
# Workaround for finding libs from online installer
# https://github.com/linuxdeploy/linuxdeploy-plugin-qt/issues/193
set(ENV{LD_LIBRARY_PATH} "${QTBIN}/../lib:$ENV{LD_LIBRARY_PATH}")
# Skip slow searching of copyright files https://github.com/linuxdeploy/linuxdeploy/issues/278
set(ENV{DISABLE_COPYRIGHT_FILES_DEPLOYMENT} 1)

View File

@@ -30,7 +30,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)
ADD_GEN_QRC(RCC_OUT "${PLUGIN_NAME}.qrc" PREFIX artwork/${PLUGIN_NAME} ${PLUGIN_EMBEDDED_RESOURCES})
ENDIF(ER_LEN)
QT5_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES})
cmake_language(CALL QT${QT_VERSION_MAJOR}_WRAP_CPP plugin_MOC_out ${PLUGIN_MOCFILES})
FOREACH(f ${PLUGIN_SOURCES})
ADD_FILE_DEPENDENCIES(${f} ${RCC_OUT})
@@ -51,7 +51,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)
ADD_LIBRARY(${PLUGIN_NAME} ${PLUGIN_LINK} ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT})
target_link_libraries("${PLUGIN_NAME}" lmms Qt5::Widgets Qt5::Xml)
target_link_libraries("${PLUGIN_NAME}" lmms Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Xml)
INSTALL(TARGETS ${PLUGIN_NAME}
LIBRARY DESTINATION "${PLUGIN_DIR}"

View File

@@ -58,7 +58,7 @@ function(add_gen_qrc RCC_OUT QRC_NAME)
# generators. See issue #6177.
add_custom_command(
OUTPUT "${CPP_FILE}"
COMMAND Qt5::rcc
COMMAND Qt${QT_VERSION_MAJOR}::rcc
--name "${RESOURCE_NAME}"
--output "${CPP_FILE}"
"${QRC_FILE}"

View File

@@ -1,5 +1,5 @@
SET(QT_LUPDATE_EXECUTABLE "${Qt5_LUPDATE_EXECUTABLE}")
SET(QT_LRELEASE_EXECUTABLE "${Qt5_LRELEASE_EXECUTABLE}")
SET(QT_LUPDATE_EXECUTABLE "${Qt${QT_VERSION_MAJOR}_LUPDATE_EXECUTABLE}")
SET(QT_LRELEASE_EXECUTABLE "${Qt${QT_VERSION_MAJOR}_LRELEASE_EXECUTABLE}")
IF(QT_LUPDATE_EXECUTABLE STREQUAL "")
EXECUTE_PROCESS(COMMAND "lupdate" "-help" RESULT_VARIABLE LUPDATE_FALLBACK OUTPUT_QUIET)

View File

@@ -55,8 +55,7 @@ protected:
//! Forward key events to the parent to prevent stuck notes when the dialog gets focus
void keyReleaseEvent(QKeyEvent *event) override
{
QKeyEvent ke(*event);
QApplication::sendEvent(parentWidget(), &ke);
QApplication::sendEvent(parentWidget(), event);
}
private:
//! Copy the current QColorDialog palette into an array

View File

@@ -35,17 +35,23 @@ class ColorHelper
public:
static QColor interpolateInRgb(const QColor& a, const QColor& b, float t)
{
qreal ar, ag, ab, aa;
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
using ColorType = float;
#else
using ColorType = qreal;
#endif
ColorType ar, ag, ab, aa;
a.getRgbF(&ar, &ag, &ab, &aa);
qreal br, bg, bb, ba;
ColorType br, bg, bb, ba;
b.getRgbF(&br, &bg, &bb, &ba);
const auto t2 = static_cast<qreal>(t);
const float interH = std::lerp(ar, br, t2);
const float interS = std::lerp(ag, bg, t2);
const float interV = std::lerp(ab, bb, t2);
const float interA = std::lerp(aa, ba, t2);
const auto t2 = static_cast<ColorType>(t);
const auto interH = std::lerp(ar, br, t2);
const auto interS = std::lerp(ag, bg, t2);
const auto interV = std::lerp(ab, bb, t2);
const auto interA = std::lerp(aa, ba, t2);
return QColor::fromRgbF(interH, interS, interV, interA);
}

View File

@@ -96,6 +96,8 @@ class ControlLayout : public QLayout
{
Q_OBJECT
using ControlLayoutMap = QMap<QString, QLayoutItem*>;
public:
explicit ControlLayout(QWidget *parent,
int margin = -1, int hSpacing = -1, int vSpacing = -1);
@@ -124,9 +126,9 @@ private slots:
private:
int doLayout(const QRect &rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const;
QMap<QString, QLayoutItem *>::const_iterator pairAt(int index) const;
ControlLayoutMap::const_iterator pairAt(int index) const;
QMultiMap<QString, QLayoutItem *> m_itemMap;
ControlLayoutMap m_itemMap;
int m_hSpace;
int m_vSpace;
// relevant dimension is width, as later, heightForWidth() will be called

View File

@@ -29,8 +29,10 @@
#include <type_traits>
#include <QDomDocument>
#include <QFontMetrics>
#include <QKeySequence>
#include <QVariant>
#include <QWheelEvent>
namespace lmms
@@ -58,15 +60,74 @@ inline int horizontalAdvance(const QFontMetrics& metrics, const QString& text)
* @param wheelEvent
* @return the position of wheelEvent
*/
inline QPoint position(QWheelEvent *wheelEvent)
inline QPoint position(const QWheelEvent* wheelEvent)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
return wheelEvent->position().toPoint();
#else
return wheelEvent->pos();
#endif
}
/**
* @brief position is a backwards-compatible adapter for
* QDropEvent::position and pos functions.
* @param me
* @return the position of the drop event
*/
inline QPoint position(const QDropEvent* de)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return de->position().toPoint();
#else
return de->pos();
#endif
}
/**
* @brief position is a backwards-compatible adapter for
* QMouseEvent::position and pos functions.
* @param me
* @return the position of the mouse event
*/
inline QPoint position(const QMouseEvent* me)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return me->position().toPoint();
#else
return me->pos();
#endif
}
/**
* @brief positionF is a backwards-compatible adapter for
* QMouseEvent::position and localPos functions.
* @param me
* @return the position of the mouse event
*/
inline QPointF positionF(const QMouseEvent* me)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return me->position();
#else
return me->localPos();
#endif
}
/**
* @brief globalPosition is a backwards-compatible adapter for
* QMouseEvent::globalPosition and globalPos functions.
* @param me
* @return the global position of the mouse event
*/
inline QPoint globalPosition(const QMouseEvent* me)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return me->globalPosition().toPoint();
#else
return me->globalPos();
#endif
}
namespace detail
{
@@ -77,20 +138,69 @@ inline constexpr bool IsKeyOrModifier = std::is_same_v<T, Qt::Key>
} // namespace detail
/**
* @brief Combines Qt key and modifier arguments together,
* replacing `A | B` which was deprecated in C++20
* due to the enums being different types. (P1120R0)
* @param args Any number of Qt::Key, Qt::Modifier, or Qt::KeyboardModifier
* @return The combination of the given keys/modifiers as an int
* @return The combination of the given keys/modifiers as a QKeySequence
*/
template<typename... Args, std::enable_if_t<(detail::IsKeyOrModifier<Args> && ...), bool> = true>
constexpr int combine(Args... args)
template<typename... Args> requires (detail::IsKeyOrModifier<Args> && ...)
inline QKeySequence keySequence(Args... args)
{
return (0 | ... | static_cast<int>(args));
}
/**
* @brief typeId is a backwards-compatible adapter for
* QVariant::typeId and type functions.
* @param variant
* @return the type id of the variant
*/
inline QMetaType::Type typeId(const QVariant& variant)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
return static_cast<QMetaType::Type>(variant.typeId());
#else
return static_cast<QMetaType::Type>(variant.type());
#endif
}
//! Backwards-compatible adapter for QDomDocument::setContent
inline bool setContent(QDomDocument& doc, const QByteArray& text,
QString* errorMsg = nullptr, int* errorLine = nullptr, int* errorColumn = nullptr)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
auto result = doc.setContent(text, QDomDocument::ParseOption::Default);
if (result) { return true; }
if (errorMsg) { *errorMsg = std::move(result.errorMessage); }
if (errorLine) { *errorLine = static_cast<int>(result.errorLine); }
if (errorColumn) { *errorColumn = static_cast<int>(result.errorColumn); }
return false;
#else
return doc.setContent(text, errorMsg, errorLine, errorColumn);
#endif
}
//! Backwards-compatible adapter for QDomDocument::setContent
inline bool setContent(QDomDocument& doc, QIODevice* dev, bool namespaceProcessing,
QString* errorMsg = nullptr, int* errorLine = nullptr, int* errorColumn = nullptr)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
const auto options = namespaceProcessing
? QDomDocument::ParseOption::UseNamespaceProcessing
: QDomDocument::ParseOption::Default;
auto result = doc.setContent(dev, options);
if (result) { return true; }
if (errorMsg) { *errorMsg = std::move(result.errorMessage); }
if (errorLine) { *errorLine = static_cast<int>(result.errorLine); }
if (errorColumn) { *errorColumn = static_cast<int>(result.errorColumn); }
return false;
#else
return doc.setContent(dev, namespaceProcessing, errorMsg, errorLine, errorColumn);
#endif
}
} // namespace lmms
#endif // LMMS_DEPRECATIONHELPER_H

View File

@@ -48,6 +48,11 @@ public:
*/
static void openDir(const QFileInfo item);
static void openDir(const QString& itemPath)
{
openDir(QFileInfo(itemPath));
}
/**
* @brief Checks whether the file manager supports selecting a specific file.
* @return True if selection is supported, otherwise false.
@@ -60,6 +65,11 @@ public:
*/
static void reveal(const QFileInfo item);
static void reveal(const QString& itemPath)
{
reveal(QFileInfo(itemPath));
}
private:
static bool s_canSelect;

View File

@@ -52,6 +52,11 @@ public:
//! Stop processing and destroys the object.
~FileSearchJob();
FileSearchJob(const FileSearchJob&) = delete;
FileSearchJob(FileSearchJob&&) = delete;
FileSearchJob& operator=(const FileSearchJob&) = delete;
FileSearchJob& operator=(FileSearchJob&&) = delete;
//! Commit to searching with the given @p task.
//! Cancels any previous search.
//! Callers can connect to the provided signals to interact with the search and its progress.
@@ -68,7 +73,6 @@ signals:
void finished();
private:
Q_DISABLE_MOVE(FileSearchJob)
void runSearch(Task task);
std::future<void> m_task;
std::atomic_flag m_stop = ATOMIC_FLAG_INIT;

View File

@@ -81,7 +81,11 @@ protected:
void paintEvent(QPaintEvent * me) override;
void wheelEvent(QWheelEvent * me) override;
void enterEvent(QEvent *event) override;
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void enterEvent(QEnterEvent*) override;
#else
void enterEvent(QEvent*) override;
#endif
void leaveEvent(QEvent *event) override;
virtual float getValue(const QPoint & p);

View File

@@ -49,10 +49,14 @@ public:
MainApplication(int& argc, char** argv);
bool event(QEvent* event) override;
#ifdef LMMS_BUILD_WIN32
bool winEventFilter(MSG* msg, long* result);
bool nativeEventFilter(const QByteArray& eventType, void* message,
long* result);
#endif
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
using FilterResult = long;
#else
using FilterResult = qintptr;
#endif // QT6 check
bool win32EventFilter(MSG* msg, FilterResult* result);
bool nativeEventFilter(const QByteArray& eventType, void* message, FilterResult* result);
#endif // LMMS_BUILD_WIN32
inline QString& queuedFile()
{
return m_queuedFile;

View File

@@ -65,7 +65,11 @@ public:
void openInNewInstrumentTrack(QString value);
protected:
void enterEvent( QEvent * _e ) override;
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void enterEvent(QEnterEvent* event) override;
#else
void enterEvent(QEvent* event) override;
#endif
void leaveEvent( QEvent * _e ) override;
void mousePressEvent( QMouseEvent * _me ) override;
void paintEvent( QPaintEvent * _pe ) override;

View File

@@ -48,7 +48,7 @@ public:
void setActiveTab(int idx);
int findTabAtPos(const QPoint* pos);
int findTabAtPos(const QPoint& pos);
inline int activeTab() const
{

View File

@@ -27,6 +27,7 @@
#define LMMS_BASE64_H
#include <QByteArray>
#include <QMetaType>
#include <QString>
#include <QVariant>
@@ -47,9 +48,10 @@ namespace lmms::base64
*_data = new T[*_size / sizeof(T)];
memcpy( *_data, data.constData(), *_size );
}
// for compatibility-code only
QVariant decode( const QString & _b64,
QVariant::Type _force_type = QVariant::Invalid );
QVariant decode(const QString& b64,
QMetaType::Type forceType = QMetaType::UnknownType);
} // namespace lmms::base64

View File

@@ -58,16 +58,12 @@ auto LMMS_EXPORT getText(std::string_view name) -> QString;
* @param pixmap The pixmap to get the size of.
* @return The device-independent size of the pixmap.
*/
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
[[deprecated("Use QPixmap::deviceIndependentSize() instead; See "
"https://doc.qt.io/qt-6/qpixmap.html#deviceIndependentSize")]]
#endif
inline auto logicalSize(const QPixmap &pixmap) noexcept
inline auto logicalSize(const QPixmap& pixmap) noexcept
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
return pixmap.deviceIndependentSize().toSize();
#else
return pixmap.isNull() ? QSize() : pixmap.size() / pixmap.devicePixelRatio();
return pixmap.isNull() ? QSize(0, 0) : pixmap.size() / pixmap.devicePixelRatio();
#endif
}

View File

@@ -26,9 +26,11 @@
#include "Sample.h"
#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "SampleThumbnail.h"
#include "FontHelper.h"
#include <QPainter>
#include <QMouseEvent>
@@ -114,10 +116,12 @@ void AudioFileProcessorWaveView::leaveEvent(QEvent * e)
void AudioFileProcessorWaveView::mousePressEvent(QMouseEvent * me)
{
m_isDragging = true;
m_draggingLastPoint = me->pos();
const auto pos = position(me);
const int x = me->x();
m_isDragging = true;
m_draggingLastPoint = pos;
const int x = pos.x();
const int start_dist = qAbs(m_startFrameX - x);
const int end_dist = qAbs(m_endFrameX - x);
@@ -155,7 +159,9 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me)
return;
}
const int step = me->x() - m_draggingLastPoint.x();
const auto pos = position(me);
const int step = pos.x() - m_draggingLastPoint.x();
switch(m_draggingType)
{
case DraggingType::SampleStart:
@@ -171,12 +177,12 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me)
slide(step);
break;
case DraggingType::ZoomWave:
zoom(me->y() < m_draggingLastPoint.y());
zoom(pos.y() < m_draggingLastPoint.y());
break;
case DraggingType::Wave:
default:
if (qAbs(me->y() - m_draggingLastPoint.y())
< 2 * qAbs(me->x() - m_draggingLastPoint.x()))
if (qAbs(pos.y() - m_draggingLastPoint.y())
< 2 * qAbs(pos.x() - m_draggingLastPoint.x()))
{
m_draggingType = DraggingType::SlideWave;
}
@@ -186,7 +192,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me)
}
}
m_draggingLastPoint = me->pos();
m_draggingLastPoint = pos;
update();
}
@@ -483,20 +489,30 @@ void AudioFileProcessorWaveView::reverse()
m_reversed = ! m_reversed;
}
void AudioFileProcessorWaveView::updateCursor(QMouseEvent * me)
void AudioFileProcessorWaveView::updateCursor(const QMouseEvent* me)
{
bool const waveIsDragged = m_isDragging && (m_draggingType == DraggingType::Wave);
bool const pointerCloseToStartEndOrLoop = (me != nullptr) &&
(isCloseTo(me->x(), m_startFrameX) ||
isCloseTo(me->x(), m_endFrameX) ||
isCloseTo(me->x(), m_loopFrameX));
if (!m_isDragging && pointerCloseToStartEndOrLoop)
if (!m_isDragging && pointerCloseToStartEndOrLoop(me))
{
setCursor(Qt::SizeHorCursor);
}
else if (waveIsDragged)
{
setCursor(Qt::ClosedHandCursor);
}
else
{
setCursor(Qt::OpenHandCursor);
}
}
bool AudioFileProcessorWaveView::pointerCloseToStartEndOrLoop(const QMouseEvent* me) const
{
if (!me) { return false; }
const QPoint pos = position(me);
return isCloseTo(pos.x(), m_startFrameX) || isCloseTo(pos.x(), m_endFrameX) || isCloseTo(pos.x(), m_loopFrameX);
}
void AudioFileProcessorWaveView::configureKnobRelationsAndWaveViews()

View File

@@ -169,7 +169,8 @@ private:
void updateGraph();
void reverse();
void updateCursor(QMouseEvent* me = nullptr);
void updateCursor(const QMouseEvent* me = nullptr);
bool pointerCloseToStartEndOrLoop(const QMouseEvent* me) const;
void configureKnobRelationsAndWaveViews();

View File

@@ -25,6 +25,7 @@
#include "AutomatableModel.h"
#include "DelayControlsDialog.h"
#include "DelayControls.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "TempoSyncKnob.h"
#include "../Eq/EqFader.h"
@@ -135,18 +136,20 @@ void XyPad::mouseReleaseEvent(QMouseEvent *event)
void XyPad::mouseMoveEvent(QMouseEvent *event)
{
if( m_acceptInput && (event->x() >= 0) && ( event->x() < width() )
&& ( event->y() >= 0) && ( event->y() < height() ) )
const auto pos = position(event);
if (m_acceptInput && (pos.x() >= 0) && (pos.x() < width())
&& (pos.y() >= 0) && (pos.y() < height()))
{
//set xmodel
float xRange = m_xModel->maxValue() - m_xModel->minValue();
float xInc = xRange / width();
m_xModel->setValue( m_xModel->minValue() + ( event->x() * xInc ) );
m_xModel->setValue(m_xModel->minValue() + (pos.x() * xInc));
//set ymodel
float yRange = m_yModel->maxValue() - m_yModel->minValue();
float yInc = yRange / height();
m_yModel->setValue( m_yModel->minValue() + ( event->y() * yInc ) );
m_yModel->setValue(m_yModel->minValue() + (pos.y() * yInc));
}
}

View File

@@ -178,7 +178,7 @@ QWidget * LadspaMatrixControlDialog::createMatrixWidget()
{
QWidget *widget = new QWidget(this);
QGridLayout *gridLayout = new QGridLayout(widget);
gridLayout->setMargin(0);
gridLayout->setContentsMargins(0, 0, 0, 0);
widget->setLayout(gridLayout);
arrangeControls(widget, gridLayout);

View File

@@ -590,7 +590,7 @@ void OpulenzInstrument::loadFile( const QString& file ) {
return;
}
if( sbidata.size() != 52 ) {
printf("SBI size error: expected 52, got %d\n",sbidata.size() );
printf("SBI size error: expected 52, got %d\n", static_cast<int>(sbidata.size()));
}
// Minimum size of SBI if we ignore "reserved" bytes at end

View File

@@ -29,6 +29,7 @@
#include <QPainter>
#include <QPainterPath>
#include "DeprecationHelper.h"
#include "SampleThumbnail.h"
#include "SlicerT.h"
#include "SlicerTView.h"
@@ -297,13 +298,15 @@ void SlicerTWaveform::updateUI()
// updates the closest object and changes the cursor respectivly
void SlicerTWaveform::updateClosest(QMouseEvent* me)
{
float normalizedClickSeeker = static_cast<float>(me->x() - s_seekerHorMargin) / m_seekerWidth;
float normalizedClickEditor = static_cast<float>(me->x()) / m_editorWidth;
const auto pos = position(me);
float normalizedClickSeeker = static_cast<float>(pos.x() - s_seekerHorMargin) / m_seekerWidth;
float normalizedClickEditor = static_cast<float>(pos.x()) / m_editorWidth;
m_closestObject = UIObjects::Nothing;
m_closestSlice = -1;
if (me->y() < m_seekerHeight)
if (pos.y() < m_seekerHeight)
{
if (std::abs(normalizedClickSeeker - m_seekerStart) < s_distanceForClick)
{
@@ -358,6 +361,8 @@ void SlicerTWaveform::updateCursor()
// handles deletion, reset and middles seeker
void SlicerTWaveform::mousePressEvent(QMouseEvent* me)
{
const auto pos = position(me);
switch (me->button())
{
case Qt::MouseButton::MiddleButton:
@@ -369,7 +374,7 @@ void SlicerTWaveform::mousePressEvent(QMouseEvent* me)
case Qt::MouseButton::LeftButton:
if (m_slicerTParent->m_originalSample.sampleSize() <= 1) { static_cast<SlicerTView*>(parent())->openFiles(); }
// update seeker middle for correct movement
m_seekerMiddle = static_cast<float>(me->x() - s_seekerHorMargin) / m_seekerWidth;
m_seekerMiddle = static_cast<float>(pos.x() - s_seekerHorMargin) / m_seekerWidth;
break;
case Qt::MouseButton::RightButton:
if (m_slicerTParent->m_slicePoints.size() > 2 && m_closestObject == UIObjects::SlicePoint)
@@ -400,8 +405,10 @@ void SlicerTWaveform::mouseMoveEvent(QMouseEvent* me)
return;
}
float normalizedClickSeeker = static_cast<float>(me->x() - s_seekerHorMargin) / m_seekerWidth;
float normalizedClickEditor = static_cast<float>(me->x()) / m_editorWidth;
const auto pos = position(me);
float normalizedClickSeeker = static_cast<float>(pos.x() - s_seekerHorMargin) / m_seekerWidth;
float normalizedClickEditor = static_cast<float>(pos.x()) / m_editorWidth;
float distStart = m_seekerStart - m_seekerMiddle;
float distEnd = m_seekerEnd - m_seekerMiddle;
@@ -449,9 +456,11 @@ void SlicerTWaveform::mouseMoveEvent(QMouseEvent* me)
void SlicerTWaveform::mouseDoubleClickEvent(QMouseEvent* me)
{
if (me->button() != Qt::MouseButton::LeftButton || me->y() < m_seekerHeight) { return; }
const auto pos = position(me);
float normalizedClickEditor = static_cast<float>(me->x()) / m_editorWidth;
if (me->button() != Qt::MouseButton::LeftButton || pos.y() < m_seekerHeight) { return; }
float normalizedClickEditor = static_cast<float>(pos.x()) / m_editorWidth;
float startFrame = m_seekerStart;
float endFrame = m_seekerEnd;
float slicePosition = startFrame + normalizedClickEditor * (endFrame - startFrame);

View File

@@ -33,6 +33,7 @@
#include <QPainterPath>
#include <QString>
#include "DeprecationHelper.h"
#include "fft_helpers.h"
#include "GuiApplication.h"
#include "MainWindow.h"
@@ -819,18 +820,14 @@ void SaSpectrumView::periodicUpdate()
// Handle mouse input: set new cursor position.
// For some reason (a bug?), localPos() only returns integers. As a workaround
// the fractional part is taken from windowPos() (which works correctly).
void SaSpectrumView::mouseMoveEvent(QMouseEvent *event)
void SaSpectrumView::mouseMoveEvent(QMouseEvent* event)
{
m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()),
event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y()));
m_cursor = positionF(event);
}
void SaSpectrumView::mousePressEvent(QMouseEvent *event)
void SaSpectrumView::mousePressEvent(QMouseEvent* event)
{
m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()),
event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y()));
m_cursor = positionF(event);
}

View File

@@ -33,6 +33,7 @@
#include <QPainter>
#include <QString>
#include "DeprecationHelper.h"
#include "EffectControlDialog.h"
#include "GuiApplication.h"
#include "MainWindow.h"
@@ -324,18 +325,14 @@ void SaWaterfallView::drawCursor(QPainter &painter)
// Handle mouse input: set new cursor position.
// For some reason (a bug?), localPos() only returns integers. As a workaround
// the fractional part is taken from windowPos() (which works correctly).
void SaWaterfallView::mouseMoveEvent(QMouseEvent *event)
void SaWaterfallView::mouseMoveEvent(QMouseEvent* event)
{
m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()),
event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y()));
m_cursor = positionF(event);
}
void SaWaterfallView::mousePressEvent(QMouseEvent *event)
void SaWaterfallView::mousePressEvent(QMouseEvent* event)
{
m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()),
event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y()));
m_cursor = positionF(event);
}

View File

@@ -34,7 +34,7 @@
#include <QLocale>
#include <QTemporaryFile>
#ifdef LMMS_BUILD_LINUX
#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0))
# include <QX11Info>
# include <X11EmbedContainer.h>
#endif
@@ -415,7 +415,7 @@ bool VstPlugin::processMessage( const message & _m )
(LONG_PTR) gui::getGUI()->mainWindow()->winId() );
#endif
#ifdef LMMS_BUILD_LINUX
#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0))
XSetTransientForHint( QX11Info::display(),
m_pluginWindowID,
gui::getGUI()->mainWindow()->winId() );
@@ -772,7 +772,7 @@ void VstPlugin::createUI( QWidget * parent )
} else
#endif
#ifdef LMMS_BUILD_LINUX
#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0))
if (m_embedMethod == "xembed" )
{
if (parent)

View File

@@ -15,6 +15,6 @@ TARGET_INCLUDE_DIRECTORIES(vstbase
PUBLIC ../
)
IF(LMMS_BUILD_LINUX)
IF(LMMS_BUILD_LINUX AND NOT WANT_QT6)
TARGET_LINK_LIBRARIES(vstbase qx11embedcontainer)
ENDIF()

View File

@@ -23,8 +23,13 @@ if(NOT MSVC AND (LMMS_HOST_X86 OR LMMS_HOST_X86_64))
ADD_DEFINITIONS(-DASM_F2I_YES)
endif()
# build ZynAddSubFX with full optimizations
if(NOT MSVC)
if(MSVC)
# enable updated C++ language standards, disable certain permissive behavior
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus /permissive-")
# workaround _WIN32 vs WIN32 differences
add_compile_definitions(WIN32)
else()
# build ZynAddSubFX with full optimizations, treat nonconformant code as warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fpermissive")
endif()
@@ -126,8 +131,8 @@ target_static_libraries(ZynAddSubFxCore PUBLIC
target_link_libraries(ZynAddSubFxCore INTERFACE
${FFTW3F_LIBRARIES}
${QT_LIBRARIES}
Qt5::Widgets
Qt5::Xml
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Xml
Threads::Threads
ZLIB::ZLIB
)
@@ -192,7 +197,7 @@ if(LMMS_HAVE_LIBRT)
endif()
# Support qt_version_tag in Qt 5.6
TARGET_LINK_LIBRARIES(RemoteZynAddSubFx Qt5::Core)
TARGET_LINK_LIBRARIES(RemoteZynAddSubFx Qt${QT_VERSION_MAJOR}::Core)
# link Qt libraries when on win32
IF(LMMS_BUILD_WIN32)

View File

@@ -1,6 +1,6 @@
set_directory_properties(PROPERTIES SYSTEM TRUE)
if(LMMS_BUILD_LINUX AND LMMS_HAVE_VST)
if(LMMS_BUILD_LINUX AND LMMS_HAVE_VST AND NOT WANT_QT6)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(qt5-x11embed)
ENDIF()

View File

@@ -35,6 +35,12 @@ ADD_SUBDIRECTORY(tracks)
LIST(APPEND LMMS_SRCS ${LMMS_COMMON_SRCS})
IF(WANT_QT6)
QT6_WRAP_UI(LMMS_UI_OUT ${LMMS_UIS})
ELSE()
QT5_WRAP_UI(LMMS_UI_OUT ${LMMS_UIS})
ENDIF()
INCLUDE_DIRECTORIES(
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_BINARY_DIR}"
@@ -114,6 +120,11 @@ TARGET_INCLUDE_DIRECTORIES(lmms
)
target_static_libraries(lmms PUBLIC lmmsobjs)
# Enable updated C++ language standards
IF(MSVC)
TARGET_COMPILE_OPTIONS(lmmsobjs PUBLIC "/Zc:__cplusplus" "/permissive-")
ENDIF()
# CMake doesn't define target_EXPORTS for OBJECT libraries.
# See the documentation of DEFINE_SYMBOL for details.
# Also add LMMS_STATIC_DEFINE for targets linking against it.

View File

@@ -186,7 +186,7 @@ TimePos AutomationClip::timeMapLength() const
if (m_timeMap.isEmpty()) { return one_bar; }
timeMap::const_iterator it = m_timeMap.end();
auto last_tick = static_cast<tick_t>(POS(it - 1));
auto last_tick = static_cast<tick_t>(POS(std::prev(it)));
// if last_tick is 0 (single item at tick 0)
// return length as a whole bar to prevent disappearing Clip
if (last_tick == 0) { return one_bar; }
@@ -582,13 +582,16 @@ float AutomationClip::valueAt( const TimePos & _time ) const
{
return 0;
}
const auto pv = std::prev(v);
if( v == m_timeMap.end() )
{
// When the time is after the last node, we want the outValue of it
return OUTVAL(v - 1);
return OUTVAL(pv);
}
return valueAt(v - 1, _time - POS(v - 1));
return valueAt(pv, _time - POS(pv));
}
@@ -610,9 +613,10 @@ float AutomationClip::valueAt( timeMap::const_iterator v, int offset ) const
}
else if( m_progressionType == ProgressionType::Linear )
{
auto const nv = std::next(v);
float slope =
(INVAL(v + 1) - OUTVAL(v))
/ (POS(v + 1) - POS(v));
(INVAL(nv) - OUTVAL(v))
/ (POS(nv) - POS(v));
return OUTVAL(v) + offset * slope;
}
@@ -626,15 +630,17 @@ float AutomationClip::valueAt( timeMap::const_iterator v, int offset ) const
// value: y. To make this work we map the values of x that this
// segment spans to values of t for t = 0.0 -> 1.0 and scale the
// tangents _m1 and _m2
int numValues = (POS(v + 1) - POS(v));
auto const nv = std::next(v);
int numValues = (POS(nv) - POS(v));
float t = (float) offset / (float) numValues;
float m1 = OUTTAN(v) * numValues * m_tension;
float m2 = INTAN(v + 1) * numValues * m_tension;
float m2 = INTAN(nv) * numValues * m_tension;
auto t2 = t * t, t3 = t2 * t;
return (2 * t3 - 3 * t2 + 1) * OUTVAL(v)
+ (t3 - 2 * t2 + t) * m1
+ (-2 * t3 + 3 * t2) * INVAL(v + 1)
+ (-2 * t3 + 3 * t2) * INVAL(nv)
+ (t3 - t2) * m2;
}
}
@@ -647,12 +653,14 @@ float *AutomationClip::valuesAfter( const TimePos & _time ) const
QMutexLocker m(&m_clipMutex);
timeMap::const_iterator v = m_timeMap.lowerBound(_time);
if( v == m_timeMap.end() || (v+1) == m_timeMap.end() )
auto const nv = std::next(v);
if (v == m_timeMap.end() || nv == m_timeMap.end())
{
return nullptr;
}
int numValues = POS(v + 1) - POS(v);
int numValues = POS(nv) - POS(v);
auto ret = new float[numValues];
for( int i = 0; i < numValues; i++ )
@@ -1156,7 +1164,9 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate)
continue;
}
if (it + 1 == m_timeMap.end())
auto const nit = std::next(it);
if (nit == m_timeMap.end())
{
// Previously, the last value's tangent was always set to 0. That logic was kept for both tangents
// of the last node
@@ -1167,7 +1177,7 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate)
{
// On the first node there's no curve behind it, so we will only calculate the outTangent
// and inTangent will be set to 0.
float tangent = (INVAL(it + 1) - OUTVAL(it)) / (POS(it + 1) - POS(it));
float tangent = (INVAL(nit) - OUTVAL(it)) / (POS(nit) - POS(it));
it.value().setInTangent(0);
it.value().setOutTangent(tangent);
}
@@ -1180,9 +1190,12 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate)
// TODO: This behavior means that a very small difference between the inValue and outValue can
// result in a big change in the curve. In the future, allowing the user to manually adjust
// the tangents would be better.
auto const pit = std::prev(it);
if (OFFSET(it) == 0)
{
float inTangent = (INVAL(it + 1) - OUTVAL(it - 1)) / (POS(it + 1) - POS(it - 1));
float inTangent = (INVAL(nit) - OUTVAL(pit)) / (POS(nit) - POS(pit));
it.value().setInTangent(inTangent);
// inTangent == outTangent in this case
it.value().setOutTangent(inTangent);
@@ -1190,9 +1203,9 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate)
else
{
// Calculate the left side of the curve
float inTangent = (INVAL(it) - OUTVAL(it - 1)) / (POS(it) - POS(it - 1));
float inTangent = (INVAL(it) - OUTVAL(pit)) / (POS(it) - POS(pit));
// Calculate the right side of the curve
float outTangent = (INVAL(it + 1) - OUTVAL(it)) / (POS(it + 1) - POS(it));
float outTangent = (INVAL(nit) - OUTVAL(it)) / (POS(nit) - POS(it));
it.value().setInTangent(inTangent);
it.value().setOutTangent(outTangent);
}

View File

@@ -24,7 +24,6 @@
#include "ConfigManager.h"
#include <PathUtil.h>
#include <QApplication>
#include <QDir>
#include <QDomElement>
@@ -32,8 +31,10 @@
#include <QStandardPaths>
#include <QTextStream>
#include "DeprecationHelper.h"
#include "GuiApplication.h"
#include "MainWindow.h"
#include "PathUtil.h"
#include "ProjectVersion.h"
#include "lmmsversion.h"
@@ -202,7 +203,7 @@ QStringList ConfigManager::availableVstEmbedMethods()
#ifdef LMMS_BUILD_WIN32
methods.append("win32");
#endif
#ifdef LMMS_BUILD_LINUX
#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0))
if (static_cast<QGuiApplication*>(QApplication::instance())->
platformName() == "xcb")
{
@@ -429,7 +430,7 @@ void ConfigManager::loadConfigFile(const QString & configFile)
{
QString errorString;
int errorLine, errorCol;
if(dom_tree.setContent(&cfg_file, false, &errorString, &errorLine, &errorCol))
if (lmms::setContent(dom_tree, &cfg_file, false, &errorString, &errorLine, &errorCol))
{
// get the head information from the DOM
QDomElement root = dom_tree.documentElement();

View File

@@ -40,6 +40,7 @@
#include "base64.h"
#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "Effect.h"
#include "embed.h"
#include "GuiApplication.h"
@@ -1027,19 +1028,19 @@ void DataFile::upgrade_0_4_0_beta1()
if( !k.isEmpty() )
{
const QList<QVariant> l =
base64::decode( k, QVariant::List ).toList();
base64::decode(k, QMetaType::QVariantList).toList();
if( !l.isEmpty() )
{
QString name = l[0].toString();
QVariant u = l[1];
EffectKey::AttributeMap m;
// VST-effect?
if( u.type() == QVariant::String )
if (typeId(u) == QMetaType::QString)
{
m["file"] = u.toString();
}
// LADSPA-effect?
else if( u.type() == QVariant::StringList )
else if (typeId(u) == QMetaType::QStringList)
{
const QStringList sl = u.toStringList();
m["plugin"] = sl.value( 0 );
@@ -2124,13 +2125,13 @@ void DataFile::loadData( const QByteArray & _data, const QString & _sourceFile )
{
QString errorMsg;
int line = -1, col = -1;
if( !setContent( _data, &errorMsg, &line, &col ) )
if (!lmms::setContent(*this, _data, &errorMsg, &line, &col))
{
// parsing failed? then try to uncompress data
QByteArray uncompressed = qUncompress( _data );
if( !uncompressed.isEmpty() )
{
if( setContent( uncompressed, &errorMsg, &line, &col ) )
if (lmms::setContent(*this, uncompressed, &errorMsg, &line, &col))
{
line = col = -1;
}

View File

@@ -489,9 +489,9 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
}
else
{
const auto octaveDiv = std::div(cur_arp_idx, total_chord_size);
const auto octaveDiv = std::div(cur_arp_idx, static_cast<int>(total_chord_size));
const int octave = octaveDiv.quot;
const auto arpDiv = std::div(octaveDiv.rem, cnphv.size());
const auto arpDiv = std::div(octaveDiv.rem, static_cast<int>(cnphv.size()));
const int arpIndex = arpDiv.rem;
const int chordIndex = arpDiv.quot;
sub_note_key = cnphv[arpIndex]->key()

View File

@@ -28,22 +28,24 @@
#include <QBuffer>
#include <QDataStream>
#include "DeprecationHelper.h"
namespace lmms::base64
{
QVariant decode( const QString & _b64, QVariant::Type _force_type )
QVariant decode(const QString& b64, QMetaType::Type forceType)
{
char * dst = nullptr;
int dsize = 0;
base64::decode( _b64, &dst, &dsize );
base64::decode(b64, &dst, &dsize);
QByteArray ba( dst, dsize );
QBuffer buf( &ba );
buf.open( QBuffer::ReadOnly );
QDataStream in( &buf );
QVariant ret;
in >> ret;
if( _force_type != QVariant::Invalid && ret.type() != _force_type )
if (forceType != QMetaType::UnknownType && typeId(ret) != forceType)
{
buf.reset();
in.setVersion( QDataStream::Qt_3_3 );

View File

@@ -360,7 +360,12 @@ int main( int argc, char * * argv )
return EXIT_FAILURE;
}
#endif
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
// High-DPI scaling is always enabled in Qt >= 6.0
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QCoreApplication * app = coreOnly ?
new QCoreApplication( argc, argv ) :
new gui::MainApplication(argc, argv);

View File

@@ -275,15 +275,15 @@ void MidiWinMM::openDevices()
m_inputDevices.clear();
for( unsigned int i = 0; i < midiInGetNumDevs(); ++i )
{
MIDIINCAPS c;
midiInGetDevCaps( i, &c, sizeof( c ) );
MIDIINCAPSW c;
midiInGetDevCapsW(i, &c, sizeof(c));
HMIDIIN hm = 0;
MMRESULT res = midiInOpen( &hm, i, (DWORD_PTR) &inputCallback,
(DWORD_PTR) this,
CALLBACK_FUNCTION );
if( res == MMSYSERR_NOERROR )
{
m_inputDevices[hm] = qstrdup( c.szPname );
m_inputDevices[hm] = QString::fromWCharArray(c.szPname);
midiInStart( hm );
}
}
@@ -291,13 +291,13 @@ void MidiWinMM::openDevices()
m_outputDevices.clear();
for( unsigned int i = 0; i < midiOutGetNumDevs(); ++i )
{
MIDIOUTCAPS c;
midiOutGetDevCaps( i, &c, sizeof( c ) );
MIDIOUTCAPSW c;
midiOutGetDevCapsW(i, &c, sizeof(c));
HMIDIOUT hm = 0;
MMRESULT res = midiOutOpen( &hm, i, 0, 0, CALLBACK_NULL );
if( res == MMSYSERR_NOERROR )
{
m_outputDevices[hm] = qstrdup( c.szPname );
m_outputDevices[hm] = QString::fromWCharArray(c.szPname);
}
}
}

View File

@@ -141,7 +141,7 @@ int ControlLayout::count() const
return m_itemMap.size() - 1;
}
QMap<QString, QLayoutItem*>::const_iterator
ControlLayout::ControlLayoutMap::const_iterator
ControlLayout::pairAt(int index) const
{
if (index < 0) { return m_itemMap.cend(); }
@@ -151,7 +151,7 @@ ControlLayout::pairAt(int index) const
return item->widget()->objectName() == s_searchBarName;
};
QMap<QString, QLayoutItem*>::const_iterator itr = m_itemMap.cbegin();
auto itr = m_itemMap.cbegin();
for (; itr != m_itemMap.cend() && (index > 0 || skip(itr.value())); ++itr)
{
if(!skip(itr.value())) { index--; }
@@ -242,10 +242,8 @@ int ControlLayout::doLayout(const QRect &rect, bool testOnly) const
const QString filterText = m_searchBar->text();
bool first = true;
QMapIterator<QString, QLayoutItem*> itr(m_itemMap);
while (itr.hasNext())
for (auto itr = m_itemMap.cbegin(); itr != m_itemMap.cend(); ++itr)
{
itr.next();
QLayoutItem* item = itr.value();
QWidget *wid = item->widget();
if (wid)

View File

@@ -169,13 +169,13 @@ void ControllerRackView::addController(Controller* controller)
connect(controllerView, &ControllerView::removedController, this, &ControllerRackView::deleteController, Qt::QueuedConnection);
auto moveUpAction = new QAction(controllerView);
moveUpAction->setShortcut(combine(Qt::Key_Up, Qt::AltModifier));
moveUpAction->setShortcut(keySequence(Qt::Key_Up, Qt::AltModifier));
moveUpAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveUpAction, &QAction::triggered, controllerView, &ControllerView::moveUp);
controllerView->addAction(moveUpAction);
auto moveDownAction = new QAction(controllerView);
moveDownAction->setShortcut(combine(Qt::Key_Down, Qt::AltModifier));
moveDownAction->setShortcut(keySequence(Qt::Key_Down, Qt::AltModifier));
moveDownAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveDownAction, &QAction::triggered, controllerView, &ControllerView::moveDown);
controllerView->addAction(moveDownAction);

View File

@@ -179,13 +179,13 @@ void EffectRackView::update()
connect(view, &EffectView::deletedPlugin, this, &EffectRackView::deletePlugin, Qt::QueuedConnection);
QAction* moveUpAction = new QAction(view);
moveUpAction->setShortcut(combine(Qt::Key_Up, Qt::AltModifier));
moveUpAction->setShortcut(keySequence(Qt::Key_Up, Qt::AltModifier));
moveUpAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveUpAction, &QAction::triggered, view, &EffectView::moveUp);
view->addAction(moveUpAction);
QAction* moveDownAction = new QAction(view);
moveDownAction->setShortcut(combine(Qt::Key_Down, Qt::AltModifier));
moveDownAction->setShortcut(keySequence(Qt::Key_Down, Qt::AltModifier));
moveDownAction->setShortcutContext(Qt::WidgetShortcut);
connect(moveDownAction, &QAction::triggered, view, &EffectView::moveDown);
view->addAction(moveDownAction);

View File

@@ -43,6 +43,7 @@
#include "AudioEngine.h"
#include "ConfigManager.h"
#include "DataFile.h"
#include "DeprecationHelper.h"
#include "Engine.h"
#include "FileBrowser.h"
#include "FileRevealer.h"
@@ -177,7 +178,13 @@ void FileBrowser::addContentCheckBox()
auto configCheckBox = [this](QBoxLayout* boxLayout, QCheckBox* box, Qt::CheckState checkState)
{
box->setCheckState(checkState);
connect(box, SIGNAL(stateChanged(int)), this, SLOT(reloadTree()));
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
connect(box, &QCheckBox::checkStateChanged, this, &FileBrowser::reloadTree);
#else
connect(box, &QCheckBox::stateChanged, this, &FileBrowser::reloadTree);
#endif
boxLayout->addWidget(box);
};
@@ -721,8 +728,10 @@ QList<QAction*> FileBrowserTreeWidget::getContextActions(FileItem* file, bool so
void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me )
{
const auto pos = position(me);
// Forward the event
QTreeWidgetItem * i = itemAt(me->pos());
QTreeWidgetItem* i = itemAt(pos);
QTreeWidget::mousePressEvent(me);
// QTreeWidget handles right clicks for us, so we only care about left clicks
if(me->button() != Qt::LeftButton) { return; }
@@ -730,13 +739,13 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me )
if (i)
{
// TODO: Restrict to visible selection
// if ( _me->x() > header()->cellPos( header()->mapToActual( 0 ) )
// if ( pos.x() > header()->cellPos( header()->mapToActual( 0 ) )
// + treeStepSize() * ( i->depth() + ( rootIsDecorated() ?
// 1 : 0 ) ) + itemMargin() ||
// _me->x() < header()->cellPos(
// pos.x() < header()->cellPos(
// header()->mapToActual( 0 ) ) )
// {
m_pressPos = me->pos();
m_pressPos = pos;
m_mousePressed = true;
// }
}
@@ -830,9 +839,7 @@ void FileBrowserTreeWidget::stopPreview()
void FileBrowserTreeWidget::mouseMoveEvent( QMouseEvent * me )
{
if( m_mousePressed == true &&
( m_pressPos - me->pos() ).manhattanLength() >
QApplication::startDragDistance() )
if (m_mousePressed && (m_pressPos - position(me)).manhattanLength() > QApplication::startDragDistance())
{
// make sure any playback is stopped
mouseReleaseEvent( nullptr );

View File

@@ -308,9 +308,9 @@ void GuiApplication::sigintOccurred()
*/
QFont GuiApplication::getWin32SystemFont()
{
NONCLIENTMETRICS metrics = { sizeof( NONCLIENTMETRICS ) };
SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( NONCLIENTMETRICS ), &metrics, 0 );
int pointSize = metrics.lfMessageFont.lfHeight;
auto metrics = NONCLIENTMETRICSW{ .cbSize = sizeof(NONCLIENTMETRICSW) };
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &metrics, 0);
int pointSize = static_cast<int>(metrics.lfMessageFont.lfHeight);
if ( pointSize < 0 )
{
// height is in pixels, convert to points
@@ -319,7 +319,7 @@ QFont GuiApplication::getWin32SystemFont()
ReleaseDC( nullptr, hDC );
}
return QFont( QString::fromUtf8( metrics.lfMessageFont.lfFaceName ), pointSize );
return QFont{QString::fromWCharArray(metrics.lfMessageFont.lfFaceName), pointSize};
}
#endif

View File

@@ -86,8 +86,8 @@ bool MainApplication::event(QEvent* event)
}
#ifdef LMMS_BUILD_WIN32
// This can be moved into nativeEventFilter once Qt4 support has been dropped
bool MainApplication::winEventFilter(MSG* msg, long* result)
// Helper function for nativeEventFilter
bool MainApplication::win32EventFilter(MSG* msg, FilterResult* result)
{
switch(msg->message)
{
@@ -110,11 +110,11 @@ bool MainApplication::winEventFilter(MSG* msg, long* result)
}
bool MainApplication::nativeEventFilter(const QByteArray& eventType,
void* message, long* result)
void* message, FilterResult* result)
{
if(eventType == "windows_generic_MSG")
{
return winEventFilter(static_cast<MSG *>(message), result);
return win32EventFilter(static_cast<MSG*>(message), result);
}
return false;
}

View File

@@ -264,87 +264,79 @@ void MainWindow::finalize()
resetWindowTitle();
setWindowIcon( embed::getIconPixmap( "icon_small" ) );
auto addAction = [this](QMenu* menu, std::string_view icon, const QString& text,
const QKeySequence& shortcut, auto(MainWindow::* slot)()) -> QAction*
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
return menu->addAction(embed::getIconPixmap(icon), text, shortcut, this, slot);
#else
return menu->addAction(embed::getIconPixmap(icon), text, this, slot, shortcut);
#endif
};
// project-popup-menu
auto project_menu = new QMenu(this);
menuBar()->addMenu( project_menu )->setText( tr( "&File" ) );
project_menu->addAction( embed::getIconPixmap( "project_new" ),
tr( "&New" ),
this, SLOT(createNewProject()),
QKeySequence::New );
addAction(project_menu, "project_new", tr("&New"),
QKeySequence::New, &MainWindow::createNewProject);
auto templates_menu = new TemplatesMenu( this );
project_menu->addMenu(templates_menu);
project_menu->addAction( embed::getIconPixmap( "project_open" ),
tr( "&Open..." ),
this, SLOT(openProject()),
QKeySequence::Open );
addAction(project_menu, "project_open", tr("&Open..."),
QKeySequence::Open, &MainWindow::openProject);
project_menu->addMenu(new RecentProjectsMenu(this));
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "&Save" ),
this, SLOT(saveProject()),
QKeySequence::Save );
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "Save &As..." ),
this, SLOT(saveProjectAs()),
combine(Qt::CTRL, Qt::SHIFT, Qt::Key_S));
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "Save as New &Version" ),
this, SLOT(saveProjectAsNewVersion()),
combine(Qt::CTRL, Qt::ALT, Qt::Key_S));
addAction(project_menu, "project_save", tr("&Save"),
QKeySequence::Save, &MainWindow::saveProject);
project_menu->addAction( embed::getIconPixmap( "project_save" ),
tr( "Save as default template" ),
this, SLOT(saveProjectAsDefaultTemplate()));
addAction(project_menu, "project_save", tr("Save &As..."),
keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_S), &MainWindow::saveProjectAs);
addAction(project_menu, "project_save", tr("Save as New &Version"),
keySequence(Qt::CTRL, Qt::ALT, Qt::Key_S), &MainWindow::saveProjectAsNewVersion);
project_menu->addAction(embed::getIconPixmap("project_save"), tr("Save as default template"),
this, &MainWindow::saveProjectAsDefaultTemplate);
project_menu->addSeparator();
project_menu->addAction( embed::getIconPixmap( "project_import" ),
tr( "Import..." ),
this,
SLOT(onImportProject()));
project_menu->addAction( embed::getIconPixmap( "project_export" ),
tr( "E&xport..." ),
this,
SLOT(onExportProject()),
combine(Qt::CTRL, Qt::Key_E));
project_menu->addAction( embed::getIconPixmap( "project_export" ),
tr("Export &Tracks..."),
this,
SLOT(onExportProjectTracks()),
combine(Qt::CTRL, Qt::SHIFT, Qt::Key_E));
project_menu->addAction( embed::getIconPixmap( "midi_file" ),
tr( "Export &MIDI..." ),
this,
SLOT(onExportProjectMidi()),
combine(Qt::CTRL, Qt::Key_M));
project_menu->addAction(embed::getIconPixmap("project_import"), tr("Import..."),
this, &MainWindow::onImportProject);
addAction(project_menu, "project_export", tr("E&xport..."),
keySequence(Qt::CTRL, Qt::Key_E), &MainWindow::onExportProject);
addAction(project_menu, "project_export", tr("Export &Tracks..."),
keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_E), &MainWindow::onExportProjectTracks);
addAction(project_menu, "midi_file", tr("Export &MIDI..."),
keySequence(Qt::CTRL, Qt::Key_M), &MainWindow::onExportProjectMidi);
project_menu->addSeparator();
project_menu->addAction( embed::getIconPixmap( "exit" ), tr( "&Quit" ),
qApp, SLOT(closeAllWindows()),
combine(Qt::CTRL, Qt::Key_Q));
project_menu->addAction(embed::getIconPixmap("exit"), tr("&Quit"),
qApp, SLOT(closeAllWindows()))->setShortcut(keySequence(Qt::CTRL, Qt::Key_Q));
auto edit_menu = new QMenu(this);
menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) );
m_undoAction = edit_menu->addAction( embed::getIconPixmap( "edit_undo" ),
tr( "Undo" ),
this, SLOT(undo()),
QKeySequence::Undo );
m_redoAction = edit_menu->addAction( embed::getIconPixmap( "edit_redo" ),
tr( "Redo" ),
this, SLOT(redo()),
QKeySequence::Redo );
m_undoAction = addAction(edit_menu, "edit_undo", tr("Undo"),
QKeySequence::Undo, &MainWindow::undo);
m_redoAction = addAction(edit_menu, "edit_redo", tr("Redo"),
QKeySequence::Redo, &MainWindow::redo);
// Ensure that both (Ctrl+Y) and (Ctrl+Shift+Z) activate redo shortcut regardless of OS defaults
if (QKeySequence(QKeySequence::Redo) != QKeySequence(combine(Qt::CTRL, Qt::Key_Y)))
if (QKeySequence(QKeySequence::Redo) != keySequence(Qt::CTRL, Qt::Key_Y))
{
new QShortcut(QKeySequence(combine(Qt::CTRL, Qt::Key_Y)), this, SLOT(redo()));
new QShortcut(keySequence(Qt::CTRL, Qt::Key_Y), this, SLOT(redo()));
}
if (QKeySequence(QKeySequence::Redo) != QKeySequence(combine(Qt::CTRL, Qt::SHIFT, Qt::Key_Z)))
if (QKeySequence(QKeySequence::Redo) != keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_Z))
{
new QShortcut(QKeySequence(combine(Qt::CTRL, Qt::SHIFT, Qt::Key_Z)), this, SLOT(redo()));
new QShortcut(keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_Z), this, SLOT(redo()));
}
edit_menu->addSeparator();
@@ -443,31 +435,31 @@ void MainWindow::finalize()
// window-toolbar
auto song_editor_window = new ToolButton(embed::getIconPixmap("songeditor"), tr("Song Editor") + " (Ctrl+1)", this,
SLOT(toggleSongEditorWin()), m_toolBar);
song_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_1));
song_editor_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_1));
auto pattern_editor_window = new ToolButton(embed::getIconPixmap("pattern_track_btn"),
tr("Pattern Editor") + " (Ctrl+2)", this, SLOT(togglePatternEditorWin()), m_toolBar);
pattern_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_2));
pattern_editor_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_2));
auto piano_roll_window = new ToolButton(
embed::getIconPixmap("piano"), tr("Piano Roll") + " (Ctrl+3)", this, SLOT(togglePianoRollWin()), m_toolBar);
piano_roll_window->setShortcut(combine(Qt::CTRL, Qt::Key_3));
piano_roll_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_3));
auto automation_editor_window = new ToolButton(embed::getIconPixmap("automation"),
tr("Automation Editor") + " (Ctrl+4)", this, SLOT(toggleAutomationEditorWin()), m_toolBar);
automation_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_4));
automation_editor_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_4));
auto mixer_window = new ToolButton(
embed::getIconPixmap("mixer"), tr("Mixer") + " (Ctrl+5)", this, SLOT(toggleMixerWin()), m_toolBar);
mixer_window->setShortcut(combine(Qt::CTRL, Qt::Key_5));
mixer_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_5));
auto controllers_window = new ToolButton(embed::getIconPixmap("controller"),
tr("Show/hide controller rack") + " (Ctrl+6)", this, SLOT(toggleControllerRack()), m_toolBar);
controllers_window->setShortcut(combine(Qt::CTRL, Qt::Key_6));
controllers_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_6));
auto project_notes_window = new ToolButton(embed::getIconPixmap("project_notes"),
tr("Show/hide project notes") + " (Ctrl+7)", this, SLOT(toggleProjectNotesWin()), m_toolBar);
project_notes_window->setShortcut(combine(Qt::CTRL, Qt::Key_7));
project_notes_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_7));
m_toolBarLayout->addWidget( song_editor_window, 1, 1 );
m_toolBarLayout->addWidget( pattern_editor_window, 1, 2 );
@@ -620,15 +612,19 @@ bool MainWindow::mayChangeProject(bool stopPlayback)
"last saving. Do you want to save it "
"now?" );
QMessageBox mb( ( getSession() == SessionState::Recover ?
messageTitleRecovered : messageTitleUnsaved ),
( getSession() == SessionState::Recover ?
messageRecovered : messageUnsaved ),
QMessageBox::Question,
QMessageBox::Save,
QMessageBox::Discard,
QMessageBox::Cancel,
this );
const auto& title = getSession() == SessionState::Recover
? messageTitleRecovered
: messageTitleUnsaved;
const auto& text = getSession() == SessionState::Recover
? messageRecovered
: messageUnsaved;
const auto buttons = QMessageBox::Save
| QMessageBox::Discard
| QMessageBox::Cancel;
auto mb = QMessageBox{QMessageBox::Question, title, text, buttons, this};
int answer = mb.exec();
if( answer == QMessageBox::Save )
@@ -1607,8 +1603,9 @@ MainWindow::MovableQMdiArea::MovableQMdiArea(QWidget* parent) :
void MainWindow::MovableQMdiArea::mousePressEvent(QMouseEvent* event)
{
m_lastX = event->x();
m_lastY = event->y();
const auto pos = position(event);
m_lastX = pos.x();
m_lastY = pos.y();
m_isBeingMoved = true;
setCursor(Qt::ClosedHandCursor);
}
@@ -1639,8 +1636,9 @@ void MainWindow::MovableQMdiArea::mouseMoveEvent(QMouseEvent* event)
}
}
int scrollX = m_lastX - event->x();
int scrollY = m_lastY - event->y();
const auto pos = position(event);
int scrollX = m_lastX - pos.x();
int scrollY = m_lastY - pos.y();
scrollX = scrollX < 0 && minX >= minXBoundary ? 0 : scrollX;
scrollX = scrollX > 0 && maxX <= maxXBoundary ? 0 : scrollX;
@@ -1657,8 +1655,8 @@ void MainWindow::MovableQMdiArea::mouseMoveEvent(QMouseEvent* event)
}
}
m_lastX = event->x();
m_lastY = event->y();
m_lastX = pos.x();
m_lastY = pos.y();
}
void MainWindow::MovableQMdiArea::mouseReleaseEvent(QMouseEvent* event)

View File

@@ -343,10 +343,16 @@ bool MixerChannelView::confirmRemoval(int index)
QString messageTitleRemoveTrack = tr("Confirm removal");
QString askAgainText = tr("Don't ask again");
auto askAgainCheckBox = new QCheckBox(askAgainText, nullptr);
connect(askAgainCheckBox, &QCheckBox::stateChanged, [](int state) {
auto onCheckedStateChanged = [](auto state) {
// Invert button state, if it's checked we *shouldn't* ask again
ConfigManager::inst()->setValue("ui", "mixerchanneldeletionwarning", state ? "0" : "1");
});
ConfigManager::inst()->setValue("ui", "mixerchanneldeletionwarning", state != Qt::Unchecked ? "0" : "1");
};
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
connect(askAgainCheckBox, &QCheckBox::checkStateChanged, onCheckedStateChanged);
#else
connect(askAgainCheckBox, &QCheckBox::stateChanged, onCheckedStateChanged);
#endif
QMessageBox mb;
mb.setText(messageRemoveTrack);

View File

@@ -258,13 +258,15 @@ void PluginDescWidget::paintEvent( QPaintEvent * )
}
void PluginDescWidget::enterEvent( QEvent * _e )
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void PluginDescWidget::enterEvent(QEnterEvent* event)
#else
void PluginDescWidget::enterEvent(QEvent* event)
#endif
{
m_mouseOver = true;
QWidget::enterEvent( _e );
QWidget::enterEvent(event);
}

View File

@@ -26,6 +26,7 @@
#include "ProjectNotes.h"
#include <QAction>
#include <QActionGroup>
#include <QApplication>
#include <QCloseEvent>
#include <QColorDialog>
@@ -146,8 +147,15 @@ void ProjectNotes::setupActions()
m_comboFont->setEditable( true );
QFontDatabase db;
m_comboFont->addItems( db.families() );
connect( m_comboFont, SIGNAL( activated( const QString& ) ),
m_edit, SLOT( setFontFamily( const QString& ) ) );
connect(m_comboFont,
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
QOverload<const QString&>::of(&QComboBox::activated),
#else
&QComboBox::textActivated,
#endif
m_edit, &QTextEdit::setFontFamily);
m_comboFont->lineEdit()->setText( QApplication::font().family() );
m_comboSize = new QComboBox( tb );
@@ -158,8 +166,15 @@ void ProjectNotes::setupActions()
{
m_comboSize->addItem( QString::number( *it ) );
}
connect( m_comboSize, SIGNAL( activated( const QString& ) ),
this, SLOT( textSize( const QString& ) ) );
connect(m_comboSize,
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
QOverload<const QString&>::of(&QComboBox::activated),
#else
&QComboBox::textActivated,
#endif
this, &ProjectNotes::textSize);
m_comboSize->lineEdit()->setText( QString::number(
QApplication::font().pointSize() ) );

View File

@@ -81,7 +81,7 @@ SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) :
// Disable the minimize button and make sure that the custom window hint is set
setWindowFlags((this->windowFlags() & ~Qt::WindowMinimizeButtonHint) | Qt::CustomizeWindowHint);
connect( mdiArea(), SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(focusChanged(QMdiSubWindow*)));
connect(mdiArea(), &QMdiArea::subWindowActivated, this, &SubWindow::focusChanged);
}

View File

@@ -293,7 +293,9 @@ void AutomationClipView::paintEvent( QPaintEvent * )
m_clip->getTimeMap().begin();
it != m_clip->getTimeMap().end(); ++it )
{
if( it+1 == m_clip->getTimeMap().end() )
const auto nit = std::next(it);
if (nit == m_clip->getTimeMap().end())
{
const float x1 = POS(it) * ppTick + offset;
const auto x2 = (float)(width() - BORDER_WIDTH);
@@ -320,21 +322,21 @@ void AutomationClipView::paintEvent( QPaintEvent * )
// the next node.
float nextValue = m_clip->progressionType() == AutomationClip::ProgressionType::Discrete
? OUTVAL(it)
: INVAL(it + 1);
: INVAL(nit);
QPainterPath path;
QPointF origin = QPointF(POS(it) * ppTick + offset, 0.0f);
path.moveTo(origin);
path.moveTo(QPointF(POS(it) * ppTick + offset, values[0]));
for (int i = POS(it) + 1; i < POS(it + 1); i++)
for (int i = POS(it) + 1; i < POS(nit); ++i)
{
float x = i * ppTick + offset;
if(x > (width() - BORDER_WIDTH)) break;
float value = values[i - POS(it)];
path.lineTo(QPointF(x, value));
}
path.lineTo((POS(it + 1)) * ppTick + offset, nextValue);
path.lineTo((POS(it + 1)) * ppTick + offset, 0.0f);
path.lineTo((POS(nit)) * ppTick + offset, nextValue);
path.lineTo((POS(nit)) * ppTick + offset, 0.0f);
path.lineTo(origin);
if( gradient() )

View File

@@ -35,6 +35,7 @@
#include "Clipboard.h"
#include "ColorChooser.h"
#include "DataFile.h"
#include "DeprecationHelper.h"
#include "Engine.h"
#include "embed.h"
#include "GuiApplication.h"
@@ -482,9 +483,11 @@ void ClipView::dropEvent( QDropEvent * de )
*/
void ClipView::updateCursor(QMouseEvent * me)
{
const auto posX = position(me).x();
// If we are at the edges, use the resize cursor
if (!me->buttons() && m_clip->manuallyResizable() && !isSelected()
&& ((me->x() > width() - RESIZE_GRIP_WIDTH) || (me->x() < RESIZE_GRIP_WIDTH)))
&& ((posX > width() - RESIZE_GRIP_WIDTH) || (posX < RESIZE_GRIP_WIDTH)))
{
setCursor(Qt::SizeHorCursor);
}
@@ -606,13 +609,15 @@ void ClipView::paintTextLabel(QString const & text, QPainter & painter)
*/
void ClipView::mousePressEvent( QMouseEvent * me )
{
const auto pos = position(me);
// Right now, active is only used on right/mid clicks actions, so we use a ternary operator
// to avoid the overhead of calling getClickedClips when it's not used
auto active = me->button() == Qt::LeftButton
? QVector<ClipView *>()
: getClickedClips();
setInitialPos( me->pos() );
setInitialPos(pos);
setInitialOffsets();
if( !fixedClips() && me->button() == Qt::LeftButton )
{
@@ -647,7 +652,7 @@ void ClipView::mousePressEvent( QMouseEvent * me )
m_clip->setJournalling(false);
}
setInitialPos( me->pos() );
setInitialPos(pos);
setInitialOffsets();
if (!m_clip->manuallyResizable() && !knifeMode)
@@ -655,12 +660,12 @@ void ClipView::mousePressEvent( QMouseEvent * me )
m_action = Action::Move;
setCursor( Qt::SizeAllCursor );
}
else if( me->x() >= width() - RESIZE_GRIP_WIDTH )
else if (pos.x() >= width() - RESIZE_GRIP_WIDTH)
{
m_action = Action::Resize;
setCursor( Qt::SizeHorCursor );
}
else if (me->x() < RESIZE_GRIP_WIDTH)
else if (pos.x() < RESIZE_GRIP_WIDTH)
{
m_action = Action::ResizeLeft;
setCursor( Qt::SizeHorCursor );
@@ -823,6 +828,7 @@ void ClipView::mouseMoveEvent( QMouseEvent * me )
m_hint = nullptr;
}
const auto pos = position(me);
const float ppb = m_trackView->trackContainerView()->pixelsPerBar();
if( m_action == Action::Move )
{
@@ -875,7 +881,7 @@ void ClipView::mouseMoveEvent( QMouseEvent * me )
if( m_action == Action::Resize )
{
// The clip's new length
TimePos l = static_cast<int>( me->x() * TimePos::ticksPerBar() / ppb );
TimePos l = static_cast<int>(pos.x() * TimePos::ticksPerBar() / ppb);
// If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize
if ( unquantizedModHeld(me) )
@@ -910,7 +916,7 @@ void ClipView::mouseMoveEvent( QMouseEvent * me )
{
auto pClip = dynamic_cast<PatternClip*>(m_clip);
const int x = mapToParent( me->pos() ).x() - m_initialMousePos.x();
const int x = mapToParent(pos).x() - m_initialMousePos.x();
TimePos t = qMax( 0, (int)
m_trackView->trackContainerView()->currentPosition() +
@@ -1020,7 +1026,7 @@ void ClipView::mouseReleaseEvent( QMouseEvent * me )
else if( m_action == Action::Split )
{
const float ppb = m_trackView->trackContainerView()->pixelsPerBar();
const TimePos relPos = me->pos().x() * TimePos::ticksPerBar() / ppb;
const TimePos relPos = position(me).x() * TimePos::ticksPerBar() / ppb;
if (me->modifiers() & Qt::ShiftModifier)
{
destructiveSplitClip(unquantizedModHeld(me) ? relPos : quantizeSplitPos(relPos));
@@ -1282,7 +1288,7 @@ void ClipView::setInitialOffsets()
*/
bool ClipView::mouseMovedDistance( QMouseEvent * me, int distance )
{
QPoint dPos = mapToGlobal( me->pos() ) - m_initialMouseGlobalPos;
QPoint dPos = mapToGlobal(position(me)) - m_initialMouseGlobalPos;
const int pixelsMoved = dPos.manhattanLength();
return ( pixelsMoved > distance || pixelsMoved < -distance );
}
@@ -1308,7 +1314,7 @@ TimePos ClipView::draggedClipPos( QMouseEvent * me )
//Pixels per bar
const float ppb = m_trackView->trackContainerView()->pixelsPerBar();
// The pixel distance that the mouse has moved
const int mouseOff = mapToGlobal(me->pos()).x() - m_initialMouseGlobalPos.x();
const int mouseOff = mapToGlobal(position(me)).x() - m_initialMouseGlobalPos.x();
TimePos newPos = m_initialClipPos + mouseOff * TimePos::ticksPerBar() / ppb;
TimePos offset = newPos - m_initialClipPos;
// If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize
@@ -1340,7 +1346,7 @@ TimePos ClipView::draggedClipPos( QMouseEvent * me )
int ClipView::knifeMarkerPos( QMouseEvent * me )
{
//Position relative to start of clip
const int markerPos = me->pos().x();
const int markerPos = position(me).x();
//In unquantized mode, we don't have to mess with the position at all
if ( unquantizedModHeld(me) ) { return markerPos; }

View File

@@ -421,17 +421,19 @@ void MidiClipView::bulkClearNotesOutOfBounds(QVector<ClipView*> clipvs)
void MidiClipView::mousePressEvent( QMouseEvent * _me )
{
const auto pos = position(_me);
bool displayPattern = fixedClips() || (pixelsPerBar() >= 96 && m_legacySEPattern);
if (_me->button() == Qt::LeftButton && m_clip->m_clipType == MidiClip::Type::BeatClip && displayPattern
&& _me->y() > BeatStepButtonOffset && _me->y() < BeatStepButtonOffset + m_stepBtnOff.height())
&& pos.y() > BeatStepButtonOffset && pos.y() < BeatStepButtonOffset + m_stepBtnOff.height())
// when mouse button is pressed in pattern mode
{
// get the step number that was clicked on and
// do calculations in floats to prevent rounding errors...
float tmp = ( ( float(_me->x()) - BORDER_WIDTH ) *
float( m_clip -> m_steps ) ) / float(width() - BORDER_WIDTH*2);
float tmp = ((static_cast<float>(pos.x()) - BORDER_WIDTH)
* static_cast<float>(m_clip->m_steps)) / static_cast<float>(width() - BORDER_WIDTH * 2);
int step = int( tmp );

View File

@@ -428,13 +428,15 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
}
};
const auto pos = position(mouseEvent);
// If we clicked inside the AutomationEditor viewport (where the nodes are represented)
if (mouseEvent->y() > TOP_MARGIN && mouseEvent->x() >= VALUES_WIDTH)
if (pos.y() > TOP_MARGIN && pos.x() >= VALUES_WIDTH)
{
float level = getLevel( mouseEvent->y() );
float level = getLevel(pos.y());
// Get the viewport X
int x = mouseEvent->x() - VALUES_WIDTH;
int x = pos.x() - VALUES_WIDTH;
// Get tick in which the user clicked
int posTicks = (x * TimePos::ticksPerBar() / m_ppb) + m_currentPosition;
@@ -453,7 +455,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
|| (m_editMode == EditMode::Erase && m_mouseDownRight)
);
timeMap::iterator clickedNode = getNodeAt(mouseEvent->x(), mouseEvent->y(), editingOutValue);
timeMap::iterator clickedNode = getNodeAt(pos.x(), pos.y(), editingOutValue);
switch (m_editMode)
{
@@ -622,7 +624,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
m_clip->addJournalCheckPoint();
// Gets the closest node to the mouse click
timeMap::iterator node = getClosestNode(mouseEvent->x());
timeMap::iterator node = getClosestNode(pos.x());
// Starts dragging a tangent
if (m_mouseDownLeft && node != tm.end())
@@ -663,14 +665,16 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent )
void AutomationEditor::mouseDoubleClickEvent(QMouseEvent * mouseEvent)
{
const auto pos = position(mouseEvent);
if (!validClip()) { return; }
// If we double clicked outside the AutomationEditor viewport return
if (mouseEvent->y() <= TOP_MARGIN || mouseEvent->x() < VALUES_WIDTH) { return; }
if (pos.y() <= TOP_MARGIN || pos.x() < VALUES_WIDTH) { return; }
// Are we fine tuning the inValue or outValue?
const bool isOutVal = (m_editMode == EditMode::DrawOutValues);
timeMap::iterator clickedNode = getNodeAt(mouseEvent->x(), mouseEvent->y(), isOutVal);
timeMap::iterator clickedNode = getNodeAt(pos.x(), pos.y(), isOutVal);
switch (m_editMode)
{
@@ -728,12 +732,14 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
return;
}
const auto pos = position(mouseEvent);
// If the mouse y position is inside the Automation Editor viewport
if (mouseEvent->y() > TOP_MARGIN)
if (pos.y() > TOP_MARGIN)
{
float level = getLevel(mouseEvent->y());
float level = getLevel(pos.y());
// Get the viewport X position where the mouse is at
int x = mouseEvent->x() - VALUES_WIDTH;
int x = pos.x() - VALUES_WIDTH;
// Get the X position in ticks
int posTicks = (x * TimePos::ticksPerBar() / m_ppb) + m_currentPosition;
@@ -882,8 +888,8 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
? yCoordOfLevel(OUTVAL(it))
: yCoordOfLevel(INVAL(it));
float dy = m_draggedOutTangent
? y - mouseEvent->y()
: mouseEvent->y() - y;
? y - pos.y()
: pos.y() - y;
float dx = std::abs(posTicks - POS(it));
float newTangent = dy / std::max(dx, 1.0f);
@@ -1314,11 +1320,13 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
if( time_map.size() > 0 )
{
timeMap::iterator it = time_map.begin();
while( it+1 != time_map.end() )
while (std::next(it) != time_map.end())
{
// skip this section if it occurs completely before the
// visible area
int next_x = xCoordOfTick(POS(it+1));
const auto nit = std::next(it);
int next_x = xCoordOfTick(POS(nit));
if( next_x < 0 )
{
++it;
@@ -1341,17 +1349,17 @@ void AutomationEditor::paintEvent(QPaintEvent * pe )
// the next node.
float nextValue = m_clip->progressionType() == AutomationClip::ProgressionType::Discrete
? OUTVAL(it)
: INVAL(it + 1);
: INVAL(nit);
p.setRenderHints( QPainter::Antialiasing, true );
QPainterPath path;
path.moveTo(QPointF(xCoordOfTick(POS(it)), yCoordOfLevel(0)));
for (int i = 0; i < POS(it + 1) - POS(it); i++)
for (int i = 0; i < POS(nit) - POS(it); ++i)
{
path.lineTo(QPointF(xCoordOfTick(POS(it) + i), yCoordOfLevel(values[i])));
}
path.lineTo(QPointF(xCoordOfTick(POS(it + 1)), yCoordOfLevel(nextValue)));
path.lineTo(QPointF(xCoordOfTick(POS(it + 1)), yCoordOfLevel(0)));
path.lineTo(QPointF(xCoordOfTick(POS(nit)), yCoordOfLevel(nextValue)));
path.lineTo(QPointF(xCoordOfTick(POS(nit)), yCoordOfLevel(0)));
path.lineTo(QPointF(xCoordOfTick(POS(it)), yCoordOfLevel(0)));
p.fillPath(path, m_graphColor);
p.setRenderHints( QPainter::Antialiasing, false );
@@ -2060,17 +2068,18 @@ AutomationEditorWindow::AutomationEditorWindow() :
auto editModeGroup = new ActionGroup(this);
m_drawAction = editModeGroup->addAction(embed::getIconPixmap("edit_draw"), tr("Draw mode (Shift+D)"));
m_drawAction->setShortcut(combine(Qt::SHIFT, Qt::Key_D));
m_drawAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_D));
m_drawAction->setChecked(true);
m_eraseAction = editModeGroup->addAction(embed::getIconPixmap("edit_erase"), tr("Erase mode (Shift+E)"));
m_eraseAction->setShortcut(combine(Qt::SHIFT, Qt::Key_E));
m_eraseAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_E));
m_drawOutAction = editModeGroup->addAction(embed::getIconPixmap("edit_draw_outvalue"), tr("Draw outValues mode (Shift+C)"));
m_drawOutAction->setShortcut(combine(Qt::SHIFT, Qt::Key_C));
m_drawOutAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_C));
m_editTanAction = editModeGroup->addAction(embed::getIconPixmap("edit_tangent"), tr("Edit tangents mode (Shift+T)"));
m_editTanAction->setShortcut(combine(Qt::SHIFT, Qt::Key_T));
m_editTanAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_T));
m_editTanAction->setEnabled(false);
m_flipYAction = new QAction(embed::getIconPixmap("flip_y"), tr("Flip vertically"), this);

View File

@@ -120,7 +120,7 @@ Editor::Editor(bool record, bool stepRecord) :
connect(m_recordAccompanyAction, SIGNAL(triggered()), this, SLOT(recordAccompany()));
connect(m_toggleStepRecordingAction, SIGNAL(triggered()), this, SLOT(toggleStepRecording()));
connect(m_stopAction, SIGNAL(triggered()), this, SLOT(stop()));
new QShortcut(QKeySequence(combine(Qt::SHIFT, Qt::Key_F11)), this, SLOT(toggleMaximize()));
new QShortcut(keySequence(Qt::SHIFT, Qt::Key_F11), this, SLOT(toggleMaximize()));
// Add actions to toolbar
addButton(m_playAction, "playButton");

View File

@@ -1117,7 +1117,10 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x,
{
// Previous node values (based on outValue). We just calculate
// the y level because the x will be the same as old_x.
const float pre_level = OUTVAL(it - 1);
const auto pit = std::prev(it);
const auto nit = std::next(it);
const float pre_level = OUTVAL(pit);
int pre_y = middle_y - pre_level * m_keyLineHeight;
// Draws the line representing the discrete jump if there's one
@@ -1142,7 +1145,7 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x,
// If we are in the last node and there's a discrete jump, we draw a
// vertical line representing it
if ((it + 1) == map.end())
if (nit == map.end())
{
const float last_level = OUTVAL(it);
if (cur_level != last_level)
@@ -1631,6 +1634,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
return;
}
const auto pos = position(me);
// -- Knife
if (m_editMode == EditMode::Knife && me->button() == Qt::LeftButton)
{
@@ -1684,25 +1689,25 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
// keep track of the point where the user clicked down
if( me->button() == Qt::LeftButton )
{
m_moveStartX = me->x();
m_moveStartY = me->y();
m_moveStartX = pos.x();
m_moveStartY = pos.y();
}
if(me->button() == Qt::LeftButton &&
me->y() > keyAreaBottom() && me->y() < noteEditTop())
if (me->button() == Qt::LeftButton
&& pos.y() > keyAreaBottom() && pos.y() < noteEditTop())
{
// resizing the note edit area
m_action = Action::ResizeNoteEditArea;
return;
}
if( me->y() > PR_TOP_MARGIN )
if (pos.y() > PR_TOP_MARGIN)
{
bool edit_note = ( me->y() > noteEditTop() );
bool edit_note = (pos.y() > noteEditTop());
int key_num = getKey( me->y() );
int key_num = getKey(pos.y());
int x = me->x();
int x = pos.x();
if (x > m_whiteKeyWidth)
@@ -1959,7 +1964,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
update();
}
else if( me->y() < keyAreaBottom() )
else if (pos.y() < keyAreaBottom())
{
// reference to last key needed for both
// right click (used for copy all keys on note)
@@ -1970,8 +1975,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
if( me->buttons() == Qt::RightButton )
{
// right click - tone marker contextual menu
m_pianoKeySelected = getKey( me->y() );
m_semiToneMarkerMenu->popup( mapToGlobal( QPoint( me->x(), me->y() ) ) );
m_pianoKeySelected = getKey(pos.y());
m_semiToneMarkerMenu->popup(mapToGlobal(pos));
}
else if( me->buttons() == Qt::LeftButton )
{
@@ -1997,7 +2002,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
else if( me->buttons() == Qt::RightButton )
{
// pop menu asking which one they want to edit
m_noteEditMenu->popup( mapToGlobal( QPoint( me->x(), me->y() ) ) );
m_noteEditMenu->popup(mapToGlobal(pos));
}
}
}
@@ -2013,13 +2018,15 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me )
return;
}
const auto pos = position(me);
// if they clicked in the note edit area, enter value for the volume bar
if( me->x() > noteEditLeft() && me->x() < noteEditRight()
&& me->y() > noteEditTop() && me->y() < noteEditBottom() )
if (pos.x() > noteEditLeft() && pos.x() < noteEditRight()
&& pos.y() > noteEditTop() && pos.y() < noteEditBottom())
{
// get values for going through notes
int pixel_range = 4;
int x = me->x() - m_whiteKeyWidth;
int x = pos.x() - m_whiteKeyWidth;
const int ticks_start = ( x-pixel_range/2 ) *
TimePos::ticksPerBar() / m_ppb + m_currentPosition;
const int ticks_end = ( x+pixel_range/2 ) *
@@ -2407,11 +2414,13 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
return;
}
const auto pos = position(me);
if( m_action == Action::None && me->buttons() == 0 )
{
// When cursor is between note editing area and volume/panning
// area show vertical size cursor.
if( me->y() > keyAreaBottom() && me->y() < noteEditTop() )
if (pos.y() > keyAreaBottom() && pos.y() < noteEditTop())
{
setCursor( Qt::SizeVerCursor );
return;
@@ -2420,12 +2429,12 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
else if( m_action == Action::ResizeNoteEditArea )
{
// Don't try to show more keys than the full keyboard, bail if trying to
if (m_pianoKeysVisible == NumKeys && me->y() > m_moveStartY)
if (m_pianoKeysVisible == NumKeys && pos.y() > m_moveStartY)
{
return;
}
int newHeight = height() - me->y();
if (me->y() < KEY_AREA_MIN_HEIGHT)
int newHeight = height() - pos.y();
if (pos.y() < KEY_AREA_MIN_HEIGHT)
{
newHeight = height() - KEY_AREA_MIN_HEIGHT -
PR_TOP_MARGIN - PR_BOTTOM_MARGIN; // - NOTE_EDIT_RESIZE_BAR
@@ -2452,14 +2461,14 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
updateStrumPos(me, false, me->modifiers() & Qt::ShiftModifier);
}
if( me->y() > PR_TOP_MARGIN || m_action != Action::None )
if (pos.y() > PR_TOP_MARGIN || m_action != Action::None)
{
bool edit_note = ( me->y() > noteEditTop() )
&& m_action != Action::SelectNotes;
bool edit_note = (pos.y() > noteEditTop())
&& m_action != Action::SelectNotes;
int key_num = getKey( me->y() );
int x = me->x();
int key_num = getKey(pos.y());
int x = pos.x();
// see if they clicked on the keyboard on the left
if (x < m_whiteKeyWidth && m_action == Action::None
@@ -2488,8 +2497,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
}
dragNotes(
me->x(),
me->y(),
pos.x(),
pos.y(),
me->modifiers() & Qt::AltModifier,
me->modifiers() & Qt::ShiftModifier,
me->modifiers() & Qt::ControlModifier
@@ -2528,29 +2537,26 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
if( me->buttons() & Qt::LeftButton )
{
vol = qBound<int>( MinVolume,
MinVolume +
( ( (float)noteEditBottom() ) - ( (float)me->y() ) ) /
( (float)( noteEditBottom() - noteEditTop() ) ) *
( MaxVolume - MinVolume ),
MaxVolume );
pan = qBound<int>( PanningLeft,
PanningLeft +
( (float)( noteEditBottom() - me->y() ) ) /
( (float)( noteEditBottom() - noteEditTop() ) ) *
( (float)( PanningRight - PanningLeft ) ),
PanningRight);
vol = qBound(MinVolume, static_cast<volume_t>(MinVolume
+ static_cast<float>(noteEditBottom() - pos.y())
/ static_cast<float>(noteEditBottom() - noteEditTop())
* (MaxVolume - MinVolume)), MaxVolume);
pan = qBound(PanningLeft, static_cast<panning_t>(PanningLeft
+ static_cast<float>(noteEditBottom() - pos.y())
/ static_cast<float>(noteEditBottom() - noteEditTop())
* (PanningRight - PanningLeft)), PanningRight);
}
if( m_noteEditMode == NoteEditMode::Volume )
{
m_lastNoteVolume = vol;
showVolTextFloat( vol, me->pos() );
showVolTextFloat(vol, position(me));
}
else if( m_noteEditMode == NoteEditMode::Panning )
{
m_lastNotePanning = pan;
showPanTextFloat( pan, me->pos() );
showPanTextFloat(pan, position(me));
}
// When alt is pressed we only edit the note under the cursor
@@ -2746,8 +2752,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
setCursor( Qt::ArrowCursor );
}
m_lastMouseX = me->x();
m_lastMouseY = me->y();
m_lastMouseX = pos.x();
m_lastMouseY = pos.y();
update();
}
@@ -2757,9 +2763,11 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
void PianoRoll::updateKnifePos(QMouseEvent* me, bool initial)
{
const auto pos = position(me);
// Calculate the TimePos from the mouse
int mouseViewportPosX = me->x() - m_whiteKeyWidth;
int mouseViewportPosY = keyAreaBottom() - 1 - me->y();
int mouseViewportPosX = pos.x() - m_whiteKeyWidth;
int mouseViewportPosY = keyAreaBottom() - 1 - pos.y();
int mouseTickPos = mouseViewportPosX * TimePos::ticksPerBar() / m_ppb + m_currentPosition;
int mouseKey = std::round(1.f * mouseViewportPosY / m_keyLineHeight) + m_startKey - 1;
@@ -2824,16 +2832,17 @@ void PianoRoll::updateStrumPos(QMouseEvent* me, bool initial, bool warp)
{
if (!hasValidMidiClip()) { return; }
// Calculate the TimePos from the mouse
int mouseViewportPos = me->x() - m_whiteKeyWidth;
const auto pos = position(me);
int mouseViewportPos = pos.x() - m_whiteKeyWidth;
int mouseTickPos = mouseViewportPos * TimePos::ticksPerBar() / m_ppb + m_currentPosition;
// Should we add quantization? probably not?
if (initial)
{
m_strumStartTime = mouseTickPos;
m_strumStartVertical = me->y();
m_strumStartVertical = pos.y();
}
m_strumCurrentTime = mouseTickPos;
m_strumCurrentVertical = me->y();
m_strumCurrentVertical = pos.y();
int strumTicksHorizontal = m_strumCurrentTime - m_strumStartTime;
float strumPower = fastPow10f(0.01f * (m_strumCurrentVertical - m_strumStartVertical));
@@ -3923,8 +3932,8 @@ void PianoRoll::wheelEvent(QWheelEvent * we )
{
for ( Note * n : nv )
{
panning_t pan = qBound<int>( PanningLeft, n->getPanning() + step, PanningRight );
n->setPanning( pan );
panning_t pan = qBound(PanningLeft, static_cast<panning_t>(n->getPanning() + step), PanningRight);
n->setPanning(pan);
}
bool allPansEqual = std::all_of( nv.begin(), nv.end(),
[nv](const Note *note)
@@ -4902,10 +4911,10 @@ PianoRollWindow::PianoRollWindow() :
drawAction->setChecked( true );
drawAction->setShortcut(combine(Qt::SHIFT, Qt::Key_D));
eraseAction->setShortcut(combine(Qt::SHIFT, Qt::Key_E));
selectAction->setShortcut(combine(Qt::SHIFT, Qt::Key_S));
pitchBendAction->setShortcut(combine(Qt::SHIFT, Qt::Key_T));
drawAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_D ));
eraseAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_E));
selectAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_S));
pitchBendAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_T));
connect( editModeGroup, SIGNAL(triggered(int)), m_editor, SLOT(setEditMode(int)));
@@ -4964,9 +4973,9 @@ PianoRollWindow::PianoRollWindow() :
auto pasteAction = new QAction(embed::getIconPixmap("edit_paste"), tr("Paste (%1+V)").arg(UI_CTRL_KEY), this);
cutAction->setShortcut(combine(Qt::CTRL, Qt::Key_X));
copyAction->setShortcut(combine(Qt::CTRL, Qt::Key_C));
pasteAction->setShortcut(combine(Qt::CTRL, Qt::Key_V));
cutAction->setShortcut(keySequence(Qt::CTRL, Qt::Key_X));
copyAction->setShortcut(keySequence(Qt::CTRL, Qt::Key_C));
pasteAction->setShortcut(keySequence(Qt::CTRL, Qt::Key_V));
connect( cutAction, SIGNAL(triggered()), m_editor, SLOT(cutSelectedNotes()));
connect( copyAction, SIGNAL(triggered()), m_editor, SLOT(copySelectedNotes()));
@@ -4987,23 +4996,23 @@ PianoRollWindow::PianoRollWindow() :
auto glueAction = new QAction(embed::getIconPixmap("glue"), tr("Glue"), noteToolsButton);
connect(glueAction, SIGNAL(triggered()), m_editor, SLOT(glueNotes()));
glueAction->setShortcut(combine(Qt::SHIFT, Qt::Key_G));
glueAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_G));
auto knifeAction = new QAction(embed::getIconPixmap("edit_knife"), tr("Knife"), noteToolsButton);
connect(knifeAction, &QAction::triggered, m_editor, &PianoRoll::setKnifeAction);
knifeAction->setShortcut(combine(Qt::SHIFT, Qt::Key_K));
knifeAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_K));
auto strumAction = new QAction(embed::getIconPixmap("arp_free"), tr("Strum"), noteToolsButton);
connect(strumAction, &QAction::triggered, m_editor, &PianoRoll::setStrumAction);
strumAction->setShortcut(combine(Qt::SHIFT, Qt::Key_J));
strumAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_J));
auto fillAction = new QAction(embed::getIconPixmap("fill"), tr("Fill"), noteToolsButton);
connect(fillAction, &QAction::triggered, [this](){ m_editor->fitNoteLengths(true); });
fillAction->setShortcut(combine(Qt::SHIFT, Qt::Key_F));
fillAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_F));
auto cutOverlapsAction = new QAction(embed::getIconPixmap("cut_overlaps"), tr("Cut overlaps"), noteToolsButton);
connect(cutOverlapsAction, &QAction::triggered, [this](){ m_editor->fitNoteLengths(false); });
cutOverlapsAction->setShortcut(combine(Qt::SHIFT, Qt::Key_C));
cutOverlapsAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_C));
auto minLengthAction = new QAction(embed::getIconPixmap("min_length"), tr("Min length as last"), noteToolsButton);
connect(minLengthAction, &QAction::triggered, [this](){ m_editor->constrainNoteLengths(false); });
@@ -5013,7 +5022,7 @@ PianoRollWindow::PianoRollWindow() :
auto reverseAction = new QAction(embed::getIconPixmap("flip_x"), tr("Reverse Notes"), noteToolsButton);
connect(reverseAction, &QAction::triggered, [this](){ m_editor->reverseNotes(); });
reverseAction->setShortcut(combine(Qt::SHIFT, Qt::Key_R));
reverseAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_R));
noteToolsButton->addAction(glueAction);
noteToolsButton->addAction(knifeAction);

View File

@@ -587,11 +587,13 @@ void SongEditor::closeEvent( QCloseEvent * ce )
void SongEditor::mousePressEvent(QMouseEvent *me)
{
const auto pos = position(me);
if (allowRubberband())
{
//we save the position of scrollbars, mouse position and zooming level
m_scrollPos = QPoint(m_leftRightScroll->value(), contentWidget()->verticalScrollBar()->value());
m_origin = contentWidget()->mapFromParent(QPoint(me->pos().x(), me->pos().y()));
m_origin = contentWidget()->mapFromParent(pos);
m_rubberbandPixelsPerBar = pixelsPerBar();
//paint the rubberband
@@ -600,8 +602,8 @@ void SongEditor::mousePressEvent(QMouseEvent *me)
rubberBand()->show();
//the trackView(index) and the time position where the mouse was clicked
m_rubberBandStartTrackview = trackIndexFromSelectionPoint(me->y());
m_rubberbandStartTimePos = TimePos((me->x() - m_trackHeadWidth)
m_rubberBandStartTrackview = trackIndexFromSelectionPoint(pos.y());
m_rubberbandStartTimePos = TimePos((pos.x() - m_trackHeadWidth)
/ pixelsPerBar() * TimePos::ticksPerBar())
+ m_currentPosition;
}
@@ -613,7 +615,7 @@ void SongEditor::mousePressEvent(QMouseEvent *me)
void SongEditor::mouseMoveEvent(QMouseEvent *me)
{
m_mousePos = me->pos();
m_mousePos = position(me);
updateRubberband();
QWidget::mouseMoveEvent(me);
}

View File

@@ -33,6 +33,7 @@
#include <QToolBar>
#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "KeyboardShortcuts.h"
#include "NStateButton.h"
@@ -239,8 +240,10 @@ auto TimeLineWidget::getClickedTime(const int xPosition) const -> TimePos
auto TimeLineWidget::getLoopAction(QMouseEvent* event) const -> TimeLineWidget::Action
{
const auto pos = position(event);
const auto mode = ConfigManager::inst()->value("app", "loopmarkermode");
const auto xPos = event->x();
const auto xPos = pos.x();
const auto button = event->button();
if (mode == "handles")
@@ -283,7 +286,9 @@ auto TimeLineWidget::actionCursor(Action action) const -> QCursor
void TimeLineWidget::mousePressEvent(QMouseEvent* event)
{
if (event->x() < m_xOffset) { return; }
const auto pos = position(event);
if (pos.x() < m_xOffset) { return; }
const auto shift = event->modifiers() & Qt::ShiftModifier;
const auto ctrl = event->modifiers() & Qt::ControlModifier;
@@ -295,14 +300,14 @@ void TimeLineWidget::mousePressEvent(QMouseEvent* event)
if (m_action == Action::MoveLoop)
{
m_dragStartPos = getClickedTime(event->x());
m_dragStartPos = getClickedTime(pos.x());
m_oldLoopPos = {m_timeline->loopBegin(), m_timeline->loopEnd()};
}
}
else if (event->button() == Qt::LeftButton && ctrl) // selection
{
m_action = Action::SelectSongClip;
m_initalXSelect = event->x();
m_initalXSelect = pos.x();
}
else if (event->button() == Qt::LeftButton && !ctrl) // move playhead
{
@@ -326,7 +331,9 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event )
{
parentWidget()->update(); // essential for widgets that this timeline had taken their mouse move event from.
auto timeAtCursor = getClickedTime(event->x());
const auto pos = position(event);
auto timeAtCursor = getClickedTime(pos.x());
const auto control = event->modifiers() & Qt::ControlModifier;
switch( m_action )
@@ -387,7 +394,7 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event )
break;
}
case Action::SelectSongClip:
emit regionSelectedFromPixels( m_initalXSelect , event->x() );
emit regionSelectedFromPixels(m_initalXSelect, pos.x());
break;
default:

View File

@@ -110,7 +110,7 @@ auto getIconPixmap(std::string_view name, int width, int height, const char* con
const auto pixmapName = QString::fromUtf8(name.data(), name.size());
const auto cacheName = (width > 0 && height > 0)
? QStringLiteral("%1_%2_%3").arg(pixmapName, width, height)
? QStringLiteral("%1_%2_%3").arg(pixmapName).arg(width).arg(height)
: pixmapName;
// Return cached pixmap if it exists

View File

@@ -45,6 +45,7 @@
#include <QVBoxLayout>
#include "AutomatableModelView.h"
#include "DeprecationHelper.h"
#include "PianoView.h"
#include "Piano.h"
#include "CaptionMenu.h"
@@ -417,11 +418,13 @@ void PianoView::mousePressEvent(QMouseEvent *me)
{
if (me->button() == Qt::LeftButton && m_piano != nullptr)
{
const auto pos = position(me);
// get pressed key
int key_num = getKeyFromMouse(me->pos());
if (me->pos().y() > PIANO_BASE)
int key_num = getKeyFromMouse(pos);
if (pos.y() > PIANO_BASE)
{
int y_diff = me->pos().y() - PIANO_BASE;
int y_diff = pos.y() - PIANO_BASE;
int velocity = static_cast<int>(
static_cast<float>(y_diff) / getKeyHeight(key_num) *
m_piano->instrumentTrack()->midiPort()->baseVelocity());
@@ -519,8 +522,10 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me )
return;
}
int key_num = getKeyFromMouse( _me->pos() );
int y_diff = _me->pos().y() - PIANO_BASE;
const auto pos = position(_me);
int key_num = getKeyFromMouse(pos);
int y_diff = pos.y() - PIANO_BASE;
int velocity = (int)( (float) y_diff /
( Piano::isWhiteKey( key_num ) ?
PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) *
@@ -551,7 +556,7 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me )
}
if( _me->buttons() & Qt::LeftButton )
{
if( _me->pos().y() > PIANO_BASE )
if (pos.y() > PIANO_BASE)
{
m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOn, -1, key_num, velocity ) );
m_piano->setKeyState( key_num, true );

View File

@@ -550,8 +550,13 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) :
setCurrentIndex(m_audioInterfaces->findText(audioDevName));
m_audioIfaceSetupWidgets[audioDevName]->show();
connect(m_audioInterfaces, SIGNAL(activated(const QString&)),
this, SLOT(audioInterfaceChanged(const QString&)));
connect(m_audioInterfaces,
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
QOverload<const QString&>::of(&QComboBox::activated),
#else
&QComboBox::textActivated,
#endif
this, &SetupDialog::audioInterfaceChanged);
// Advanced setting, hidden for now
// // TODO Handle or remove.
@@ -725,9 +730,13 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) :
m_midiInterfaces->setCurrentIndex(m_midiInterfaces->findText(midiDevName));
m_midiIfaceSetupWidgets[midiDevName]->show();
connect(m_midiInterfaces, SIGNAL(activated(const QString&)),
this, SLOT(midiInterfaceChanged(const QString&)));
connect(m_midiInterfaces,
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
QOverload<const QString&>::of(&QComboBox::activated),
#else
&QComboBox::textActivated,
#endif
this, &SetupDialog::midiInterfaceChanged);
// MIDI autoassign group
QGroupBox * midiAutoAssignBox = new QGroupBox(tr("Automatically assign MIDI controller to selected track"), midi_w);

View File

@@ -26,6 +26,7 @@
#include "AutomationTrackView.h"
#include "AutomationClip.h"
#include "AutomationTrack.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "Engine.h"
#include "ProjectJournal.h"
@@ -64,13 +65,10 @@ void AutomationTrackView::dropEvent( QDropEvent * _de )
auto mod = dynamic_cast<AutomatableModel*>(Engine::projectJournal()->journallingObject(val.toInt()));
if( mod != nullptr )
{
TimePos pos = TimePos( trackContainerView()->
currentPosition() +
( _de->pos().x() -
getTrackContentWidget()->x() ) *
TimePos::ticksPerBar() /
static_cast<int>( trackContainerView()->pixelsPerBar() ) )
.toAbsoluteBar();
const int deX = position(_de).x();
TimePos pos = TimePos(trackContainerView()->currentPosition()
+ (deX - getTrackContentWidget()->x()) * TimePos::ticksPerBar()
/ static_cast<int>(trackContainerView()->pixelsPerBar())).toAbsoluteBar();
if( pos.getTicks() < 0 )
{

View File

@@ -31,6 +31,7 @@
#include <QVBoxLayout>
#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "Engine.h"
#include "FadeButton.h"
@@ -207,9 +208,10 @@ void SampleTrackView::dropEvent(QDropEvent *de)
? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT
: DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
int xPos = de->pos().x() < trackHeadWidth
const int deX = position(de).x();
int xPos = deX < trackHeadWidth
? trackHeadWidth
: de->pos().x();
: deX;
const float snapSize = getGUI()->songEditor()->m_editor->getSnapSize();
TimePos clipPos = trackContainerView()->fixedClips()

View File

@@ -32,6 +32,7 @@
#include "AutomationClip.h"
#include "Clipboard.h"
#include "DataFile.h"
#include "DeprecationHelper.h"
#include "Engine.h"
#include "GuiApplication.h"
#include "PatternEditor.h"
@@ -321,7 +322,7 @@ TimePos TrackContentWidget::getPosition( int mouseX )
*/
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
{
TimePos clipPos = getPosition( dee->pos().x() );
TimePos clipPos = getPosition(position(dee).x());
if( canPasteSelection( clipPos, dee ) == false )
{
dee->ignore();
@@ -557,7 +558,9 @@ bool TrackContentWidget::pasteSelection( TimePos clipPos, const QMimeData * md,
*/
void TrackContentWidget::dropEvent( QDropEvent * de )
{
TimePos clipPos = TimePos( getPosition( de->pos().x() ) );
const auto pos = position(de);
TimePos clipPos = TimePos(getPosition(pos.x()));
if( pasteSelection( clipPos, de ) == true )
{
de->accept();
@@ -573,6 +576,8 @@ void TrackContentWidget::dropEvent( QDropEvent * de )
*/
void TrackContentWidget::mousePressEvent( QMouseEvent * me )
{
const auto pos = position(me);
// Enable box select if control is held when clicking an empty space
// (If we had clicked a Clip it would have intercepted the mouse event)
if( me->modifiers() & Qt::ControlModifier ){
@@ -599,8 +604,8 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me )
}
getTrack()->addJournalCheckPoint();
const float snapSize = getGUI()->songEditor()->m_editor->getSnapSize();
const TimePos pos = TimePos(getPosition(me->x())).quantize(snapSize, true);
getTrack()->createClip(pos);
const TimePos timePos = TimePos(getPosition(pos.x())).quantize(snapSize, true);
getTrack()->createClip(timePos);
}
}

View File

@@ -29,6 +29,7 @@
#include <QMouseEvent>
#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "Instrument.h"
#include "InstrumentTrack.h"
@@ -181,7 +182,8 @@ void TrackLabelButton::mouseDoubleClickEvent( QMouseEvent * _me )
void TrackLabelButton::mouseReleaseEvent( QMouseEvent *_me )
{
if( m_buttonRect.contains( _me->globalPos(), true ) && m_renameLineEdit->isHidden() )
const auto globalPos = globalPosition(_me);
if (m_buttonRect.contains(globalPos, true) && m_renameLineEdit->isHidden())
{
QToolButton::mousePressEvent( _me );
}

View File

@@ -175,10 +175,16 @@ bool TrackOperationsWidget::confirmRemoval()
QString messageTitleRemoveTrack = tr("Confirm removal");
QString askAgainText = tr("Don't ask again");
auto askAgainCheckBox = new QCheckBox(askAgainText, nullptr);
connect(askAgainCheckBox, &QCheckBox::stateChanged, [](int state){
auto onCheckedStateChanged = [](auto state){
// Invert button state, if it's checked we *shouldn't* ask again
ConfigManager::inst()->setValue("ui", "trackdeletionwarning", state ? "0" : "1");
});
ConfigManager::inst()->setValue("ui", "trackdeletionwarning", state != Qt::Unchecked ? "0" : "1");
};
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
connect(askAgainCheckBox, &QCheckBox::checkStateChanged, onCheckedStateChanged);
#else
connect(askAgainCheckBox, &QCheckBox::stateChanged, onCheckedStateChanged);
#endif
QMessageBox mb;
mb.setText(messageRemoveTrack);

View File

@@ -36,6 +36,7 @@
#include "AutomatableButton.h"
#include "ConfigManager.h"
#include "DataFile.h"
#include "DeprecationHelper.h"
#include "Engine.h"
#include "FadeButton.h"
#include "StringPairDrag.h"
@@ -259,6 +260,7 @@ void TrackView::dropEvent( QDropEvent * de )
*/
void TrackView::mousePressEvent( QMouseEvent * me )
{
const auto pos = position(me);
// If previously dragged too small, restore on shift-leftclick
if( height() < DEFAULT_TRACK_HEIGHT &&
@@ -274,7 +276,7 @@ void TrackView::mousePressEvent( QMouseEvent * me )
"compacttrackbuttons" ).toInt()==1 ?
DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT :
DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal )
if (m_trackContainerView->allowRubberband() == true && pos.x() > widgetTotal)
{
QWidget::mousePressEvent( me );
}
@@ -283,10 +285,8 @@ void TrackView::mousePressEvent( QMouseEvent * me )
if( me->modifiers() & Qt::ShiftModifier )
{
m_action = Action::Resize;
QCursor::setPos( mapToGlobal( QPoint( me->x(),
height() ) ) );
QCursor c( Qt::SizeVerCursor);
QApplication::setOverrideCursor( c );
QCursor::setPos(mapToGlobal(QPoint(pos.x(), height())));
QApplication::setOverrideCursor(Qt::SizeVerCursor);
}
me->accept();
@@ -318,11 +318,13 @@ void TrackView::mousePressEvent( QMouseEvent * me )
*/
void TrackView::mouseMoveEvent( QMouseEvent * me )
{
const auto pos = position(me);
int widgetTotal = ConfigManager::inst()->value( "ui",
"compacttrackbuttons" ).toInt()==1 ?
DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT :
DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal )
if (m_trackContainerView->allowRubberband() == true && pos.x() > widgetTotal)
{
QWidget::mouseMoveEvent( me );
}
@@ -330,7 +332,7 @@ void TrackView::mouseMoveEvent( QMouseEvent * me )
{
// look which track-widget the mouse-cursor is over
const int yPos =
m_trackContainerView->contentWidget()->mapFromGlobal( me->globalPos() ).y();
m_trackContainerView->contentWidget()->mapFromGlobal(globalPosition(me)).y();
const TrackView * trackAtY = m_trackContainerView->trackViewAt( yPos );
// debug code
@@ -340,7 +342,7 @@ void TrackView::mouseMoveEvent( QMouseEvent * me )
if( trackAtY != nullptr && trackAtY != this )
{
// then move us up/down there!
if( me->y() < 0 )
if (pos.y() < 0)
{
m_trackContainerView->moveTrackViewUp( this );
}
@@ -352,7 +354,7 @@ void TrackView::mouseMoveEvent( QMouseEvent * me )
}
else if( m_action == Action::Resize )
{
resizeToHeight(me->y());
resizeToHeight(pos.y());
}
if( height() < DEFAULT_TRACK_HEIGHT )
@@ -393,7 +395,9 @@ void TrackView::wheelEvent(QWheelEvent* we)
{
resizeToHeight(height() + stepSize * direction);
we->accept();
return;
}
we->ignore();
}

View File

@@ -33,6 +33,7 @@
#include "CaptionMenu.h"
#include "FontHelper.h"
#include "DeprecationHelper.h"
#define QT_SUPPORTS_WIDGET_SCREEN (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
#if !QT_SUPPORTS_WIDGET_SCREEN
@@ -105,9 +106,11 @@ void ComboBox::mousePressEvent( QMouseEvent* event )
return;
}
const auto pos = position(event);
if( event->button() == Qt::LeftButton && ! ( event->modifiers() & Qt::ControlModifier ) )
{
if( event->x() > width() - CB_ARROW_BTN_WIDTH )
if (pos.x() > width() - CB_ARROW_BTN_WIDTH)
{
m_pressed = true;
update();

View File

@@ -54,6 +54,7 @@
#include "lmms_math.h"
#include "CaptionMenu.h"
#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "KeyboardShortcuts.h"
#include "SimpleTextFloat.h"
@@ -172,7 +173,7 @@ void Fader::contextMenuEvent(QContextMenuEvent* ev)
void Fader::mouseMoveEvent(QMouseEvent* mouseEvent)
{
const int localY = mouseEvent->y();
const int localY = position(mouseEvent).y();
setVolumeByLocalPixelValue(localY);
@@ -186,6 +187,8 @@ void Fader::mouseMoveEvent(QMouseEvent* mouseEvent)
void Fader::mousePressEvent(QMouseEvent* mouseEvent)
{
const auto pos = position(mouseEvent);
if (mouseEvent->button() == Qt::LeftButton &&
!(mouseEvent->modifiers() & KBD_COPY_MODIFIER))
{
@@ -196,7 +199,7 @@ void Fader::mousePressEvent(QMouseEvent* mouseEvent)
thisModel->saveJournallingState(false);
}
const int localY = mouseEvent->y();
const int localY = pos.y();
const auto knobLowerPosY = calculateKnobPosYFromModel();
const auto knobUpperPosY = knobLowerPosY - m_knobSize.height();

View File

@@ -30,6 +30,7 @@
#include <QPainter>
#include "lmms_math.h"
#include "DeprecationHelper.h"
#include "CaptionMenu.h"
#include "ControllerConnection.h"
#include "GuiApplication.h"
@@ -166,8 +167,7 @@ void FloatModelEditorBase::mousePressEvent(QMouseEvent * me)
thisModel->saveJournallingState(false);
}
const QPoint & p = me->pos();
m_lastMousePos = p;
m_lastMousePos = position(me);
m_leftOver = 0.0f;
emit sliderPressed();
@@ -196,13 +196,15 @@ void FloatModelEditorBase::mousePressEvent(QMouseEvent * me)
void FloatModelEditorBase::mouseMoveEvent(QMouseEvent * me)
{
if (m_buttonPressed && me->pos() != m_lastMousePos)
const auto pos = position(me);
if (m_buttonPressed && pos != m_lastMousePos)
{
// knob position is changed depending on last mouse position
setPosition(me->pos() - m_lastMousePos);
setPosition(pos - m_lastMousePos);
emit sliderMoved(model()->value());
// original position for next time is current position
m_lastMousePos = me->pos();
m_lastMousePos = pos;
}
s_textFloat->setText(displayValue());
s_textFloat->show();
@@ -229,8 +231,11 @@ void FloatModelEditorBase::mouseReleaseEvent(QMouseEvent* event)
s_textFloat->hide();
}
void FloatModelEditorBase::enterEvent(QEvent *event)
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
void FloatModelEditorBase::enterEvent(QEnterEvent*)
#else
void FloatModelEditorBase::enterEvent(QEvent*)
#endif
{
showTextFloat(700, 2000);
}

View File

@@ -26,6 +26,7 @@
#include <QPainter>
#include "Graph.h"
#include "DeprecationHelper.h"
#include "SampleLoader.h"
#include "StringPairDrag.h"
#include "Oscillator.h"
@@ -99,9 +100,11 @@ void graph::loadSampleFromFile( const QString & _filename )
void Graph::mouseMoveEvent ( QMouseEvent * _me )
{
const auto pos = position(_me);
// get position
int x = _me->x();
int y = _me->y();
int x = pos.x();
int y = pos.y();
/* static bool skip = false;
@@ -146,13 +149,15 @@ void Graph::mouseMoveEvent ( QMouseEvent * _me )
void Graph::mousePressEvent( QMouseEvent * _me )
{
const auto pos = position(_me);
if( _me->button() == Qt::LeftButton )
{
if ( !( _me->modifiers() & Qt::ShiftModifier ) )
{
// get position
int x = _me->x();
int y = _me->y();
int x = pos.x();
int y = pos.y();
changeSampleAt( x, y );
@@ -165,8 +170,8 @@ void Graph::mousePressEvent( QMouseEvent * _me )
{
//when shift-clicking, draw a line from last position to current
//position
int x = _me->x();
int y = _me->y();
int x = pos.x();
int y = pos.y();
drawLineAt( x, y, m_lastCursorX );

View File

@@ -26,6 +26,7 @@
#include <QPainter>
#include "GroupBox.h"
#include "DeprecationHelper.h"
#include "embed.h"
#include "FontHelper.h"
@@ -81,7 +82,9 @@ void GroupBox::setLedButtonShown(bool value)
void GroupBox::mousePressEvent( QMouseEvent * _me )
{
if (ledButtonShown() && _me->y() > 1 && _me->y() < 13 && _me->button() == Qt::LeftButton)
const auto pos = position(_me);
if (ledButtonShown() && pos.y() > 1 && pos.y() < 13 && _me->button() == Qt::LeftButton)
{
model()->setValue(!model()->value());
}

View File

@@ -136,15 +136,17 @@ void LcdFloatSpinBox::contextMenuEvent(QContextMenuEvent* event)
void LcdFloatSpinBox::mousePressEvent(QMouseEvent* event)
{
const auto pos = position(event);
// switch between integer and fractional step based on cursor position
m_intStep = event->x() < m_wholeDisplay.width();
m_intStep = pos.x() < m_wholeDisplay.width();
if (event->button() == Qt::LeftButton &&
!(event->modifiers() & KBD_COPY_MODIFIER) &&
event->y() < m_wholeDisplay.cellHeight() + 2)
pos.y() < m_wholeDisplay.cellHeight() + 2)
{
m_mouseMoving = true;
m_origMousePos = event->globalPos();
m_origMousePos = globalPosition(event);
AutomatableModel *thisModel = model();
if (thisModel)
@@ -164,13 +166,14 @@ void LcdFloatSpinBox::mouseMoveEvent(QMouseEvent* event)
{
if (m_mouseMoving)
{
int dy = event->globalY() - m_origMousePos.y();
const auto globalPos = globalPosition(event);
int dy = globalPos.y() - m_origMousePos.y();
if (getGUI()->mainWindow()->isShiftPressed()) { dy = qBound(-4, dy/4, 4); }
if (dy > 1 || dy < -1)
{
model()->setValue(model()->value() - dy / 2 * getStep());
emit manualChange();
m_origMousePos = event->globalPos();
m_origMousePos = globalPos;
}
}
}

View File

@@ -30,6 +30,7 @@
#include "LcdSpinBox.h"
#include "KeyboardShortcuts.h"
#include "CaptionMenu.h"
#include "DeprecationHelper.h"
namespace lmms::gui
@@ -79,12 +80,14 @@ void LcdSpinBox::contextMenuEvent(QContextMenuEvent* event)
void LcdSpinBox::mousePressEvent( QMouseEvent* event )
{
if( event->button() == Qt::LeftButton &&
! (event->modifiers() & KBD_COPY_MODIFIER) &&
event->y() < cellHeight() + 2 )
const auto pos = position(event);
if (event->button() == Qt::LeftButton
&& !(event->modifiers() & KBD_COPY_MODIFIER)
&& pos.y() < cellHeight() + 2)
{
m_mouseMoving = true;
m_lastMousePos = event->globalPos();
m_lastMousePos = globalPosition(event);
AutomatableModel *thisModel = model();
if( thisModel )
@@ -106,7 +109,8 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event )
{
if( m_mouseMoving )
{
int dy = event->globalY() - m_lastMousePos.y();
const auto globalPos = globalPosition(event);
int dy = globalPos.y() - m_lastMousePos.y();
if( dy )
{
auto fdy = static_cast<float>(dy);
@@ -119,7 +123,7 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event )
m_remainder = floatValNotRounded - floatValRounded;
model()->setValue( floatValRounded );
emit manualChange();
m_lastMousePos = event->globalPos();
m_lastMousePos = globalPos;
}
}
}

View File

@@ -39,7 +39,7 @@ SimpleTextFloat::SimpleTextFloat() :
QWidget(getGUI()->mainWindow(), Qt::ToolTip)
{
QHBoxLayout * layout = new QHBoxLayout(this);
layout->setMargin(3);
layout->setContentsMargins(3, 3, 3, 3);
setLayout(layout);
m_textLabel = new QLabel(this);

View File

@@ -123,10 +123,10 @@ void TabWidget::setActiveTab(int idx)
// Return the index of the tab at position "pos"
int TabWidget::findTabAtPos(const QPoint* pos)
int TabWidget::findTabAtPos(const QPoint& pos)
{
if (pos->y() > 1 && pos->y() < m_tabbarHeight - 1)
if (pos.y() > 1 && pos.y() < m_tabbarHeight - 1)
{
int cx = ((m_caption == "") ? 4 : 14) + horizontalAdvance(fontMetrics(), m_caption);
@@ -134,7 +134,7 @@ int TabWidget::findTabAtPos(const QPoint* pos)
{
int const currentWidgetWidth = it->nwidth;
if (pos->x() >= cx && pos->x() <= cx + currentWidgetWidth)
if (pos.x() >= cx && pos.x() <= cx + currentWidgetWidth)
{
return(it.key());
}
@@ -155,7 +155,7 @@ bool TabWidget::event(QEvent* event)
{
auto helpEvent = static_cast<QHelpEvent*>(event);
int idx = findTabAtPos(& helpEvent->pos());
int idx = findTabAtPos(helpEvent->pos());
if (idx != -1)
{
@@ -180,10 +180,8 @@ bool TabWidget::event(QEvent* event)
// Activate tab when clicked
void TabWidget::mousePressEvent(QMouseEvent* me)
{
// Find index of tab that has been clicked
QPoint pos = me->pos();
int idx = findTabAtPos(&pos);
const int idx = findTabAtPos(position(me));
// When found, activate tab that has been clicked
if (idx != -1)