diff --git a/.clang-format b/.clang-format index 48efc78b9871..0d3daf194f9f 100644 --- a/.clang-format +++ b/.clang-format @@ -31,15 +31,14 @@ SpacesBeforeTrailingComments: 1 # StatementMacros don't require a trailing semicolon. # Trailing semicolons should be omitted after these macros # when compiling with -Wpedantic to avoid warnings. -# TODO: Enable if Clang 8 is available, Ubuntu 18.04 uses Clang 6 -#StatementMacros: -# - Q_DECLARE_FLAGS -# - Q_DECLARE_METATYPE -# - Q_DECLARE_OPERATORS_FOR_FLAGS -# - Q_OBJECT -# - Q_PROPERTY -# - Q_UNUSED -# - QT_REQUIRE_VERSION +StatementMacros: + - Q_DECLARE_FLAGS + - Q_DECLARE_METATYPE + - Q_DECLARE_OPERATORS_FOR_FLAGS + - Q_OBJECT + - Q_PROPERTY + - Q_UNUSED + - QT_REQUIRE_VERSION --- Language: JavaScript # Don't format .js files yet diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dce6fd12194b..ef9513853f96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -157,8 +157,11 @@ jobs: # Possibly related: actions/checkout#290 run: git fetch origin --force --tags - - name: "Set up cmake" - uses: jwlawson/actions-setup-cmake@v1.4 + - name: "[macOS] Set up cmake" + uses: jwlawson/actions-setup-cmake@v1.9 + # Ubuntu 20.04 should use the CMake version from the repos, and Visual + # Studio on Windows comes with its own CMake version anyway. + if: runner.os == 'macOS' with: # This should always match the mininum required version in # our CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 43f47347b2e8..6fae99978152 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2349,12 +2349,19 @@ if(COREAUDIO) target_include_directories(mixxx-lib SYSTEM PUBLIC lib/apple) endif() + # FAAD AAC audio file decoder plugin find_package(MP4) find_package(MP4v2) # It is enabled by default on Linux only, because other targets have other # solutions. It requires MP4 or MP4v2. -default_option(FAAD "FAAD AAC audio file decoder support" "UNIX;NOT APPLE;(MP4_FOUND OR MP4v2_FOUND)") +# Note, we use if() here, because the following line does not work with cmake 3.16.3 +# default_option(FAAD "FAAD AAC audio file decoder support" "UNIX;NOT APPLE;(MP4_FOUND OR MP4v2_FOUND)") +if (UNIX AND NOT APPLE AND (MP4_FOUND OR MP4v2_FOUND)) + option(FAAD "FAAD AAC audio file decoder support" ON) +else() + option(FAAD "FAAD AAC audio file decoder support" OFF) +endif() if(FAAD) if(NOT MP4_FOUND AND NOT MP4v2_FOUND) message(FATAL_ERROR "FAAD AAC audio support requires libmp4 or libmp4v2 with development headers.") diff --git a/packaging/CPackDebInstall.cmake b/packaging/CPackDebInstall.cmake index b4eff0d867ef..16e99ecb72da 100644 --- a/packaging/CPackDebInstall.cmake +++ b/packaging/CPackDebInstall.cmake @@ -27,7 +27,7 @@ endif() message( NOTICE "Creating temporary debian folder for debhelper" ) file(COPY ${CPACK_DEBIAN_SOURCE_DIR}/packaging/debian DESTINATION ${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}) -set(CPACK_DEBIAN_PACKAGE_BUILD_DEPENDS_EXTRA "libavcodec-dev, libavutil-dev,") +set(CPACK_DEBIAN_PACKAGE_BUILD_DEPENDS_EXTRA "libavformat-dev, ") configure_file(${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/debian/control.in ${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/debian/control @ONLY) diff --git a/packaging/CPackDebUploadPPA.cmake b/packaging/CPackDebUploadPPA.cmake index 5a127f9d68ed..daaa59a81261 100644 --- a/packaging/CPackDebUploadPPA.cmake +++ b/packaging/CPackDebUploadPPA.cmake @@ -98,7 +98,7 @@ foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES}) if (RELEASE STREQUAL "bionic") set(CPACK_DEBIAN_PACKAGE_BUILD_DEPENDS_EXTRA "libmp4v2-dev,") else() - set(CPACK_DEBIAN_PACKAGE_BUILD_DEPENDS_EXTRA "libavcodec-dev, libavutil-dev,") + set(CPACK_DEBIAN_PACKAGE_BUILD_DEPENDS_EXTRA "libavformat-dev,") endif() configure_file(${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/packaging/debian/control.in diff --git a/res/controllers/Pioneer-DDJ-200-scripts.js b/res/controllers/Pioneer-DDJ-200-scripts.js index a48cdb1225e6..5cfc72745977 100644 --- a/res/controllers/Pioneer-DDJ-200-scripts.js +++ b/res/controllers/Pioneer-DDJ-200-scripts.js @@ -181,7 +181,7 @@ DDJ200.headmix = function(channel, control, value) { if (value) { // do nothing if button is released, i.e. value === 0 var masterMixEnabled = (engine.getValue("[Master]", "headMix") > 0); engine.setValue("[Master]", "headMix", masterMixEnabled ? -1 : 1); - midi.sendShortMsg(0x96, 0x63, masterMixEnabled ? 0x7F : 0); // set LED + midi.sendShortMsg(0x96, 0x63, masterMixEnabled ? 0 : 0x7F); // set LED } }; diff --git a/res/skins/Deere/deck_waveform.xml b/res/skins/Deere/deck_waveform.xml index 52a290eb3fa6..344879676d4c 100644 --- a/res/skins/Deere/deck_waveform.xml +++ b/res/skins/Deere/deck_waveform.xml @@ -83,16 +83,16 @@ intro_start_position [Skin],show_intro_outro_cues - |◢ - bottom + + bottom|right #0000FF #FFFFFF intro_end_position [Skin],show_intro_outro_cues - ◢| - bottom + + bottom|left #0000FF #FFFFFF @@ -107,16 +107,16 @@ outro_start_position [Skin],show_intro_outro_cues - |◣ - bottom + + bottom|right #0000FF #FFFFFF outro_end_position [Skin],show_intro_outro_cues - ◣| - bottom + + bottom|left #0000FF #FFFFFF diff --git a/res/skins/Deere/image/style_branch_closed.png b/res/skins/Deere/image/style_branch_closed.png deleted file mode 100644 index aac367c5b22a..000000000000 Binary files a/res/skins/Deere/image/style_branch_closed.png and /dev/null differ diff --git a/res/skins/Deere/image/style_branch_closed.svg b/res/skins/Deere/image/style_branch_closed.svg new file mode 100644 index 000000000000..b0db7fc42bb1 --- /dev/null +++ b/res/skins/Deere/image/style_branch_closed.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Deere/image/style_branch_open.png b/res/skins/Deere/image/style_branch_open.png deleted file mode 100644 index 56ae3993ef5d..000000000000 Binary files a/res/skins/Deere/image/style_branch_open.png and /dev/null differ diff --git a/res/skins/Deere/image/style_branch_open.svg b/res/skins/Deere/image/style_branch_open.svg new file mode 100644 index 000000000000..c3099a9e8de9 --- /dev/null +++ b/res/skins/Deere/image/style_branch_open.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 3db9b57ba3bd..f93114a9c1a3 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -263,7 +263,6 @@ WLibrary QLineEdit, border: 1px solid #006596; } - /* checkbox in library "Played" column */ WTrackTableView::indicator:checked { image: url(skin:/../Deere/icon/ic_library_checkmark.svg); @@ -274,7 +273,8 @@ WTrackTableView::indicator:unchecked { } /* focused BPM cell in the library "BPM" column */ -#LibraryBPMButton:focus { +#LibraryBPMButton:focus +#LibraryBPMButton::indicator:focus { outline: none; } /* BPM lock icon */ @@ -341,7 +341,7 @@ WTrackTableViewHeader { WTrackTableViewHeader::section { height: 1.1em; font-weight: bold; - padding: 2px; + padding: 0.1em; background-color: #1A1A1A; border-top: none; border-left: none; @@ -423,12 +423,12 @@ WLibrarySidebar::item:focus { /* triangle for closed/opened branches in treeview */ WLibrarySidebar::branch:has-children:!has-siblings:closed, WLibrarySidebar::branch:closed:has-children:has-siblings { - border-image: none; image: url(skin:/../Deere/image/style_branch_closed.png); + border-image: none; image: url(skin:/../Deere/image/style_branch_closed.svg); } WLibrarySidebar::branch:open:has-children:!has-siblings, WLibrarySidebar::branch:open:has-children:has-siblings { - border-image: none; image: url(skin:/../Deere/image/style_branch_open.png); + border-image: none; image: url(skin:/../Deere/image/style_branch_open.svg); } /* space left of selected child item */ @@ -1892,20 +1892,6 @@ do not highlight either state. */ /* common styles for WEffectSelector, QMenu, QToolTip */ -QToolTip, -#MainMenu QMenu, -WLibrarySidebar QMenu, -WTrackTableViewHeader QMenu, -WLibraryTextBrowser QMenu, -WTrackMenu, -WTrackMenu QMenu, -QLineEdit QMenu, -WCueMenuPopup, -WCoverArtMenu, -WEffectSelector QAbstractScrollArea, -#fadeModeCombobox QAbstractScrollArea { - padding: 2px; -} WEffectSelector QAbstractScrollArea, #fadeModeCombobox QAbstractScrollArea { font: 13px; @@ -2005,22 +1991,6 @@ WEffectSelector QAbstractScrollArea, margin-bottom: 0px; padding-bottom: 0px; } -/* Checkbox preceeding menu items (Options, ) */ -#MainMenu QMenu::indicator { -/* Make it big: the highlighted background of the hovered box - should be as tall as the text highlight */ - width: 1em; - height: 1em; -/* In all other menus the checkboxes are compiled from a css - border and a SVG checkmark icon individually per state - (i.e. indeterminate, checked:selected, checked:disabled) - - In the menu bar we only need to display two states - * checked / checked:selected - * unchecked / unchecked:selected - and we want identical appearance on both Wind'ohs and Linux - (avoid rendering issues) thus we use complete SVG checkboxes. */ - } #MainMenu QMenu::indicator:checked, #MainMenu QMenu::indicator:checked:selected { image: url(skin:/../Deere/icon/ic_mainmenu_checkbox_checked.svg); @@ -2035,18 +2005,12 @@ WEffectSelector QAbstractScrollArea, border: 1px solid #888; border-radius: 2px; } - #MainMenu QMenu::separator { - height: 0px; - margin: 0.25em; - } - #MainMenu QMenu::right-arrow { + #MainMenu QMenu::right-arrow, + WTrackMenu::right-arrow, + WTrackMenu QMenu::right-arrow { width: 0.7em; height: 0.7em; - } - - #MainMenu QMenu::indicator { - width: 1em; - height: 1em; + image: url(skin:/../Deere/icon/ic_chevron_right_48px.svg); } @@ -2117,72 +2081,19 @@ WEffectSelector::indicator:unchecked, border: 0px solid transparent; } -WLibrarySidebar QMenu::separator, -WTrackMenu::separator, -WTrackMenu QMenu::separator, -QLineEdit QMenu::separator { - height: 0px; - margin: 4px; -} #MainMenu QMenu::separator, WLibrarySidebar QMenu::separator, WTrackTableViewHeader QMenu::separator, WTrackMenu::separator, WTrackMenu QMenu::separator, +WLibraryTextBrowser QMenu::separator, QLineEdit QMenu::separator { - border-top: 1px solid #0a0a0a; -} - -/* All menus that have at least one item with a checkbox*/ -WLibrarySidebar QMenu::item, -WTrackTableViewHeader QMenu::item, -#CratesMenu::item { -/* padding-right reserves space for the submenu expand arrow - padding-left should be bigger than the menu icon width + - icon margin-left/-right */ - padding: 5px 12px 5px 26px; -} - -WTrackMenu::item, -WTrackMenu QMenu::item, -/* This catches context menus of - - property cells in the tracks table - - WCueMenuPopup cue label editor - - WBeatSpinBox - - AutoDJ transition QSpinBox*/ -QLineEdit QMenu::item, -WCoverArtMenu::item, -/* for the sake of completeness: html root view of Crates, Rec etc. */ -WLibraryTextBrowser QMenu::item { - padding: 5px 12px 5px 12px; -} - -/* Icons in those menus (copy, paste, cut, delete) */ -QLineEdit QMenu::icon, -WLibraryTextBrowser QMenu::icon, -/* - checkbox in Crate name context menu - "[ ] Auto DJ Track Source" */ -WLibrarySidebar QMenu::indicator, -/* Column checkboxes in the table header menu */ -WTrackTableViewHeader QMenu::indicator { - /* Qt 5.12.8: negative margin-right increases the overall item width but has no effect - on the indicator itself. - positive margin-right pushes icon to the right... - Qt 5.15.2: needs negative margin-right in order to eliminate the item's - padding-left (necessary to avoid text/icon overlap); */ - margin: 0px -20px 0px 5px; -} - -/* items in Crate sub menu */ -WTrackMenu QMenu QCheckBox { - padding: 3px 10px 3px 5px; + border-top: 1px solid #999; } WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 13px; - height: 13px; border: 1px solid #555; border-radius: 1px; background-color: #0f0f0f; @@ -2190,28 +2101,20 @@ WTrackMenu QMenu QCheckBox::indicator { outline: none; } -WTrackMenu::right-arrow, -WTrackMenu QMenu::right-arrow, -WTrackTableView::indicator { - width: 10px; - height: 10px; -} - QLineEdit QMenu::icon:selected, WLibrarySidebar QMenu::indicator:selected, WTrackTableViewHeader QMenu::indicator:selected, WTrackMenu QMenu QCheckBox::indicator:selected { border: 1px solid #999; } -/* disabled menu item and checkbox */ +/* disabled menu items and checkboxes */ #MainMenu::item:disabled, #MainMenu QMenu::item:disabled, WLibrarySidebar QMenu::item:disabled, WTrackMenu::item:disabled, WTrackMenu QMenu::item:disabled, WTrackMenu QMenu QCheckBox:disabled, -QLineEdit QMenu::item:disabled, -WCoverArtMenu::item:disabled { +QLineEdit QMenu::item:disabled { color: #555; } WTrackMenu QMenu QCheckBox::indicator:disabled { @@ -2249,12 +2152,6 @@ WTrackMenu QMenu QCheckBox::indicator:disabled:unchecked { border: 1px solid #222; } -#MainMenu QMenu::right-arrow, -WTrackMenu::right-arrow, -WTrackMenu QMenu::right-arrow { - image: url(skin:/../Deere/icon/ic_chevron_right_48px.svg); -} - /* explicitly remove icons from unchecked items otherwise selected, unchecked items would have a checkmark */ WLibrarySidebar QMenu::indicator:unchecked, diff --git a/res/skins/LateNight/classic/style/library_branch_closed.svg b/res/skins/LateNight/classic/style/library_branch_closed.svg new file mode 100644 index 000000000000..ad6d30065092 --- /dev/null +++ b/res/skins/LateNight/classic/style/library_branch_closed.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/LateNight/classic/style/library_branch_closed_grey.png b/res/skins/LateNight/classic/style/library_branch_closed_grey.png deleted file mode 100644 index aac367c5b22a..000000000000 Binary files a/res/skins/LateNight/classic/style/library_branch_closed_grey.png and /dev/null differ diff --git a/res/skins/LateNight/classic/style/library_branch_closed_selected.svg b/res/skins/LateNight/classic/style/library_branch_closed_selected.svg new file mode 100644 index 000000000000..7622ad9def38 --- /dev/null +++ b/res/skins/LateNight/classic/style/library_branch_closed_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/LateNight/classic/style/library_branch_closed_selected_white.png b/res/skins/LateNight/classic/style/library_branch_closed_selected_white.png deleted file mode 100644 index d55311cfc0d6..000000000000 Binary files a/res/skins/LateNight/classic/style/library_branch_closed_selected_white.png and /dev/null differ diff --git a/res/skins/LateNight/classic/style/library_branch_open.svg b/res/skins/LateNight/classic/style/library_branch_open.svg new file mode 100644 index 000000000000..74c6bcd00343 --- /dev/null +++ b/res/skins/LateNight/classic/style/library_branch_open.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/LateNight/classic/style/library_branch_open_grey.png b/res/skins/LateNight/classic/style/library_branch_open_grey.png deleted file mode 100644 index 56ae3993ef5d..000000000000 Binary files a/res/skins/LateNight/classic/style/library_branch_open_grey.png and /dev/null differ diff --git a/res/skins/LateNight/classic/style/library_branch_open_selected.svg b/res/skins/LateNight/classic/style/library_branch_open_selected.svg new file mode 100644 index 000000000000..2257c7d86b45 --- /dev/null +++ b/res/skins/LateNight/classic/style/library_branch_open_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/LateNight/classic/style/library_branch_open_selected_white.png b/res/skins/LateNight/classic/style/library_branch_open_selected_white.png deleted file mode 100644 index ee4730690ed3..000000000000 Binary files a/res/skins/LateNight/classic/style/library_branch_open_selected_white.png and /dev/null differ diff --git a/res/skins/LateNight/classic/style/menu_arrow_gold.svg b/res/skins/LateNight/classic/style/menu_arrow_gold.svg deleted file mode 100644 index d2d1f009a63b..000000000000 --- a/res/skins/LateNight/classic/style/menu_arrow_gold.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/res/skins/LateNight/palemoon/style/library_branch_closed.svg b/res/skins/LateNight/palemoon/style/library_branch_closed.svg new file mode 100644 index 000000000000..48e5ec111966 --- /dev/null +++ b/res/skins/LateNight/palemoon/style/library_branch_closed.svg @@ -0,0 +1,4 @@ + + + + diff --git a/res/skins/LateNight/palemoon/style/library_branch_closed_grey.png b/res/skins/LateNight/palemoon/style/library_branch_closed_grey.png deleted file mode 100644 index 8db3c12ddba3..000000000000 Binary files a/res/skins/LateNight/palemoon/style/library_branch_closed_grey.png and /dev/null differ diff --git a/res/skins/LateNight/palemoon/style/library_branch_closed_selected.svg b/res/skins/LateNight/palemoon/style/library_branch_closed_selected.svg new file mode 100644 index 000000000000..e3851764d752 --- /dev/null +++ b/res/skins/LateNight/palemoon/style/library_branch_closed_selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/res/skins/LateNight/palemoon/style/library_branch_closed_selected_white.png b/res/skins/LateNight/palemoon/style/library_branch_closed_selected_white.png deleted file mode 100644 index d55311cfc0d6..000000000000 Binary files a/res/skins/LateNight/palemoon/style/library_branch_closed_selected_white.png and /dev/null differ diff --git a/res/skins/LateNight/palemoon/style/library_branch_open.svg b/res/skins/LateNight/palemoon/style/library_branch_open.svg new file mode 100644 index 000000000000..30e668f894f7 --- /dev/null +++ b/res/skins/LateNight/palemoon/style/library_branch_open.svg @@ -0,0 +1,4 @@ + + + + diff --git a/res/skins/LateNight/palemoon/style/library_branch_open_grey.png b/res/skins/LateNight/palemoon/style/library_branch_open_grey.png deleted file mode 100644 index 5f90ac334789..000000000000 Binary files a/res/skins/LateNight/palemoon/style/library_branch_open_grey.png and /dev/null differ diff --git a/res/skins/LateNight/palemoon/style/library_branch_open_selected.svg b/res/skins/LateNight/palemoon/style/library_branch_open_selected.svg new file mode 100644 index 000000000000..f2943f287275 --- /dev/null +++ b/res/skins/LateNight/palemoon/style/library_branch_open_selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/res/skins/LateNight/palemoon/style/library_branch_open_selected_white.png b/res/skins/LateNight/palemoon/style/library_branch_open_selected_white.png deleted file mode 100644 index ee4730690ed3..000000000000 Binary files a/res/skins/LateNight/palemoon/style/library_branch_open_selected_white.png and /dev/null differ diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index a6adbd2cec59..3584169bbe1c 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -24,7 +24,6 @@ WEffectSelector, WEffectSelector QAbstractScrollArea, #fadeModeCombobox, #fadeModeCombobox QAbstractScrollArea, -WLibraryTextBrowser, WLibrary QPushButton, WLibrary QLabel, WLibrary QRadioButton, @@ -86,6 +85,7 @@ WOverview #PassthroughLabel { QToolTip, WLibrarySidebar QMenu, WTrackTableViewHeader QMenu, +WLibraryTextBrowser, WLibraryTextBrowser QMenu, WTrackMenu, WTrackMenu QMenu, @@ -112,30 +112,10 @@ QLabel#labelRecStatistics { margin-bottom: 0px; padding-bottom: 0px; } -/* Checkbox preceeding menu items (Options, ) */ -#MainMenu QMenu::indicator { -/* Make it big: the highlighted background of the hovered box - should be as tall as the text highlight */ - width: 1em; - height: 1em; -} -/* In all other menus the checkboxes are compiled from a css border - and a SVG checkmark icon individually per state - (i.e. indeterminate, checked:selected, checked:disabled) - - In the menu bar we only need to display two states - * checked / checked:selected - * unchecked / unchecked:selected - and we want identical appearance on both Wind'ohs and Linux - (avoid rendering issues) thus we use complete SVG checkboxes. - Checkbox icons are set per theme. */ - -#MainMenu QMenu::separator { - height: 0px; - margin: 0.25em; -} -#MainMenu QMenu::right-arrow { +#MainMenu QMenu::right-arrow, +WTrackMenu::right-arrow, +WTrackMenu QMenu::right-arrow { width: 0.7em; height: 0.7em; } @@ -180,71 +160,9 @@ WEffectSelector::item:selected, border: 0px; } -WLibrarySidebar QMenu::separator, -WLibraryTextBrowser QMenu::separator, -WTrackMenu::separator, -WTrackMenu QMenu::separator, -QLineEdit QMenu::separator { - height: 0px; - margin: 4px; -} - -/* All menus that have at least one item with a checkbox*/ -WLibrarySidebar QMenu::item, -WTrackTableViewHeader QMenu::item, -#CratesMenu::item { -/* padding-right reserves space for the submenu expand arrow - padding-left should be bigger than the menu icon width + - icon margin-left/-right */ - padding: 5px 12px 5px 26px; -} - -WTrackMenu::item, -WTrackMenu QMenu::item, -/* This catches context menus of - - property cells in the tracks table - - WCueMenuPopup cue label editor - - WBeatSpinBox - - AutoDJ transition QSpinBox*/ -QLineEdit QMenu::item, -WCoverArtMenu::item, -/* for the sake of completeness: html root view of Crates, Rec etc. */ -WLibraryTextBrowser QMenu::item { - padding: 5px 12px 5px 12px; -} - -/* Icons in those menus (copy, paste, cut, delete) */ -QLineEdit QMenu::icon, -WLibraryTextBrowser QMenu::icon, -/* - checkbox in Crate name context menu - "[ ] Auto DJ Track Source" */ -WLibrarySidebar QMenu::indicator, -/* Column checkboxes in the table header menu */ -WTrackTableViewHeader QMenu::indicator { - /* Qt 5.12.8: negative margin-right increases the overall item width but has no effect - on the indicator itself. - positive margin-right pushes icon to the right... - Qt 5.15.2: needs negative margin-right in order to eliminate the item's - padding-left (necessary to avoid text/icon overlap); */ - margin: 0px -20px 0px 5px; -} - -/* items in Crate sub menu */ -WTrackMenu QMenu QCheckBox { - padding: 3px 10px 3px 5px; -} - - WTrackMenu::right-arrow, - WTrackMenu QMenu::right-arrow, - WTrackTableView::indicator { - width: 10px; - height: 10px; - } WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 13px; - height: 13px; border: 1px solid #333; border-radius: 1px; background-color: #000; @@ -366,13 +284,13 @@ WTrackTableViewHeader::item { } WTrackTableViewHeader::section { height: 1.1em; - border: 0px; - padding: 2px; + border: 0; + padding: 0.1em; } WTrackTableViewHeader::up-arrow, WTrackTableViewHeader::down-arrow { width: 0.8em; - padding: 0px 3px; + padding: 0 0.15em; } diff --git a/res/skins/LateNight/style_classic.qss b/res/skins/LateNight/style_classic.qss index f5f9f3f633af..bab8b194d519 100644 --- a/res/skins/LateNight/style_classic.qss +++ b/res/skins/LateNight/style_classic.qss @@ -245,7 +245,7 @@ WSearchLineEdit, min-width: 1px; max-width: 1px; margin: 2px 1px; - background: url(skin:/classic/style/fx_separator.svg) no-repeat center center; + image: url(skin:/classic/style/fx_separator.svg) no-repeat center center; } #FxSlotSeparatorH { min-height: 2px; @@ -2302,27 +2302,26 @@ WLibrarySidebar::branch:closed:has-children:!has-siblings:!selected, WLibrarySidebar::branch:closed:has-children:has-siblings:!selected { /* Suppresses that selected sidebar items branch indicator shows wrong color when out of focus ; lp:880588 */ border-image: none; - /* TODO try if oversized icon would be upscaled */ - image: url(skin:/classic/style/library_branch_closed_grey.png); + image: url(skin:/classic/style/library_branch_closed.svg); } /* closed, selected */ WLibrarySidebar::branch:closed:has-children:!has-siblings:selected, WLibrarySidebar::branch:closed:has-children:has-siblings:selected { border-image: none; - image: url(skin:/classic/style/library_branch_closed_selected_white.png); + image: url(skin:/classic/style/library_branch_closed_selected.svg); background-color: #5e4507; } /* open */ WLibrarySidebar::branch:open:has-children:!has-siblings, WLibrarySidebar::branch:open:has-children:has-siblings { border-image: none; - image: url(skin:/classic/style/library_branch_open_grey.png); + image: url(skin:/classic/style/library_branch_open.svg); } /* open, selected */ WLibrarySidebar::branch:open:has-children:!has-siblings:selected, WLibrarySidebar::branch:open:has-children:has-siblings:selected { border-image: none; - image: url(skin:/classic/style/library_branch_open_selected_white.png); + image: url(skin:/classic/style/library_branch_open_selected.svg); background-color: #5e4507; } /* space left of selected child item */ @@ -2340,22 +2339,17 @@ WLibrarySidebar::branch:open:has-children:has-siblings { /************** common styles for WEffectSelector ****************************** *************** QSpinBox, QMenu, QToolTip *************************************/ QToolTip, +#MainMenu QMenu, WLibrarySidebar QMenu, WTrackTableViewHeader QMenu, WLibraryTextBrowser QMenu, WTrackMenu, WTrackMenu QMenu, -WEffectSelector QAbstractScrollArea, -#fadeModeCombobox QAbstractScrollArea, QLineEdit QMenu, WCueMenuPopup, -WCoverArtMenu { - padding: 3px; - border: 1px solid #888; - border-radius: 2px; -} -#MainMenu QMenu { - padding: 0.08em; +WCoverArtMenu, +WEffectSelector QAbstractScrollArea, +#fadeModeCombobox QAbstractScrollArea { border: 1px solid #888; border-radius: 2px; } @@ -2429,10 +2423,10 @@ WEffectSelector::item:selected, background-color: #2a1e03; color: #fff; } - -/* disabled menu item and checkbox */ +/* disabled menu items and checkboxes */ #MainMenu::item:disabled, #MainMenu QMenu::item:disabled, +WLibrarySidebar QMenu::item:disabled, WTrackMenu::item:disabled, WTrackMenu QMenu::item:disabled, WTrackMenu QMenu QCheckBox:disabled, @@ -2507,6 +2501,7 @@ WTrackTableView::indicator { WTrackTableViewHeader QMenu::separator, WTrackMenu::separator, WTrackMenu QMenu::separator, + WLibraryTextBrowser QMenu::separator, QLineEdit QMenu::separator, #SkinSettingsSeparator { border-top: 1px solid #000; diff --git a/res/skins/LateNight/style_palemoon.qss b/res/skins/LateNight/style_palemoon.qss index 6a3452f54369..c08796ddcad8 100644 --- a/res/skins/LateNight/style_palemoon.qss +++ b/res/skins/LateNight/style_palemoon.qss @@ -324,7 +324,7 @@ WSearchLineEdit { #FxFlowIndicatorCollapsed { margin: 0px 0px 0px 0px; - background-image: url(skin:/palemoon/style/fx_flow_horizontal.svg) no-repeat center center; + image: url(skin:/palemoon/style/fx_flow_horizontal.svg) no-repeat center center; } #ToolbarSeparator { margin: 0px 5px; @@ -2203,21 +2203,15 @@ WPushButton#PlayDeck[value="0"] { image: url(skin:/palemoon/buttons/btn__split_active.svg) no-repeat center center; } -#FxExpand, -#SamplerExpand, -#LibExpand { - background-repeat: no-repeat; - background-position: center center; -} #FxExpand[value="0"], #SamplerExpand[value="0"], #LibExpand[value="0"] { - background: url(skin:/palemoon/buttons/btn__expand_dim.svg) no-repeat center center; + image: url(skin:/palemoon/buttons/btn__expand_dim.svg) no-repeat center center; } #FxExpand[value="1"], #SamplerExpand[value="1"], #LibExpand[value="1"] { - background: url(skin:/palemoon/buttons/btn__collapse_dim.svg) no-repeat center center; + image: url(skin:/palemoon/buttons/btn__collapse_dim.svg) no-repeat center center; } #MixModeButton[value="0"] { @@ -2790,11 +2784,11 @@ WLibrary QLabel, WLibrary QRadioButton { } WLibrary QRadioButton::indicator:checked { - background: url(skin:/palemoon/buttons/btn__lib_radio_button_on_blue.svg) center center; + image: url(skin:/palemoon/buttons/btn__lib_radio_button_on_blue.svg) center center; } WLibrary QRadioButton::indicator:unchecked { - background: url(skin:/palemoon/buttons/btn__lib_radio_button_off.svg) center center; + image: url(skin:/palemoon/buttons/btn__lib_radio_button_off.svg) center center; } /* Library feature pushbuttons @@ -2829,26 +2823,26 @@ WLibrarySidebar::branch:closed:has-children:has-siblings:!selected { /* Suppresses that selected sidebar items branch indicator shows wrong color when out of focus ; lp:880588 */ border-image: none; - image: url(skin:/palemoon/style/library_branch_closed_grey.png); + image: url(skin:/palemoon/style/library_branch_closed.svg); } /* closed, selected */ WLibrarySidebar::branch:closed:has-children:!has-siblings:selected, WLibrarySidebar::branch:closed:has-children:has-siblings:selected { border-image: none; - image: url(skin:/palemoon/style/library_branch_closed_selected_white.png); + image: url(skin:/palemoon/style/library_branch_closed_selected.svg); background-color: #2c454f; } /* open */ WLibrarySidebar::branch:open:has-children:!has-siblings, WLibrarySidebar::branch:open:has-children:has-siblings { border-image: none; - image: url(skin:/palemoon/style/library_branch_open_grey.png); + image: url(skin:/palemoon/style/library_branch_open.svg); } /* open, selected */ WLibrarySidebar::branch:open:has-children:!has-siblings:selected, WLibrarySidebar::branch:open:has-children:has-siblings:selected { border-image: none; - image: url(skin:/palemoon/style/library_branch_open_selected_white.png); + image: url(skin:/palemoon/style/library_branch_open_selected.svg); background-color: #2c454f; } /* space left of selected child item */ @@ -2866,6 +2860,7 @@ WLibrarySidebar::branch:open:has-children:has-siblings { /************** common styles for WEffectSelector ****************************** *************** QSpinBox, QMenu, QToolTip *************************************/ QToolTip, +#MainMenu QMenu, WLibrarySidebar QMenu, WTrackTableViewHeader QMenu, WLibraryTextBrowser QMenu, @@ -2876,12 +2871,6 @@ WCueMenuPopup, WCoverArtMenu, WEffectSelector QAbstractScrollArea, #fadeModeCombobox QAbstractScrollArea { - padding: 3px; - border: 1px solid #333; - border-radius: 1px; -} -#MainMenu QMenu { - padding: 0.08em; border: 1px solid #333; border-radius: 1px; } @@ -2958,9 +2947,10 @@ WEffectSelector::item:selected, WCueMenuPopup QPushButton:focus { outline: none; } -/* disabled items */ +/* disabled menu items and checkboxes */ +#MainMenu::item:disabled, #MainMenu QMenu::item:disabled, -#MainMenu QMenu QCheckBox:disabled, +WLibrarySidebar QMenu::item:disabled, WTrackMenu::item:disabled, WTrackMenu QMenu::item:disabled, WTrackMenu QMenu QCheckBox:disabled, @@ -2970,8 +2960,10 @@ QLineEdit QMenu::item:disabled { #MainMenu QMenu::separator, WLibrarySidebar QMenu::separator, + WTrackTableViewHeader QMenu::separator, WTrackMenu::separator, WTrackMenu QMenu::separator, + WLibraryTextBrowser QMenu::separator, QLineEdit QMenu::separator, #SkinSettingsSeparator { border-top: 1px solid #000; diff --git a/res/skins/QMLDemo/AuxiliaryUnit.qml b/res/skins/QMLDemo/AuxiliaryUnit.qml new file mode 100644 index 000000000000..a433cfab3f24 --- /dev/null +++ b/res/skins/QMLDemo/AuxiliaryUnit.qml @@ -0,0 +1,119 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import "Theme" + +Row { + id: root + + property int unitNumber // required + property string group: "[Auxiliary" + unitNumber + "]" + + spacing: 5 + + Skin.VuMeter { + id: vuMeter + + group: root.group + key: "VuMeter" + width: 4 + height: parent.height + } + + Rectangle { + id: gainKnobFrame + + width: 52 + height: width + color: Theme.knobBackgroundColor + radius: 5 + + Skin.ControlKnob { + id: gainKnob + + anchors.centerIn: parent + width: 48 + height: width + arcStart: 0 + group: root.group + key: "pregain" + color: Theme.gainKnobColor + } + + } + + Column { + Skin.SectionText { + width: parent.width + height: root.height / 2 + text: "AUX " + root.unitNumber + } + + Skin.ControlButton { + id: pflButton + + group: root.group + key: "pfl" + text: "PFL" + activeColor: Theme.pflActiveButtonColor + toggleable: true + } + + } + + Skin.EmbeddedBackground { + id: embedded + + height: parent.height + width: 56 + + Skin.OrientationToggleButton { + id: orientationButton + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.verticalCenter + group: root.group + key: "orientation" + color: Theme.crossfaderOrientationColor + } + + Skin.InfoBarButton { + id: fx1Button + + anchors.left: parent.left + anchors.right: parent.horizontalCenter + anchors.top: parent.verticalCenter + anchors.bottom: parent.bottom + group: "[EffectRack1_EffectUnit1]" + key: "group_" + root.group + "_enable" + activeColor: Theme.deckActiveColor + + foreground: Skin.EmbeddedText { + anchors.centerIn: parent + text: "FX1" + } + + } + + Skin.InfoBarButton { + group: "[EffectRack1_EffectUnit2]" + anchors.left: parent.horizontalCenter + anchors.right: parent.right + anchors.top: parent.verticalCenter + anchors.bottom: parent.bottom + key: "group_" + root.group + "_enable" + activeColor: Theme.deckActiveColor + + foreground: Skin.EmbeddedText { + anchors.centerIn: parent + text: "FX2" + } + + } + + } + +} diff --git a/res/skins/QMLDemo/Button.qml b/res/skins/QMLDemo/Button.qml index f667a1185126..133ce7e213f1 100644 --- a/res/skins/QMLDemo/Button.qml +++ b/res/skins/QMLDemo/Button.qml @@ -22,7 +22,7 @@ AbstractButton { PropertyChanges { target: backgroundImage - source: "images/button_pressed.svg" + source: Theme.imgButtonPressed } PropertyChanges { @@ -42,7 +42,7 @@ AbstractButton { PropertyChanges { target: backgroundImage - source: "images/button.svg" + source: Theme.imgButton } PropertyChanges { @@ -62,7 +62,7 @@ AbstractButton { PropertyChanges { target: backgroundImage - source: "images/button.svg" + source: Theme.imgButton } PropertyChanges { @@ -84,7 +84,7 @@ AbstractButton { anchors.fill: parent horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch - source: "images/button.svg" + source: Theme.imgButton border { top: 10 diff --git a/res/skins/QMLDemo/ComboBox.qml b/res/skins/QMLDemo/ComboBox.qml new file mode 100644 index 000000000000..db2e97e0dc68 --- /dev/null +++ b/res/skins/QMLDemo/ComboBox.qml @@ -0,0 +1,63 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import "Theme" + +ComboBox { + id: root + + background: Skin.EmbeddedBackground { + } + + delegate: ItemDelegate { + width: parent.width + highlighted: root.highlightedIndex === index + + contentItem: Text { + text: modelData + color: Theme.deckTextColor + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + background: Rectangle { + radius: 5 + border.width: highlighted ? 1 : 0 + border.color: Theme.deckLineColor + color: "transparent" + } + + } + + contentItem: Text { + leftPadding: 5 + rightPadding: root.indicator.width + root.spacing + text: root.displayText + font: root.font + color: Theme.deckTextColor + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + popup: Popup { + y: root.height + width: root.width + implicitHeight: contentItem.implicitHeight + + contentItem: ListView { + clip: true + implicitHeight: contentHeight + model: root.popup.visible ? root.delegateModel : null + currentIndex: root.highlightedIndex + + ScrollIndicator.vertical: ScrollIndicator { + } + + } + + background: Skin.EmbeddedBackground { + } + + } + +} diff --git a/res/skins/QMLDemo/ControlMiniKnob.qml b/res/skins/QMLDemo/ControlMiniKnob.qml new file mode 100644 index 000000000000..5cdffcac25a5 --- /dev/null +++ b/res/skins/QMLDemo/ControlMiniKnob.qml @@ -0,0 +1,22 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx +import QtQuick 2.12 + +Skin.MiniKnob { + id: root + + property alias group: control.group + property alias key: control.key + + value: control.parameter + onTurned: control.parameter = value + + Mixxx.ControlProxy { + id: control + } + + TapHandler { + onDoubleTapped: control.reset() + } + +} diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index 1c1c106c7e58..a3a35530b10c 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -1,4 +1,5 @@ import "." as Skin +import Mixxx 0.1 as Mixxx import QtQuick 2.12 import QtQuick.Controls 2.12 import "Theme" @@ -8,36 +9,100 @@ Item { property real crossfaderWidth // required - implicitHeight: crossfaderSlider.height + 5 + implicitHeight: crossfader.height - Item { - id: effectUnitLeftPlaceholder + Skin.SectionBackground { + anchors.fill: microphoneRow + } + + Row { + id: microphoneRow anchors.top: parent.top - anchors.left: parent.left anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: crossfader.left + layoutDirection: Qt.RightToLeft + padding: 5 + spacing: 10 + + Skin.MicrophoneUnit { + unitNumber: 1 + } + + Skin.MicrophoneUnit { + unitNumber: 2 + } + + Skin.MicrophoneUnit { + unitNumber: 3 + } + + Skin.MicrophoneUnit { + unitNumber: 4 + } + + Skin.MicrophoneDuckingPanel { + } + } - Skin.ControlSlider { - id: crossfaderSlider + Skin.SectionBackground { + id: crossfader - orientation: Qt.Horizontal anchors.centerIn: parent width: root.crossfaderWidth - group: "[Master]" - key: "crossfader" - barColor: Theme.crossfaderBarColor - barStart: 0.5 - fg: "images/slider_handle_crossfader.svg" - bg: "images/slider_crossfader.svg" + height: crossfaderSlider.height + 20 + + Skin.ControlSlider { + id: crossfaderSlider + + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 5 + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + orientation: Qt.Horizontal + group: "[Master]" + key: "crossfader" + barColor: Theme.crossfaderBarColor + barStart: 0.5 + fg: Theme.imgCrossfaderHandle + bg: Theme.imgCrossfaderBackground + } + } - Item { - id: effectUnitRightPlaceholder + Row { + id: auxiliaryRow + anchors.left: crossfader.right anchors.top: parent.top - anchors.right: parent.right anchors.bottom: parent.bottom + anchors.right: parent.right + padding: 5 + spacing: 10 + + Skin.AuxiliaryUnit { + layoutDirection: Qt.RightToLeft + unitNumber: 1 + } + + Skin.AuxiliaryUnit { + layoutDirection: Qt.RightToLeft + unitNumber: 2 + } + + Skin.AuxiliaryUnit { + layoutDirection: Qt.RightToLeft + unitNumber: 3 + } + + Skin.AuxiliaryUnit { + layoutDirection: Qt.RightToLeft + unitNumber: 4 + } + } } diff --git a/res/skins/QMLDemo/Deck.qml b/res/skins/QMLDemo/Deck.qml index f30c7edcee80..0d10bc96ee9d 100644 --- a/res/skins/QMLDemo/Deck.qml +++ b/res/skins/QMLDemo/Deck.qml @@ -13,10 +13,16 @@ Item { property bool minimized: false property var deckPlayer: Mixxx.PlayerManager.getPlayer(group) + Skin.SectionBackground { + anchors.fill: parent + } + Skin.DeckInfoBar { id: infoBar anchors.leftMargin: 5 + anchors.topMargin: 5 + anchors.rightMargin: 5 anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right @@ -28,6 +34,7 @@ Item { visible: !root.minimized anchors.topMargin: 5 + anchors.rightMargin: 5 anchors.bottomMargin: 5 anchors.top: infoBar.bottom anchors.right: parent.right @@ -37,7 +44,7 @@ Item { key: "rate" barStart: 0.5 barColor: Theme.bpmSliderBarColor - bg: "images/slider_bpm.svg" + bg: Theme.imgBpmSliderBackground FadeBehavior on visible { fadeTarget: rateSlider @@ -98,15 +105,9 @@ Item { key: "group_" + root.group + "_enable" activeColor: Theme.deckActiveColor - foreground: Text { + foreground: Skin.EmbeddedText { anchors.centerIn: parent text: "FX 1" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.bold: true - font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor } } @@ -131,15 +132,9 @@ Item { key: "group_" + root.group + "_enable" activeColor: Theme.deckActiveColor - foreground: Text { + foreground: Skin.EmbeddedText { anchors.centerIn: parent text: "FX 2" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.bold: true - font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor } } @@ -155,18 +150,13 @@ Item { color: infoBar.lineColor } - Text { + Skin.EmbeddedText { id: waveformBarPosition anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: waveformBarHSeparator2.right anchors.leftMargin: 5 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: Theme.fontFamily - font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor text: { const positionSeconds = samplesControl.value / 2 / sampleRateControl.value * playPositionControl.value; if (isNaN(positionSeconds)) @@ -298,6 +288,8 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 5 + anchors.rightMargin: 5 + anchors.bottomMargin: 5 height: 56 visible: !root.minimized @@ -370,15 +362,9 @@ Item { } - DropArea { + Mixxx.PlayerDropArea { anchors.fill: parent - onDropped: { - if (drop.hasUrls) { - let url = drop.urls[0]; - console.log("Dropped URL '" + url + "' on deck " + root.group); - root.deckPlayer.loadTrackFromLocationUrl(url); - } - } + group: root.group } } diff --git a/res/skins/QMLDemo/DeckInfoBar.qml b/res/skins/QMLDemo/DeckInfoBar.qml index de084eaa99d5..6d43f93cd4bd 100644 --- a/res/skins/QMLDemo/DeckInfoBar.qml +++ b/res/skins/QMLDemo/DeckInfoBar.qml @@ -10,9 +10,10 @@ Rectangle { property string group // required property var deckPlayer: Mixxx.PlayerManager.getPlayer(group) - property color textColor: Theme.deckTextColor property color lineColor: Theme.deckLineColor + border.width: 2 + border.color: Theme.deckBackgroundColor radius: 5 height: 56 @@ -91,7 +92,7 @@ Rectangle { } - Text { + Skin.EmbeddedText { id: infoBarTitle text: root.deckPlayer.title @@ -99,11 +100,9 @@ Rectangle { anchors.left: infoBarVSeparator.left anchors.right: infoBarHSeparator1.left anchors.bottom: infoBarVSeparator.bottom - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - font.family: Theme.fontFamily + horizontalAlignment: Text.AlignLeft + font.bold: false font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor } Rectangle { @@ -117,7 +116,7 @@ Rectangle { color: infoBar.lineColor } - Text { + Skin.EmbeddedText { id: infoBarArtist text: root.deckPlayer.artist @@ -126,11 +125,8 @@ Rectangle { anchors.right: infoBarHSeparator1.left anchors.bottom: infoBarHSeparator1.bottom horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - font.family: Theme.fontFamily + font.bold: false font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor } Rectangle { @@ -145,19 +141,14 @@ Rectangle { color: infoBar.lineColor } - Text { + Skin.EmbeddedText { id: infoBarKey + text: root.deckPlayer.keyText anchors.top: infoBarHSeparator1.top anchors.bottom: infoBarVSeparator.top - width: rateSlider.width anchors.right: infoBarHSeparator2.left - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - text: root.deckPlayer.keyText - font.family: Theme.fontFamily - font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor + width: rateSlider.width } Rectangle { @@ -172,20 +163,14 @@ Rectangle { color: infoBar.lineColor } - Text { + Skin.EmbeddedText { id: infoBarRate anchors.top: infoBarHSeparator2.top anchors.bottom: infoBarVSeparator.top - width: rateSlider.width anchors.right: infoBar.right anchors.rightMargin: 5 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - text: bpmControl.value.toFixed(2) - font.family: Theme.fontFamily - font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor + width: rateSlider.width Mixxx.ControlProxy { id: bpmControl @@ -196,7 +181,7 @@ Rectangle { } - Text { + Skin.EmbeddedText { id: infoBarRateRatio property real ratio: ((rateRatioControl.value - 1) * 100).toPrecision(2) @@ -206,11 +191,6 @@ Rectangle { width: rateSlider.width anchors.right: infoBar.right anchors.rightMargin: 5 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.pixelSize: Theme.textFontPixelSize - color: infoBar.textColor text: (ratio > 0) ? "+" + ratio.toFixed(2) : ratio.toFixed(2) Mixxx.ControlProxy { @@ -226,15 +206,18 @@ Rectangle { orientation: Gradient.Horizontal GradientStop { - position: -0.75 + position: 0 color: { - let trackColor = root.deckPlayer.color; - return trackColor ? trackColor : Theme.deckBackgroundColor; + const trackColor = root.deckPlayer.color; + if (!trackColor.valid) + return Theme.deckBackgroundColor; + + return Qt.darker(root.deckPlayer.color, 2); } } GradientStop { - position: 0.5 + position: 1 color: Theme.deckBackgroundColor } diff --git a/res/skins/QMLDemo/DeckRow.qml b/res/skins/QMLDemo/DeckRow.qml index 22506ecba1a2..b4f9cb96a07a 100644 --- a/res/skins/QMLDemo/DeckRow.qml +++ b/res/skins/QMLDemo/DeckRow.qml @@ -22,7 +22,7 @@ Item { PropertyChanges { target: root - implicitHeight: 56 + implicitHeight: 66 } AnchorChanges { @@ -75,7 +75,6 @@ Item { anchors.top: parent.top anchors.left: parent.left anchors.bottom: parent.bottom - anchors.rightMargin: 5 group: root.leftDeckGroup } @@ -100,7 +99,6 @@ Item { anchors.top: parent.top anchors.right: parent.right anchors.bottom: parent.bottom - anchors.leftMargin: 5 group: root.rightDeckGroup } diff --git a/res/skins/QMLDemo/EffectRow.qml b/res/skins/QMLDemo/EffectRow.qml new file mode 100644 index 000000000000..b57f926d28ff --- /dev/null +++ b/res/skins/QMLDemo/EffectRow.qml @@ -0,0 +1,26 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +Row { + id: root + + height: 60 + + Skin.EffectUnit { + id: effectUnit1 + + width: root.width / 2 + height: root.height + unitNumber: 1 + } + + Skin.EffectUnit { + id: effectUnit2 + + width: root.width / 2 + height: root.height + unitNumber: 2 + } + +} diff --git a/res/skins/QMLDemo/EffectUnit.qml b/res/skins/QMLDemo/EffectUnit.qml new file mode 100644 index 000000000000..02b89d26d2ad --- /dev/null +++ b/res/skins/QMLDemo/EffectUnit.qml @@ -0,0 +1,104 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import "Theme" + +Item { + property int unitNumber // required + + Skin.SectionBackground { + anchors.fill: parent + } + + RowLayout { + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: effectSuperKnobFrame.left + anchors.rightMargin: 5 + + Repeater { + model: 3 + + Item { + id: effect + + property string group: "[EffectRack1_EffectUnit" + unitNumber + "_Effect" + (index + 1) + "]" + + height: 50 + Layout.fillWidth: true + + Skin.ControlButton { + id: effectEnableButton + + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.margins: 5 + width: 40 + group: effect.group + key: "enabled" + toggleable: true + text: "ON" + activeColor: Theme.effectColor + } + + Skin.ComboBox { + id: effectSelector + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: effectEnableButton.right + anchors.right: effectMetaKnob.left + anchors.margins: 5 + // TODO: Add a way to retrieve effect names here + model: ["---", "Effect 1", "Effect 2", "Effect 3", "Effect 4"] + } + + Skin.ControlMiniKnob { + id: effectMetaKnob + + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.margins: 5 + arcStart: 0 + width: 40 + group: effect.group + key: "meta" + color: Theme.effectColor + } + + } + + } + + } + + Rectangle { + id: effectSuperKnobFrame + + anchors.margins: 5 + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.bottom + width: height + color: Theme.knobBackgroundColor + radius: 5 + + Skin.ControlKnob { + id: effectSuperKnob + + anchors.centerIn: parent + width: 48 + height: 48 + arcStart: 0 + group: "[EffectRack1_EffectUnit" + unitNumber + "]" + key: "super1" + color: Theme.effectUnitColor + } + + } + +} diff --git a/res/skins/QMLDemo/EmbeddedBackground.qml b/res/skins/QMLDemo/EmbeddedBackground.qml new file mode 100644 index 000000000000..85a2e5f17a96 --- /dev/null +++ b/res/skins/QMLDemo/EmbeddedBackground.qml @@ -0,0 +1,11 @@ +import QtQuick 2.12 +import "Theme" + +Rectangle { + id: root + + border.width: 2 + border.color: Theme.deckBackgroundColor + radius: 5 + color: Theme.embeddedBackgroundColor +} diff --git a/res/skins/QMLDemo/EmbeddedText.qml b/res/skins/QMLDemo/EmbeddedText.qml new file mode 100644 index 000000000000..2902af70490b --- /dev/null +++ b/res/skins/QMLDemo/EmbeddedText.qml @@ -0,0 +1,6 @@ +import "." as Skin +import "Theme" + +Skin.SectionText { + font.pixelSize: Theme.buttonFontPixelSize +} diff --git a/res/skins/QMLDemo/HotcuePopup.qml b/res/skins/QMLDemo/HotcuePopup.qml index a6a1159fcaa0..7a7a76ad2507 100644 --- a/res/skins/QMLDemo/HotcuePopup.qml +++ b/res/skins/QMLDemo/HotcuePopup.qml @@ -81,7 +81,7 @@ Popup { anchors.fill: parent horizontalTileMode: BorderImage.Stretch verticalTileMode: BorderImage.Stretch - source: "images/button.svg" + source: Theme.imgPopupBackground border { top: 10 diff --git a/res/skins/QMLDemo/Knob.qml b/res/skins/QMLDemo/Knob.qml index 0fddb4cd1673..e139dfd28485 100644 --- a/res/skins/QMLDemo/Knob.qml +++ b/res/skins/QMLDemo/Knob.qml @@ -24,7 +24,7 @@ MixxxControls.Knob { anchors.right: parent.right height: width * 7 / 6 fillMode: Image.PreserveAspectFit - source: "images/knob_shadow.svg" + source: Theme.imgKnobShadow } background: Image { @@ -34,7 +34,7 @@ MixxxControls.Knob { anchors.left: parent.left anchors.right: parent.right height: width - source: "images/knob.svg" + source: Theme.imgKnob } foreground: Item { diff --git a/res/skins/QMLDemo/MicrophoneDuckingPanel.qml b/res/skins/QMLDemo/MicrophoneDuckingPanel.qml new file mode 100644 index 000000000000..c209039ada28 --- /dev/null +++ b/res/skins/QMLDemo/MicrophoneDuckingPanel.qml @@ -0,0 +1,62 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx +import QtQuick 2.12 +import "Theme" + +Column { + + enum DuckingMode { + Off, + Auto, + Manual, + NumModes // This always needs to be the last value + } + + Skin.ControlSlider { + width: 50 + height: 26 + orientation: Qt.Horizontal + group: "[Master]" + key: "duckStrength" + barColor: Theme.crossfaderBarColor + barStart: 1 + fg: Theme.imgMicDuckingSliderHandle + bg: Theme.imgMicDuckingSlider + } + + Skin.Button { + id: pflButton + + text: duckingControl.duckingModeName + activeColor: Theme.pflActiveButtonColor + highlight: duckingControl.duckingEnabled + onClicked: duckingControl.nextMode() + + Mixxx.ControlProxy { + id: duckingControl + + property string duckingModeName: { + switch (value) { + case MicrophoneDuckingPanel.DuckingMode.Auto: + return "Auto"; + case MicrophoneDuckingPanel.DuckingMode.Manual: + return "Manual"; + default: + return "Off"; + } + } + property bool duckingEnabled: { + return (value == MicrophoneDuckingPanel.DuckingMode.Auto || value == MicrophoneDuckingPanel.DuckingMode.Manual); + } + + function nextMode() { + value = (value + 1) % MicrophoneDuckingPanel.DuckingMode.NumModes; + } + + group: "[Master]" + key: "talkoverDucking" + } + + } + +} diff --git a/res/skins/QMLDemo/MicrophoneUnit.qml b/res/skins/QMLDemo/MicrophoneUnit.qml new file mode 100644 index 000000000000..aef83afb799f --- /dev/null +++ b/res/skins/QMLDemo/MicrophoneUnit.qml @@ -0,0 +1,125 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import "Theme" + +Row { + id: root + + property int unitNumber // required + property string group: unitNumber === 1 ? "[Microphone]" : "[Microphone" + unitNumber + "]" + + spacing: 5 + + Skin.VuMeter { + id: vuMeter + + group: root.group + key: "VuMeter" + width: 4 + height: parent.height + } + + Rectangle { + id: gainKnobFrame + + width: 52 + height: width + color: Theme.knobBackgroundColor + radius: 5 + + Skin.ControlKnob { + id: gainKnob + + anchors.centerIn: parent + width: 48 + height: width + arcStart: 0 + group: root.group + key: "pregain" + color: Theme.gainKnobColor + } + + } + + Column { + SectionText { + width: parent.width + height: root.height / 2 + text: "MIC " + root.unitNumber + } + + Skin.ControlButton { + id: pflButton + + group: root.group + key: "pfl" + text: "PFL" + activeColor: Theme.pflActiveButtonColor + toggleable: true + } + + } + + Skin.EmbeddedBackground { + id: embedded + + height: parent.height + width: 56 + + Skin.InfoBarButton { + id: talkButton + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: parent.verticalCenter + group: root.group + key: "talkover" + activeColor: Theme.deckActiveColor + + foreground: Skin.EmbeddedText { + anchors.centerIn: parent + text: "TALK" + } + + } + + Skin.InfoBarButton { + id: fx1Button + + anchors.left: parent.left + anchors.right: parent.horizontalCenter + anchors.top: parent.verticalCenter + anchors.bottom: parent.bottom + group: "[EffectRack1_EffectUnit1]" + key: "group_" + root.group + "_enable" + activeColor: Theme.deckActiveColor + + foreground: Skin.EmbeddedText { + anchors.centerIn: parent + text: "FX1" + } + + } + + Skin.InfoBarButton { + group: "[EffectRack1_EffectUnit2]" + anchors.left: parent.horizontalCenter + anchors.right: parent.right + anchors.top: parent.verticalCenter + anchors.bottom: parent.bottom + key: "group_" + root.group + "_enable" + activeColor: Theme.deckActiveColor + + foreground: Skin.EmbeddedText { + anchors.centerIn: parent + text: "FX2" + } + + } + + } + +} diff --git a/res/skins/QMLDemo/MiniKnob.qml b/res/skins/QMLDemo/MiniKnob.qml new file mode 100644 index 000000000000..b55bbc411bfc --- /dev/null +++ b/res/skins/QMLDemo/MiniKnob.qml @@ -0,0 +1,56 @@ +import Mixxx.Controls 0.1 as MixxxControls +import QtQuick 2.12 +import "Theme" + +MixxxControls.Knob { + id: root + + property color color // required + + implicitWidth: background.width + implicitHeight: implicitWidth + arc: true + arcRadius: width * 0.45 + arcOffsetY: width * 0.01 + arcColor: root.color + arcWidth: 2 + angle: 116 + + Image { + id: shadow + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: width * 7 / 6 + fillMode: Image.PreserveAspectFit + source: Theme.imgKnobMiniShadow + } + + background: Image { + id: background + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: width + source: Theme.imgKnobMini + } + + foreground: Item { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: width + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: root.width / 30 + height: 10 + y: height + color: root.color + } + + } + +} diff --git a/res/skins/QMLDemo/Mixer.qml b/res/skins/QMLDemo/Mixer.qml index 9dc04e9591eb..3a208f1e3fb6 100644 --- a/res/skins/QMLDemo/Mixer.qml +++ b/res/skins/QMLDemo/Mixer.qml @@ -1,35 +1,50 @@ +import "." as Skin import QtQuick 2.12 import QtQuick.Controls 2.12 -Row { +Item { id: mixer property string leftDeckGroup // required property string rightDeckGroup // required property bool show4decks: false - spacing: 5 + implicitWidth: content.width + 10 + implicitHeight: content.height + 10 - EqColumn { - group: root.leftDeckGroup + Skin.SectionBackground { + anchors.fill: parent } - MixerColumn { - width: 56 - height: parent.height - group: root.leftDeckGroup - } + Row { + id: content - MixerColumn { - width: 56 - height: parent.height - group: root.rightDeckGroup - } + spacing: 5 + anchors.centerIn: parent + anchors.margins: 5 + + EqColumn { + group: root.leftDeckGroup + } + + MixerColumn { + width: 56 + height: parent.height + group: root.leftDeckGroup + } + + MixerColumn { + width: 56 + height: parent.height + group: root.rightDeckGroup + } + + EqColumn { + width: 56 + height: parent.height + group: root.rightDeckGroup + } - EqColumn { - width: 56 - height: parent.height - group: root.rightDeckGroup } } diff --git a/res/skins/QMLDemo/MixerColumn.qml b/res/skins/QMLDemo/MixerColumn.qml index 8ddb5be466fd..3bf931542183 100644 --- a/res/skins/QMLDemo/MixerColumn.qml +++ b/res/skins/QMLDemo/MixerColumn.qml @@ -64,7 +64,7 @@ Item { group: root.group key: "volume" barColor: Theme.volumeSliderBarColor - bg: "images/slider_volume.svg" + bg: Theme.imgVolumeSliderBackground } } diff --git a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml index ad7a709b1a39..303ef760774a 100644 --- a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml +++ b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml @@ -15,15 +15,21 @@ Item { property real angle: 130 property bool arc: false property real arcRadius: width / 2 + property real arcStart: (max - min) / 2 property real arcOffsetX: 0 property real arcOffsetY: 0 property alias arcColor: arcPath.strokeColor property alias arcWidth: arcPath.strokeWidth property alias arcStyle: arcPath.strokeStyle property alias arcStylePattern: arcPath.dashPattern + readonly property real valueCenter: (max - min) / 2 signal turned(real value) + function angleFrom(targetValue) { + return targetValue * 2 * root.angle; + } + Item { id: background @@ -34,7 +40,7 @@ Item { id: foreground anchors.fill: parent - rotation: (root.value - (root.max - root.min) / 2) * 2 * root.angle + rotation: root.angleFrom(root.value - root.valueCenter) } Shape { @@ -50,8 +56,8 @@ Item { fillColor: "transparent" PathAngleArc { - startAngle: -90 - sweepAngle: (root.value - (root.max - root.min) / 2) * 2 * root.angle + startAngle: root.angleFrom(root.arcStart - root.valueCenter) - 90 + sweepAngle: root.angleFrom(root.value - root.arcStart) radiusX: root.arcRadius radiusY: root.arcRadius centerX: root.width / 2 + root.arcOffsetX diff --git a/res/skins/QMLDemo/Mixxx/PlayerDropArea.qml b/res/skins/QMLDemo/Mixxx/PlayerDropArea.qml new file mode 100644 index 000000000000..53a81a931610 --- /dev/null +++ b/res/skins/QMLDemo/Mixxx/PlayerDropArea.qml @@ -0,0 +1,16 @@ +import Mixxx 0.1 as Mixxx +import QtQuick 2.12 + +// Handles drops on decks and samplers +DropArea { + property string group // required + property var player: Mixxx.PlayerManager.getPlayer(group) + + onDropped: { + if (drop.hasUrls) { + let url = drop.urls[0]; + console.log("Dropped URL '" + url + "' on deck " + group); + player.loadTrackFromLocationUrl(url); + } + } +} diff --git a/res/skins/QMLDemo/Mixxx/qmldir b/res/skins/QMLDemo/Mixxx/qmldir index 8b7f31169caf..d2b42c2d4fb7 100644 --- a/res/skins/QMLDemo/Mixxx/qmldir +++ b/res/skins/QMLDemo/Mixxx/qmldir @@ -1,2 +1,3 @@ module Mixxx MathUtils 0.1 MathUtils.mjs +PlayerDropArea 0.1 PlayerDropArea.qml diff --git a/res/skins/QMLDemo/Sampler.qml b/res/skins/QMLDemo/Sampler.qml new file mode 100644 index 000000000000..ca56973c3896 --- /dev/null +++ b/res/skins/QMLDemo/Sampler.qml @@ -0,0 +1,176 @@ +import "." as Skin +import Mixxx 0.1 as Mixxx +import Mixxx.Controls 0.1 as MixxxControls +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.11 +import "Theme" + +Rectangle { + id: root + + property string group // required + property bool minimized: false + property var deckPlayer: Mixxx.PlayerManager.getPlayer(group) + + color: { + const trackColor = root.deckPlayer.color; + if (!trackColor.valid) + return Theme.backgroundColor; + + return Qt.darker(root.deckPlayer.color, 2); + } + implicitHeight: gainKnob.height + 10 + + Skin.SectionBackground { + anchors.fill: parent + } + + Skin.EmbeddedBackground { + id: embedded + + anchors.margins: 5 + anchors.top: parent.top + anchors.left: parent.left + anchors.right: vuMeter.left + anchors.bottom: parent.bottom + } + + Skin.ControlMiniKnob { + id: gainKnob + + anchors.margins: 5 + anchors.top: parent.top + anchors.right: parent.right + height: 40 + width: 40 + group: root.group + key: "pregain" + color: Theme.samplerColor + } + + Skin.ControlButton { + id: playButton + + anchors.top: embedded.top + anchors.left: embedded.left + activeColor: Theme.samplerColor + width: 40 + height: 40 + text: "Play" + group: root.group + key: "cue_gotoandplay" + highlight: playControl.playing + } + + Text { + id: label + + text: root.deckPlayer.title + anchors.top: embedded.top + anchors.left: playButton.right + anchors.right: embedded.right + anchors.margins: 5 + elide: Text.ElideRight + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + color: Theme.deckTextColor + } + + Rectangle { + id: progressContainer + + anchors.margins: 5 + anchors.left: playButton.right + anchors.right: embedded.right + anchors.bottom: embedded.bottom + height: 5 + radius: height / 2 + color: "transparent" + border.color: Theme.deckLineColor + border.width: 1 + + Rectangle { + antialiasing: false // for performance reasons + width: playPositionControl.value * parent.width + height: parent.height + radius: height / 2 + color: Theme.samplerColor + + Mixxx.ControlProxy { + id: playPositionControl + + group: root.group + key: "playposition" + } + + } + + MouseArea { + anchors.fill: progressContainer + cursorShape: Qt.PointingHandCursor + hoverEnabled: true + onPressed: { + playPositionControl.value = mouse.x / width; + } + onPositionChanged: { + if (containsPress) + playPositionControl.value = mouse.x / width; + + } + } + + } + + Skin.VuMeter { + id: vuMeter + + group: root.group + key: "VuMeter" + width: 4 + anchors.margins: 5 + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: gainKnob.left + } + + Mixxx.ControlProxy { + id: playControl + + readonly property bool playing: value != 0 + + function stop() { + value = 0; + } + + group: root.group + key: "play" + } + + Mixxx.ControlProxy { + id: ejectControl + + function trigger() { + value = 1; + value = 0; + } + + group: root.group + key: "eject" + } + + TapHandler { + onDoubleTapped: { + if (playControl.playing) + playControl.stop(); + else + ejectControl.trigger(); + } + } + + Mixxx.PlayerDropArea { + anchors.fill: parent + group: root.group + } + +} diff --git a/res/skins/QMLDemo/SamplerRow.qml b/res/skins/QMLDemo/SamplerRow.qml new file mode 100644 index 000000000000..5b818c921d35 --- /dev/null +++ b/res/skins/QMLDemo/SamplerRow.qml @@ -0,0 +1,18 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Layouts 1.12 + +RowLayout { + spacing: 0 + + Repeater { + model: 8 + + Skin.Sampler { + Layout.fillWidth: true + group: "[Sampler" + (index + 1) + "]" + } + + } + +} diff --git a/res/skins/QMLDemo/SectionBackground.qml b/res/skins/QMLDemo/SectionBackground.qml new file mode 100644 index 000000000000..ba87d98c60bd --- /dev/null +++ b/res/skins/QMLDemo/SectionBackground.qml @@ -0,0 +1,16 @@ +import QtQuick 2.12 +import "Theme" + +BorderImage { + horizontalTileMode: BorderImage.Stretch + verticalTileMode: BorderImage.Stretch + source: Theme.imgSectionBackground + + border { + top: 10 + left: 10 + right: 10 + bottom: 10 + } + +} diff --git a/res/skins/QMLDemo/SectionText.qml b/res/skins/QMLDemo/SectionText.qml new file mode 100644 index 000000000000..804fabb06e76 --- /dev/null +++ b/res/skins/QMLDemo/SectionText.qml @@ -0,0 +1,12 @@ +import QtQuick 2.12 +import "Theme" + +Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + font.bold: true + color: Theme.buttonNormalColor +} diff --git a/res/skins/QMLDemo/Slider.qml b/res/skins/QMLDemo/Slider.qml index 7a5d67d09012..7d7a83006d78 100644 --- a/res/skins/QMLDemo/Slider.qml +++ b/res/skins/QMLDemo/Slider.qml @@ -20,7 +20,7 @@ MixxxControls.Slider { id: handleImage visible: false - source: "images/slider_handle.svg" + source: Theme.imgSliderHandle fillMode: Image.PreserveAspectFit } @@ -49,7 +49,7 @@ MixxxControls.Slider { id: backgroundImage anchors.fill: parent - anchors.margins: 10 + anchors.margins: root.barMargin } } diff --git a/res/skins/QMLDemo/Theme/Theme.qml b/res/skins/QMLDemo/Theme/Theme.qml index 4bf19a9c3b25..23301140a0b5 100644 --- a/res/skins/QMLDemo/Theme/Theme.qml +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -16,9 +16,12 @@ QtObject { property color eqMidColor: white property color eqLowColor: white property color eqFxColor: red + property color effectColor: yellow + property color effectUnitColor: red property color bpmSliderBarColor: green property color volumeSliderBarColor: blue property color gainKnobColor: blue + property color samplerColor: blue property color crossfaderOrientationColor: lightGray property color crossfaderBarColor: red property color toolbarBackgroundColor: darkGray2 @@ -29,10 +32,26 @@ QtObject { property color knobBackgroundColor: "#262626" property color deckLineColor: darkGray2 property color deckTextColor: lightGray2 + property color embeddedBackgroundColor: "#a0000000" property color buttonNormalColor: midGray property color textColor: lightGray2 property color toolbarActiveColor: white property string fontFamily: "Open Sans" property int textFontPixelSize: 14 property int buttonFontPixelSize: 10 + property string imgButton: "images/button.svg" + property string imgButtonPressed: "images/button_pressed.svg" + property string imgSliderHandle: "images/slider_handle.svg" + property string imgBpmSliderBackground: "images/slider_bpm.svg" + property string imgVolumeSliderBackground: "images/slider_volume.svg" + property string imgCrossfaderHandle: "images/slider_handle_crossfader.svg" + property string imgCrossfaderBackground: "images/slider_crossfader.svg" + property string imgMicDuckingSliderHandle: "images/slider_handle_micducking.svg" + property string imgMicDuckingSlider: "images/slider_micducking.svg" + property string imgPopupBackground: imgButton + property string imgKnob: "images/knob.svg" + property string imgKnobShadow: "images/knob_shadow.svg" + property string imgKnobMini: "images/miniknob.svg" + property string imgKnobMiniShadow: "images/miniknob_shadow.svg" + property string imgSectionBackground: "images/section.svg" } diff --git a/res/skins/QMLDemo/WaveformOverview.qml b/res/skins/QMLDemo/WaveformOverview.qml index 47da4f7770cc..7eb30228c754 100644 --- a/res/skins/QMLDemo/WaveformOverview.qml +++ b/res/skins/QMLDemo/WaveformOverview.qml @@ -1,3 +1,4 @@ +import "." as Skin import Mixxx 0.1 as Mixxx import Mixxx.Controls 0.1 as MixxxControls import QtQuick 2.12 @@ -141,11 +142,8 @@ Item { anchors.fill: parent color: "transparent" - Text { + Skin.SectionText { anchors.centerIn: parent - font.family: Theme.fontFamily - font.pixelSize: Theme.textFontPixelSize - color: Theme.deckTextColor text: "Passthrough Enabled" } diff --git a/res/skins/QMLDemo/images/miniknob.svg b/res/skins/QMLDemo/images/miniknob.svg new file mode 100644 index 000000000000..2c08c5bf93cb --- /dev/null +++ b/res/skins/QMLDemo/images/miniknob.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/miniknob_shadow.svg b/res/skins/QMLDemo/images/miniknob_shadow.svg new file mode 100644 index 000000000000..19d4caa480a3 --- /dev/null +++ b/res/skins/QMLDemo/images/miniknob_shadow.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/section.svg b/res/skins/QMLDemo/images/section.svg new file mode 100644 index 000000000000..d36770819bf2 --- /dev/null +++ b/res/skins/QMLDemo/images/section.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/slider_handle_micducking.svg b/res/skins/QMLDemo/images/slider_handle_micducking.svg new file mode 100644 index 000000000000..9d13c70fbf86 --- /dev/null +++ b/res/skins/QMLDemo/images/slider_handle_micducking.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/images/slider_micducking.svg b/res/skins/QMLDemo/images/slider_micducking.svg new file mode 100644 index 000000000000..b0bf656deb1b --- /dev/null +++ b/res/skins/QMLDemo/images/slider_micducking.svg @@ -0,0 +1,2 @@ + + diff --git a/res/skins/QMLDemo/main.qml b/res/skins/QMLDemo/main.qml index 9a4a3f643bc3..5ff7b56db8b0 100644 --- a/res/skins/QMLDemo/main.qml +++ b/res/skins/QMLDemo/main.qml @@ -8,6 +8,8 @@ Rectangle { id: root property alias show4decks: show4DecksButton.checked + property alias showEffects: showEffectsButton.checked + property alias showSamplers: showSamplersButton.checked property alias maximizeLibrary: maximizeLibraryButton.checked width: 1920 @@ -17,7 +19,6 @@ Rectangle { Column { anchors.fill: parent - spacing: 10 Rectangle { id: toolbar @@ -47,6 +48,22 @@ Rectangle { checkable: true } + Skin.Button { + id: showEffectsButton + + text: "Effects" + activeColor: Theme.white + checkable: true + } + + Skin.Button { + id: showSamplersButton + + text: "Sampler" + activeColor: Theme.white + checkable: true + } + } } @@ -56,8 +73,7 @@ Rectangle { leftDeckGroup: "[Channel1]" rightDeckGroup: "[Channel2]" - width: parent.width - 10 - x: 5 + width: parent.width minimized: root.maximizeLibrary } @@ -65,8 +81,7 @@ Rectangle { id: crossfader crossfaderWidth: decks12.mixer.width - width: parent.width - 10 - x: 5 + width: parent.width visible: !root.maximizeLibrary FadeBehavior on visible { @@ -80,8 +95,7 @@ Rectangle { leftDeckGroup: "[Channel3]" rightDeckGroup: "[Channel4]" - width: parent.width - 10 - x: 5 + width: parent.width minimized: root.maximizeLibrary visible: root.show4decks @@ -91,6 +105,30 @@ Rectangle { } + SamplerRow { + id: samplers + + width: parent.width + visible: root.showSamplers + + FadeBehavior on visible { + fadeTarget: samplers + } + + } + + EffectRow { + id: effects + + width: parent.width + visible: root.showEffects + + FadeBehavior on visible { + fadeTarget: effects + } + + } + Library { width: parent.width height: parent.height - y diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index 865b0226f351..463078e2ce04 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -29,6 +29,7 @@ QToolTip, WOverview #PassthroughLabel, WTrackTableViewHeader, WTrackTableViewHeader QMenu, +WTrackTableViewHeader::section, WLibrarySidebar QMenu, WLibraryTextBrowser, WLibraryTextBrowser QMenu, @@ -201,22 +202,6 @@ WEffectSelector::indicator:unchecked:selected, #MainMenu { margin-bottom: 0px; padding-bottom: 0px; -} -/* Checkbox preceeding menu items (Options, ) */ -#MainMenu QMenu::indicator { -/* Make it big: the highlighted background of the hovered box - should be as tall as the text highlight */ - width: 1em; - height: 1em; -/* In all other menus the checkboxes are compiled from a css - border and a SVG checkmark icon individually per state - (i.e. indeterminate, checked:selected, checked:disabled) - - In the menu bar we only need to display two states - * checked / checked:selected - * unchecked / unchecked:selected - and we want identical appearance on both Wind'ohs and Linux - (avoid rendering issues) thus we use complete SVG checkboxes. */ } #MainMenu QMenu::indicator:checked, #MainMenu QMenu::indicator:checked:selected { @@ -232,19 +217,13 @@ WEffectSelector::indicator:unchecked:selected, border: 1px solid #060613; border-radius: 2px; } - #MainMenu QMenu::separator { - height: 0px; - margin: 0.25em; - } - #MainMenu QMenu::right-arrow { + #MainMenu QMenu::right-arrow, + WTrackMenu::right-arrow, + WTrackMenu QMenu::right-arrow { width: 0.5em; height: 0.5em; margin-right: 0.2em; - } - - #MainMenu QMenu::indicator { - width: 1em; - height: 1em; + image: url(skin:/style/menu_arrow.svg); } WEffectSelector, @@ -258,39 +237,27 @@ WBeatSpinBox, } WEffectSelector QAbstractScrollArea, #fadeModeCombobox QAbstractScrollArea { - padding: 2px; min-width: 160px; } WEffectSelector:!editable, WEffectSelector:!editable:on, -WEffectSelector QAbstractScrollArea, -WEffectSelector::down-arrow, -#fadeModeCombobox QAbstractScrollArea, -#fadeModeCombobox, -#fadeModeCombobox::down-arrow, -#spinBoxTransition, QToolTip, +#MainMenu QMenu, WLibrarySidebar QMenu, +WTrackTableViewHeader QMenu, +WLibraryTextBrowser QMenu, WTrackMenu, WTrackMenu QMenu, QLineEdit QMenu, WCueMenuPopup, -WCoverArtMenu { +WCoverArtMenu, +WEffectSelector QAbstractScrollArea, +#fadeModeCombobox QAbstractScrollArea { border-width: 1px; border-style: solid; border-color: #060613; } -QToolTip, -WLibrarySidebar QMenu, -WTrackMenu, -WTrackMenu QMenu, -QLineEdit QMenu, -WCueMenuPopup, -WCoverArtMenu, -WEffectSelector QAbstractScrollArea, -#fadeModeCombobox QAbstractScrollArea { - padding: 3px; -} + WEffectSelector:!editable, WEffectSelector:!editable:on, #fadeModeCombobox { @@ -383,7 +350,9 @@ WEffectSelector QAbstractScrollArea, /* remove OS focus indicator */ outline: none; } - /* disabled menu item & checkbox */ + /* disabled menu items and checkboxes */ + #MainMenu::item:disabled, + #MainMenu QMenu::item:disabled, WLibrarySidebar QMenu::item:disabled, WTrackMenu::item:disabled, WTrackMenu QMenu::item:disabled, @@ -395,64 +364,12 @@ WEffectSelector QAbstractScrollArea, border-color: #666; } -/* All menus that have at least one item with a checkbox*/ -WLibrarySidebar QMenu::item, -WTrackTableViewHeader QMenu::item, -#CratesMenu::item { -/* padding-right reserves space for the submenu expand arrow - padding-left should be bigger than the menu icon width + - icon margin-left/-right */ - padding: 5px 12px 5px 26px; -} - -WTrackMenu::item, -WTrackMenu QMenu::item, -/* This catches context menus of - - property cells in the tracks table - - WCueMenuPopup cue label editor - - WBeatSpinBox - - AutoDJ transition QSpinBox*/ -QLineEdit QMenu::item, -WCoverArtMenu::item, -/* for the sake of completeness: html root view of Crates, Rec etc. */ -WLibraryTextBrowser QMenu::item { - padding: 5px 12px 5px 12px; -} - -/* Icons in those menus (copy, paste, cut, delete) */ -QLineEdit QMenu::icon, -WLibraryTextBrowser QMenu::icon, -/* - checkbox in Crate name context menu - "[ ] Auto DJ Track Source" */ -WLibrarySidebar QMenu::indicator, -/* Column checkboxes in the table header menu */ -WTrackTableViewHeader QMenu::indicator { - /* Qt 5.12.8: negative margin-right increases the overall item width but has no effect - on the indicator itself. - positive margin-right pushes icon to the right... - Qt 5.15.2: needs negative margin-right in order to eliminate the item's - padding-left (necessary to avoid text/icon overlap); */ - margin: 0px -20px 0px 5px; -} - -/* items in Crate sub menu */ -WTrackMenu QMenu QCheckBox { - padding: 3px 10px 3px 5px; -} - -WLibrarySidebar QMenu::separator, -WTrackTableViewHeader QMenu::separator, -WTrackMenu::separator, -WTrackMenu QMenu::separator, -QLineEdit QMenu::separator { - height: 0px; - margin: 4px; - } #MainMenu QMenu::separator, WLibrarySidebar QMenu::separator, WTrackTableViewHeader QMenu::separator, WTrackMenu::separator, WTrackMenu QMenu::separator, + WLibraryTextBrowser QMenu::separator, QLineEdit QMenu::separator { border-top: 1px solid #71777a; } @@ -460,22 +377,9 @@ QLineEdit QMenu::separator { WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 13px; - height: 13px; border-width: 1px; border-style: solid; } - WTrackMenu::right-arrow, - WTrackMenu QMenu::right-arrow { - width: 10px; - height: 10px; - margin-right: 4px; - } - #MainMenu QMenu::right-arrow, - WTrackMenu::right-arrow, - WTrackMenu QMenu::right-arrow { - image: url(skin:/style/menu_arrow.svg); - } #EffectSelectorGroup[highlight="1"] { border: 1px solid #52f864; @@ -643,8 +547,6 @@ WTrackTableView { /* checkbox in library "Played" column */ WTrackTableView::indicator { - width: 10px; - height: 10px; margin: 0px; padding: 0px; color: #cfcfcf; @@ -712,22 +614,22 @@ WLibrarySidebar { /* Closed branch of tree */ WLibrarySidebar::branch:has-children:!has-siblings:closed, WLibrarySidebar::branch:closed:has-children:has-siblings { - image: url(skin:/style/style_branch_closed.png); + image: url(skin:/style/style_branch_closed.svg); } WLibrarySidebar::branch:has-children:!has-siblings:closed:selected, WLibrarySidebar::branch:closed:has-children:has-siblings:selected { - image: url(skin:/style/style_branch_closed_selected.png); + image: url(skin:/style/style_branch_closed_selected.svg); } /* Open branch of tree */ WLibrarySidebar::branch:open:has-children:!has-siblings, WLibrarySidebar::branch:open:has-children:has-siblings { - image: url(skin:/style/style_branch_open.png); + image: url(skin:/style/style_branch_open.svg); } WLibrarySidebar::branch:open:has-children:!has-siblings:selected, WLibrarySidebar::branch:open:has-children:has-siblings:selected { border-image: none; - image: url(skin:/style/style_branch_open_selected.png); + image: url(skin:/style/style_branch_open_selected.svg); } /* space left of selected child item */ WLibrarySidebar::branch:!has-children:!has-siblings:closed:selected, @@ -759,7 +661,7 @@ WTrackTableViewHeader { /* Library header 'buttons' */ WTrackTableViewHeader::section { height: 1.1em; - padding: 2px 1px 2px 2px; + padding: 0.1em; /* set right border so that first column header on the left doesn't have double border on the left */ border-right: 1px solid #0f0f0f; @@ -769,8 +671,8 @@ WTrackTableViewHeader::section { WTrackTableViewHeader::up-arrow, WTrackTableViewHeader::down-arrow { - width: 12px; - padding-right: 2px; + width: 0.6em; + padding-right: 0.1em; margin-right: 1px; background-color: rgba(98,111,135,255); } diff --git a/res/skins/Shade/style/style_branch_closed.png b/res/skins/Shade/style/style_branch_closed.png deleted file mode 100644 index aac367c5b22a..000000000000 Binary files a/res/skins/Shade/style/style_branch_closed.png and /dev/null differ diff --git a/res/skins/Shade/style/style_branch_closed.svg b/res/skins/Shade/style/style_branch_closed.svg new file mode 100644 index 000000000000..b0db7fc42bb1 --- /dev/null +++ b/res/skins/Shade/style/style_branch_closed.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Shade/style/style_branch_closed_selected.png b/res/skins/Shade/style/style_branch_closed_selected.png deleted file mode 100644 index 082109a21aa2..000000000000 Binary files a/res/skins/Shade/style/style_branch_closed_selected.png and /dev/null differ diff --git a/res/skins/Shade/style/style_branch_closed_selected.svg b/res/skins/Shade/style/style_branch_closed_selected.svg new file mode 100644 index 000000000000..ca65bcc58b3f --- /dev/null +++ b/res/skins/Shade/style/style_branch_closed_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Shade/style/style_branch_open.png b/res/skins/Shade/style/style_branch_open.png deleted file mode 100644 index 56ae3993ef5d..000000000000 Binary files a/res/skins/Shade/style/style_branch_open.png and /dev/null differ diff --git a/res/skins/Shade/style/style_branch_open.svg b/res/skins/Shade/style/style_branch_open.svg new file mode 100644 index 000000000000..c3099a9e8de9 --- /dev/null +++ b/res/skins/Shade/style/style_branch_open.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Shade/style/style_branch_open_selected.png b/res/skins/Shade/style/style_branch_open_selected.png deleted file mode 100644 index c0d06861b1f1..000000000000 Binary files a/res/skins/Shade/style/style_branch_open_selected.png and /dev/null differ diff --git a/res/skins/Shade/style/style_branch_open_selected.svg b/res/skins/Shade/style/style_branch_open_selected.svg new file mode 100644 index 000000000000..b73fd23b60b7 --- /dev/null +++ b/res/skins/Shade/style/style_branch_open_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Shade/style_dark.qss b/res/skins/Shade/style_dark.qss index a6c06f79c3df..c631f00c1548 100644 --- a/res/skins/Shade/style_dark.qss +++ b/res/skins/Shade/style_dark.qss @@ -83,6 +83,7 @@ WEffectSelector::indicator:unchecked:selected, WTrackTableViewHeader QMenu::separator, WTrackMenu::separator, WTrackMenu QMenu::separator, + WLibraryTextBrowser QMenu::separator, QLineEdit QMenu::separator { border-top: 1px solid #3F3041; } @@ -100,7 +101,9 @@ WEffectSelector::indicator:unchecked:selected, border-color: #111; background-color: #897300; } - /* disabled menu item & checkbox */ + /* disabled menu items and checkboxes */ + #MainMenu::item:disabled, + #MainMenu QMenu::item:disabled, WLibrarySidebar QMenu::item:disabled, WTrackMenu::item:disabled, WTrackMenu QMenu::item:disabled, diff --git a/res/skins/Shade/style_summer_sunset.qss b/res/skins/Shade/style_summer_sunset.qss index a0eff389e43a..5f86de1649c1 100644 --- a/res/skins/Shade/style_summer_sunset.qss +++ b/res/skins/Shade/style_summer_sunset.qss @@ -44,11 +44,12 @@ WBeatSpinBox, #spinBoxTransition { background-color: #7b6f38; } - #MainMenu QMenu::separator + #MainMenu QMenu::separator, WLibrarySidebar QMenu::separator, WTrackTableViewHeader QMenu::separator, WTrackMenu::separator, WTrackMenu QMenu::separator, + WLibraryTextBrowser QMenu::separator, QLineEdit QMenu::separator { border-top: 1px solid #222; } diff --git a/res/skins/Shade/waveform.xml b/res/skins/Shade/waveform.xml index ed974b6e874f..739ac9e64a82 100644 --- a/res/skins/Shade/waveform.xml +++ b/res/skins/Shade/waveform.xml @@ -59,43 +59,43 @@ #0000FF 0.1 - - outro_start_position - outro_end_position - [Skin],show_intro_outro_cues - #0000FF - intro_start_position [Skin],show_intro_outro_cues - |◢ - bottom + + bottom|right #0000FF #FFFFFF - intro_end_position [Skin],show_intro_outro_cues - ◢| - bottom + + bottom|left #0000FF - 0.1 #FFFFFF + + + outro_start_position + outro_end_position + [Skin],show_intro_outro_cues + #0000FF + 0.1 + outro_start_position [Skin],show_intro_outro_cues - |◣ - bottom + + bottom|right #0000FF #FFFFFF outro_end_position [Skin],show_intro_outro_cues - ◣| - bottom + + bottom|left #0000FF #FFFFFF diff --git a/res/skins/Tango/graphics/branch_closed.png b/res/skins/Tango/graphics/branch_closed.png deleted file mode 100644 index aac367c5b22a..000000000000 Binary files a/res/skins/Tango/graphics/branch_closed.png and /dev/null differ diff --git a/res/skins/Tango/graphics/branch_closed.svg b/res/skins/Tango/graphics/branch_closed.svg new file mode 100644 index 000000000000..b0db7fc42bb1 --- /dev/null +++ b/res/skins/Tango/graphics/branch_closed.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Tango/graphics/branch_open.png b/res/skins/Tango/graphics/branch_open.png deleted file mode 100644 index 56ae3993ef5d..000000000000 Binary files a/res/skins/Tango/graphics/branch_open.png and /dev/null differ diff --git a/res/skins/Tango/graphics/branch_open.svg b/res/skins/Tango/graphics/branch_open.svg new file mode 100644 index 000000000000..c3099a9e8de9 --- /dev/null +++ b/res/skins/Tango/graphics/branch_open.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index 0e9d0ee8eb45..d5a6ac89993e 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -2144,22 +2144,6 @@ WEffectSelector::indicator:unchecked, #MainMenu { margin-bottom: 0px; padding-bottom: 0px; -} -/* Checkbox preceeding menu items (Options, ) */ -#MainMenu QMenu::indicator { -/* Make it big: the highlighted background of the hovered box - should be as tall as the text highlight */ - width: 1em; - height: 1em; -/* In all other menus the checkboxes are compiled from a css - border and a SVG checkmark icon individually per state - (i.e. indeterminate, checked:selected, checked:disabled) - - In the menu bar we only need to display two states - * checked / checked:selected - * unchecked / unchecked:selected - and we want identical appearance on both Wind'ohs and Linux - (avoid rendering issues) thus we use complete SVG checkboxes. */ } #MainMenu QMenu::indicator:checked, #MainMenu QMenu::indicator:checked:selected { @@ -2175,60 +2159,19 @@ WEffectSelector::indicator:unchecked, border: 1px solid #888; border-radius: 2px; } - #MainMenu QMenu::separator { - height: 0px; - margin: 0.25em 0.06em; - } - #MainMenu QMenu::right-arrow { + #MainMenu QMenu::right-arrow, + WTrackMenu::right-arrow, + WTrackMenu QMenu::right-arrow { width: 0.35em; height: 0.7em; margin-right: 0.2em; + image: url(skin:/../Tango/buttons/btn_arrow_right.svg); + } + #MainMenu QMenu::right-arrow:selected, + WTrackMenu::right-arrow:selected, + WTrackMenu QMenu::right-arrow:selected { + image: url(skin:/../Tango/buttons/btn_arrow_right_hover.svg); } - -/* All menus that have at least one item with a checkbox*/ -WLibrarySidebar QMenu::item, -WTrackTableViewHeader QMenu::item, -#CratesMenu::item { -/* padding-right reserves space for the submenu expand arrow - padding-left should be bigger than the menu icon width + - icon margin-left/-right */ - padding: 5px 12px 5px 26px; -} - -WTrackMenu::item, -WTrackMenu QMenu::item, -/* This catches context menus of - - property cells in the tracks table - - WCueMenuPopup cue label editor - - WBeatSpinBox - - AutoDJ transition QSpinBox*/ -QLineEdit QMenu::item, -WCoverArtMenu::item, -/* for the sake of completeness: html root view of Crates, Rec etc. */ -WLibraryTextBrowser QMenu::item { - padding: 5px 12px 5px 12px; -} - -/* Icons in those menus (copy, paste, cut, delete) */ -QLineEdit QMenu::icon, -WLibraryTextBrowser QMenu::icon, -/* - checkbox in Crate name context menu - "[ ] Auto DJ Track Source" */ -WLibrarySidebar QMenu::indicator, -/* Column checkboxes in the table header menu */ -WTrackTableViewHeader QMenu::indicator { - /* Qt 5.12.8: negative margin-right increases the overall item width but has no effect - on the indicator itself. - positive margin-right pushes icon to the right... - Qt 5.15.2: needs negative margin-right in order to eliminate the item's - padding-left (necessary to avoid text/icon overlap); */ - margin: 0px -20px 0px 5px; -} - -/* items in Crate sub menu */ -WTrackMenu QMenu QCheckBox { - padding: 3px 10px 3px 5px; -} /* Passthrough label on overview waveform */ WOverview #PassthroughLabel { @@ -2270,17 +2213,17 @@ WEffectSelector, WEffectSelector QAbstractScrollArea, color: #ccc; } QToolTip, -WCueMenuPopup, +#MainMenu QMenu, WLibrarySidebar QMenu, WTrackTableViewHeader QMenu, -QLineEdit QMenu, -WCoverArtMenu, +WLibraryTextBrowser QMenu, WTrackMenu, WTrackMenu QMenu, -#SkinSettings, +QLineEdit QMenu, +WCueMenuPopup, +WCoverArtMenu, WEffectSelector QAbstractScrollArea, #fadeModeCombobox QAbstractScrollArea { - padding: 2px; border: 1px solid #888; border-radius: 2px; } @@ -2316,7 +2259,7 @@ WEffectSelector::item:selected { outline: none; } -/* disabled menu items */ +/* disabled menu items and checkboxes */ #MainMenu::item:disabled, #MainMenu QMenu::item:disabled, WLibrarySidebar QMenu::item:disabled, @@ -2327,53 +2270,19 @@ QLineEdit QMenu::item:disabled { color: #555; } -WLibrarySidebar QMenu::separator, -WTrackTableViewHeader QMenu::separator, -WTrackMenu::separator, -WTrackMenu QMenu::separator, -QLineEdit QMenu::separator { - height: 0px; - margin: 4px; - } #MainMenu QMenu::separator, WLibrarySidebar QMenu::separator, WTrackTableViewHeader QMenu::separator, WTrackMenu::separator, WTrackMenu QMenu::separator, + WLibraryTextBrowser QMenu::separator, QLineEdit QMenu::separator { border-top: 1px solid #0a0a0a; } -WTrackMenu::right-arrow, -WTrackMenu QMenu::right-arrow { - width: 8px; - height: 16px; - margin-right: 4px; - } - #MainMenu QMenu::right-arrow, - WTrackMenu::right-arrow, - WTrackMenu QMenu::right-arrow { - image: url(skin:/../Tango/buttons/btn_arrow_right.svg); - } - #MainMenu QMenu::right-arrow:selected, - WTrackMenu::right-arrow:selected, - WTrackMenu QMenu::right-arrow:selected { - image: url(skin:/../Tango/buttons/btn_arrow_right_hover.svg); - } - - WTrackTableViewHeader QMenu::indicator { - width: 10px; - height: 10px; - } - WTrackTableViewHeader QMenu::indicator:checked { - image: url(skin:/../Tango/buttons/btn_lib_checkmark_white.svg); - } - WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 13px; - height: 13px; background-color: #0f0f0f; border: 1px solid #333; border-radius: 1px; @@ -2584,7 +2493,7 @@ WLibrarySidebar { /* Closed branch icon in tree */ WLibrarySidebar::branch:has-children:!has-siblings:closed, WLibrarySidebar::branch:closed:has-children:has-siblings { - image: url(skin:/../Tango/graphics/branch_closed.png); + image: url(skin:/../Tango/graphics/branch_closed.svg); } WLibrarySidebar::branch:has-children:!has-siblings:closed:selected, WLibrarySidebar::branch:closed:has-children:has-siblings:selected { @@ -2594,7 +2503,7 @@ WLibrarySidebar::branch:closed:has-children:has-siblings { /* Open branch icon in tree */ WLibrarySidebar::branch:open:has-children:!has-siblings, WLibrarySidebar::branch:open:has-children:has-siblings { - image: url(skin:/../Tango/graphics/branch_open.png); + image: url(skin:/../Tango/graphics/branch_open.svg); } WLibrarySidebar::branch:open:has-children:!has-siblings:selected, WLibrarySidebar::branch:open:has-children:has-siblings:selected { @@ -2633,7 +2542,7 @@ WTrackTableViewHeader { /* Library header 'buttons' */ WTrackTableViewHeader::section { height: 1.1em; - padding: 0px 2px; + padding: 0 0.1em; /* use 'border-right' so that for the header of the leftmost column the border doesn't add to the border of the surrounding qtableview */ border-right: 1px solid #585858; @@ -2647,8 +2556,8 @@ WTrackTableViewHeader { WTrackTableViewHeader::up-arrow, WTrackTableViewHeader::down-arrow { - width: 12px; - padding-right: 2px; + width: 0.6em; + padding-right: 0.1em; border-right: 1px solid #585858; background-color: rgba(51,51,51,200); } @@ -2994,8 +2903,6 @@ QPushButton#pushButtonRepeatPlaylist:!checked { /* checkbox in library "Played" column */ WTrackTableView::indicator { - width: 10px; - height: 10px; margin: 0px; padding: 0px; color: #cfcfcf; diff --git a/res/skins/Tango/waveform.xml b/res/skins/Tango/waveform.xml index 03418eb8c26c..3225d6a004ce 100644 --- a/res/skins/Tango/waveform.xml +++ b/res/skins/Tango/waveform.xml @@ -76,16 +76,16 @@ Variables: intro_start_position [Skin],show_intro_outro_cues - |◢ - bottom + + bottom|right #0000FF #FFFFFF intro_end_position [Skin],show_intro_outro_cues - ◢| - bottom + + bottom|left #0000FF #FFFFFF @@ -99,16 +99,16 @@ Variables: outro_start_position [Skin],show_intro_outro_cues - |◣ - bottom + + bottom|right #0000FF #FFFFFF outro_end_position [Skin],show_intro_outro_cues - ◣| - bottom + + bottom|left #0000FF #FFFFFF diff --git a/res/skins/default-menu-styles-linux.qss b/res/skins/default-menu-styles-linux.qss index 671939165902..e014dbe17e22 100644 --- a/res/skins/default-menu-styles-linux.qss +++ b/res/skins/default-menu-styles-linux.qss @@ -21,5 +21,5 @@ margin-right: negative to eliminate the tiny margin between checkbox and text (visible when the row is highlighted) */ margin: 0em -0.1em 0em -1.3em; - padding: 0.2em 0em 0.2em 0em; + padding: 0.3em 0em 0.3em 0em; } diff --git a/res/skins/default.qss b/res/skins/default.qss index 91cd71887fb0..e7090c3cf692 100644 --- a/res/skins/default.qss +++ b/res/skins/default.qss @@ -11,6 +11,14 @@ image: url(:/images/library/ic_library_preview_play.svg); } +/* These library table indicators are scaled with the library font: +checkbox next to the 'Played' counter */ +WTrackTableView::indicator, +/* BPM lock icon */ +#LibraryBPMButton::indicator { + width: 0.5em; + height: 0.5em; +} /* Style the library BPM Button with a default image */ QPushButton#LibraryBPMButton { background: transparent; border: 0; @@ -73,3 +81,91 @@ WOverview #PassthroughLabel { #SearchClearButton:focus { image: url(:/images/library/ic_library_cross_orange.svg); } + + +#MainMenu QMenu::indicator { + width: 1em; + height: 1em; +} + +/* Lay out all context menus and the track table header with relative sizes, +adjusting to the system-chosen font (size). Same is done for the Played checkedbox +and the BPM lock icon in the library above. +Appearantly, the mainmenubar needs special treatment -- see default-menu-styles-linux7windows.qss */ +QToolTip, +#MainMenu QMenu, +WLibrarySidebar QMenu, +WTrackTableViewHeader QMenu, +WLibraryTextBrowser QMenu, +WTrackMenu, +WTrackMenu QMenu, +QLineEdit QMenu, +WCueMenuPopup, +WCoverArtMenu, +WEffectSelector QAbstractScrollArea, +#fadeModeCombobox QAbstractScrollArea { + padding: 0.15em; +} + +#MainMenu QMenu::separator, +WLibrarySidebar QMenu::separator, +WTrackMenu::separator, +WTrackMenu QMenu::separator, +QLineEdit QMenu::separator, +WLibraryTextBrowser QMenu::separator { + height: 0px; + margin: 0.25em; +} + + +/* All menus that have at least one item with a checkbox*/ +WLibrarySidebar QMenu::item, +WTrackTableViewHeader QMenu::item, +#CratesMenu::item { +/* padding-right reserves space for the submenu expand arrow + padding-left should be bigger than the menu icon width + + icon margin-left/-right */ + padding: 0.17em 0.6em 0.17em 1.3em; +} + +WTrackMenu::item, +WTrackMenu QMenu::item, +/* This catches context menus of + - property cells in the tracks table + - WCueMenuPopup cue label editor + - WBeatSpinBox + - AutoDJ transition QSpinBox*/ +QLineEdit QMenu::item, +WCoverArtMenu::item, +/* for the sake of completeness: html root view of Crates, Rec etc. */ +WLibraryTextBrowser QMenu::item { + padding: 0.17em 0.6em 0.17em 0.6em; +} + +/* Icons in those menus (copy, paste, cut, delete) */ +QLineEdit QMenu::icon, +WLibraryTextBrowser QMenu::icon, +/* - checkbox in Crate name context menu + "[ ] Auto DJ Track Source" */ +WLibrarySidebar QMenu::indicator, +/* Column checkboxes in the table header menu */ +WTrackTableViewHeader QMenu::indicator { + /* Qt 5.12.8: negative margin-right increases the overall item width but has no effect + on the indicator itself. + positive margin-right pushes icon to the right... + Qt 5.15.2: needs negative margin-right in order to eliminate the item's + padding-left (necessary to avoid text/icon overlap); */ + margin: 0 -1em 0 0.25em; +} + +/* items in Crate sub menu */ +WTrackMenu QMenu QCheckBox { + padding: 0.17em 0.6em 0.17em 0.25em; +} + +WLibrarySidebar QMenu::indicator, +WTrackTableViewHeader QMenu::indicator, +WTrackMenu QMenu QCheckBox::indicator { + width: 0.7em; + height: 0.7em; +} diff --git a/src/encoder/encoderfdkaac.cpp b/src/encoder/encoderfdkaac.cpp index 35ce522c3c66..81e4db74feec 100644 --- a/src/encoder/encoderfdkaac.cpp +++ b/src/encoder/encoderfdkaac.cpp @@ -77,7 +77,7 @@ EncoderFdkAac::EncoderFdkAac(EncoderCallback* pCallback) #endif libnames << QStringLiteral("fdk-aac"); // Although the line above should suffice, detection of the fdk-aac library - // does not work on Ubuntu 18.04 LTS and Ubuntu 20.04 LTS: + // does not work on Ubuntu 20.04 LTS: // // $ dpkg -L libfdk-aac1 | grep so // /usr/lib/x86_64-linux-gnu/libfdk-aac.so.1.0.0 diff --git a/src/encoder/encodersndfileflac.cpp b/src/encoder/encodersndfileflac.cpp index f6280c03de8e..482df1456542 100644 --- a/src/encoder/encodersndfileflac.cpp +++ b/src/encoder/encodersndfileflac.cpp @@ -85,7 +85,7 @@ void EncoderSndfileFlac::initStream() { #endif //SFC_SUPPORTS_SET_COMPRESSION_LEVEL // Version 1.0.28 suffers broken clamping https://bugs.launchpad.net/mixxx/+bug/1915298 - // We receive "libsndfile-1.0.28" on Ubuntu Bionic 18.04 LTS/Focal 20.04 LTS/Grovy 20.10 + // We receive "libsndfile-1.0.28" on Ubuntu Focal 20.04 LTS/Grovy 20.10 // Older versions are not expected. All newer version have a working internal clamping const char* sf_version = sf_version_string(); if (strstr(sf_version, "-1.0.28") != nullptr) { diff --git a/src/engine/sync/enginesync.cpp b/src/engine/sync/enginesync.cpp index 1b446b6e177c..e1778d2c84e8 100644 --- a/src/engine/sync/enginesync.cpp +++ b/src/engine/sync/enginesync.cpp @@ -98,7 +98,7 @@ void EngineSync::requestSyncMode(Syncable* pSyncable, SyncMode mode) { if (pParamsSyncable) { if (kLogger.traceEnabled()) { kLogger.trace() - << "EngineSync::requestSyncMode setting master params from " + << "EngineSync::requestSyncMode setting leader params from " << pParamsSyncable->getGroup(); } reinitLeaderParams(pParamsSyncable); @@ -414,11 +414,11 @@ void EngineSync::requestBpmUpdate(Syncable* pSyncable, double bpm) { } if (mbaseBpm != 0.0) { - // update from current master + // update from current leader pSyncable->updateLeaderBeatDistance(beatDistance); pSyncable->updateLeaderBpm(mbpm); } else { - // There is no leader, adopt this bpm as leader values + // There is no leader, adopt this bpm as leader value pSyncable->updateLeaderBeatDistance(0.0); pSyncable->updateLeaderBpm(bpm); } diff --git a/src/engine/sync/syncable.h b/src/engine/sync/syncable.h index e4e1ab350d22..53670cfc5b77 100644 --- a/src/engine/sync/syncable.h +++ b/src/engine/sync/syncable.h @@ -141,7 +141,7 @@ class SyncableListener { // Syncable::notifySyncModeChanged. virtual void requestSyncMode(Syncable* pSyncable, SyncMode mode) = 0; - // A Syncable must never call notifyBpmChanged in response to a setLeaderBpm() + // A Syncable must never call notifyBpmChanged in response to a updateLeaderBpm() // call. virtual void notifyBaseBpmChanged(Syncable* pSyncable, double bpm) = 0; virtual void notifyRateChanged(Syncable* pSyncable, double bpm) = 0; diff --git a/src/engine/sync/synccontrol.cpp b/src/engine/sync/synccontrol.cpp index f67603c1b47d..7ec60f09e95f 100644 --- a/src/engine/sync/synccontrol.cpp +++ b/src/engine/sync/synccontrol.cpp @@ -210,7 +210,7 @@ double SyncControl::getBaseBpm() const { void SyncControl::updateLeaderBeatDistance(double beatDistance) { if (kLogger.traceEnabled()) { - kLogger.trace() << getGroup() << "SyncControl::setLeaderBeatDistance" + kLogger.trace() << getGroup() << "SyncControl::updateLeaderBeatDistance" << beatDistance; } // Set the BpmControl target beat distance to beatDistance, adjusted by @@ -223,7 +223,7 @@ void SyncControl::updateLeaderBeatDistance(double beatDistance) { void SyncControl::updateLeaderBpm(double bpm) { if (kLogger.traceEnabled()) { - kLogger.trace() << getGroup() << "SyncControl::setLeaderBpm" << bpm; + kLogger.trace() << getGroup() << "SyncControl::updateLeaderBpm" << bpm; } VERIFY_OR_DEBUG_ASSERT(isSynchronized()) { @@ -249,7 +249,7 @@ void SyncControl::notifyLeaderParamSource() { void SyncControl::reinitLeaderParams( double beatDistance, double baseBpm, double bpm) { if (kLogger.traceEnabled()) { - kLogger.trace() << "SyncControl::setLeaderParams" << getGroup() + kLogger.trace() << "SyncControl::reinitLeaderParams" << getGroup() << beatDistance << baseBpm << bpm; } m_leaderBpmAdjustFactor = determineBpmMultiplier(fileBpm(), baseBpm); diff --git a/src/preferences/dialog/dlgprefwaveform.cpp b/src/preferences/dialog/dlgprefwaveform.cpp index faf25c2fca15..d1d2e8d35a10 100644 --- a/src/preferences/dialog/dlgprefwaveform.cpp +++ b/src/preferences/dialog/dlgprefwaveform.cpp @@ -27,11 +27,15 @@ DlgPrefWaveform::DlgPrefWaveform( // Populate waveform options. WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); + // We assume that the original type list order remains constant. + // We will use the type index later on to set waveform types and to + // update the combobox. QVector handles = factory->getAvailableTypes(); for (int i = 0; i < handles.size(); ++i) { - waveformTypeComboBox->addItem(handles[i].getDisplayName(), - handles[i].getType()); + waveformTypeComboBox->addItem(handles[i].getDisplayName(), i); } + // Sort the combobox items alphabetically + waveformTypeComboBox->model()->sort(0); // Populate zoom options. for (int i = static_cast(WaveformWidgetRenderer::s_waveformMinZoom); @@ -144,8 +148,8 @@ void DlgPrefWaveform::slotUpdate() { openGlStatusIcon->setText(tr("OpenGL not available") + ": " + factory->getOpenGLVersion()); } - WaveformWidgetType::Type currentType = factory->getType(); - int currentIndex = waveformTypeComboBox->findData(currentType); + // The combobox holds a list of [handle name, handle index] + int currentIndex = waveformTypeComboBox->findData(factory->getHandleIndex()); if (currentIndex != -1 && waveformTypeComboBox->currentIndex() != currentIndex) { waveformTypeComboBox->setCurrentIndex(currentIndex); } @@ -194,10 +198,10 @@ void DlgPrefWaveform::slotApply() { void DlgPrefWaveform::slotResetToDefaults() { WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); - // Get the default we ought to use based on whether the user has OpenGL or - // not. - WaveformWidgetType::Type defaultType = factory->autoChooseWidgetType(); - int defaultIndex = waveformTypeComboBox->findData(defaultType); + // Get the default we ought to use based on whether the user has OpenGL or not. + // Select the combobox index that holds the default handle's index in data column. + int defaultIndex = waveformTypeComboBox->findData( + factory->findHandleIndexFromType(factory->autoChooseWidgetType())); if (defaultIndex != -1 && waveformTypeComboBox->currentIndex() != defaultIndex) { waveformTypeComboBox->setCurrentIndex(defaultIndex); } @@ -247,7 +251,8 @@ void DlgPrefWaveform::slotSetWaveformType(int index) { if (index < 0) { return; } - WaveformWidgetFactory::instance()->setWidgetTypeFromHandle(index); + int handleIndex = waveformTypeComboBox->itemData(index).toInt(); + WaveformWidgetFactory::instance()->setWidgetTypeFromHandle(handleIndex); } void DlgPrefWaveform::slotSetWaveformOverviewType(int index) { diff --git a/src/sources/soundsourceflac.cpp b/src/sources/soundsourceflac.cpp index 8f508bb046c6..a6624a7e8269 100644 --- a/src/sources/soundsourceflac.cpp +++ b/src/sources/soundsourceflac.cpp @@ -415,19 +415,26 @@ inline CSAMPLE convertDecodedSample(FLAC__int32 decodedSample, int bitsPerSample FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite( const FLAC__Frame* frame, const FLAC__int32* const buffer[]) { - const SINT numChannels = frame->header.channels; - if (getSignalInfo().getChannelCount() > numChannels) { + VERIFY_OR_DEBUG_ASSERT(frame->header.channels > 0) { + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + const auto channelCount = mixxx::audio::ChannelCount::fromInt(frame->header.channels); + if (getSignalInfo().getChannelCount() > channelCount) { kLogger.warning() << "Corrupt or unsupported FLAC file:" << "Invalid number of channels in FLAC frame header" - << frame->header.channels << "<>" << getSignalInfo().getChannelCount(); + << channelCount << "<>" << getSignalInfo().getChannelCount(); + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + VERIFY_OR_DEBUG_ASSERT(frame->header.sample_rate > 0) { return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } - if (getSignalInfo().getSampleRate() != SINT(frame->header.sample_rate)) { + const auto sampleRate = mixxx::audio::SampleRate(frame->header.sample_rate); + if (getSignalInfo().getSampleRate() != sampleRate) { kLogger.warning() << "Corrupt or unsupported FLAC file:" << "Invalid sample rate in FLAC frame header" - << frame->header.sample_rate << "<>" << getSignalInfo().getSampleRate(); + << sampleRate << "<>" << getSignalInfo().getSampleRate(); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } const SINT numReadableFrames = frame->header.blocksize; @@ -460,7 +467,7 @@ FLAC__StreamDecoderWriteStatus SoundSourceFLAC::flacWrite( } CSAMPLE* pSampleBuffer = writableSlice.data(); - DEBUG_ASSERT(getSignalInfo().getChannelCount() <= numChannels); + DEBUG_ASSERT(getSignalInfo().getChannelCount() <= channelCount); switch (getSignalInfo().getChannelCount()) { case 1: { // optimized code for 1 channel (mono) diff --git a/src/test/enginesynctest.cpp b/src/test/enginesynctest.cpp index fa0fbd745244..07a8368807d5 100644 --- a/src/test/enginesynctest.cpp +++ b/src/test/enginesynctest.cpp @@ -679,7 +679,7 @@ TEST_F(EngineSyncTest, RateChangeTestOrder3) { EXPECT_DOUBLE_EQ( 120.0, ControlObject::get(ConfigKey(m_sGroup2, "file_bpm"))); - // Turn on Leader. Even though it is explict leader, it still matches the other deck. + // Turn on Leader. Even though it is explicit leader, it still matches the other deck. auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); pButtonLeaderSync1->set(SYNC_LEADER_EXPLICIT); diff --git a/src/waveform/waveformwidgetfactory.cpp b/src/waveform/waveformwidgetfactory.cpp index bed2fc66fc12..0c617c2df76f 100644 --- a/src/waveform/waveformwidgetfactory.cpp +++ b/src/waveform/waveformwidgetfactory.cpp @@ -765,26 +765,42 @@ void WaveformWidgetFactory::evaluateWidgets() { case WaveformWidgetType::SoftwareSimpleWaveform: continue; // //TODO(vrince): case WaveformWidgetType::SoftwareWaveform: +#ifdef __APPLE__ + // Don't offer the simple renderers on macOS, they do not work with skins + // that load GL widgets (spinnies, waveforms) in singletons. + // Also excluded in enum WaveformWidgetType + // https://bugs.launchpad.net/bugs/1928772 + continue; +#else widgetName = SoftwareWaveformWidget::getWaveformWidgetName(); useOpenGl = SoftwareWaveformWidget::useOpenGl(); useOpenGles = SoftwareWaveformWidget::useOpenGles(); useOpenGLShaders = SoftwareWaveformWidget::useOpenGLShaders(); developerOnly = SoftwareWaveformWidget::developerOnly(); break; +#endif case WaveformWidgetType::HSVWaveform: +#ifdef __APPLE__ + continue; +#else widgetName = HSVWaveformWidget::getWaveformWidgetName(); useOpenGl = HSVWaveformWidget::useOpenGl(); useOpenGles = HSVWaveformWidget::useOpenGles(); useOpenGLShaders = HSVWaveformWidget::useOpenGLShaders(); developerOnly = HSVWaveformWidget::developerOnly(); break; +#endif case WaveformWidgetType::RGBWaveform: +#ifdef __APPLE__ + continue; +#else widgetName = RGBWaveformWidget::getWaveformWidgetName(); useOpenGl = RGBWaveformWidget::useOpenGl(); useOpenGles = RGBWaveformWidget::useOpenGles(); useOpenGLShaders = RGBWaveformWidget::useOpenGLShaders(); developerOnly = RGBWaveformWidget::developerOnly(); break; +#endif case WaveformWidgetType::QtSimpleWaveform: widgetName = QtSimpleWaveformWidget::getWaveformWidgetName(); useOpenGl = QtSimpleWaveformWidget::useOpenGl(); diff --git a/src/waveform/waveformwidgetfactory.h b/src/waveform/waveformwidgetfactory.h index 514a1a9402b2..483ea4caad85 100644 --- a/src/waveform/waveformwidgetfactory.h +++ b/src/waveform/waveformwidgetfactory.h @@ -92,6 +92,10 @@ class WaveformWidgetFactory : public QObject, public Singleton(static_cast(type)); - switch (cueType) { + switch (static_cast(static_cast(type))) { case mixxx::CueType::Invalid: m_type = QLatin1String(""); break; diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 36ec3890eadd..6a083ad3dc42 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -259,4 +259,7 @@ bool WLibrarySidebar::event(QEvent* pEvent) { void WLibrarySidebar::slotSetFont(const QFont& font) { setFont(font); + // Resize the feature icons to be a bit taller than the label's capital + int iconSize = static_cast(QFontMetrics(font).height() * 0.8); + setIconSize(QSize(iconSize, iconSize)); } diff --git a/tools/clang_format.py b/tools/clang_format.py index a37e6468d43b..5a385d3be4f2 100755 --- a/tools/clang_format.py +++ b/tools/clang_format.py @@ -21,7 +21,7 @@ def get_clang_format_config_with_columnlimit(rootdir, limit): """Create a temporary config with ColumnLimit set to 80.""" - cpp_file = os.path.join(rootdir, "src/mixxx.cpp") + cpp_file = os.path.join(rootdir, "src/main.cpp") proc = subprocess.run( ["clang-format", "--dump-config", cpp_file], capture_output=True, diff --git a/tools/debian_buildenv.sh b/tools/debian_buildenv.sh index c17fb79e64a2..013f154b9977 100755 --- a/tools/debian_buildenv.sh +++ b/tools/debian_buildenv.sh @@ -21,8 +21,7 @@ case "$COMMAND" in ;; *) # libmp4v2 was removed from Debian 10 & Ubuntu 20.04 due to lack of maintenance, so use FFMPEG instead PACKAGES_EXTRA=( - libavcodec-dev - libavutil-dev + libavformat-dev ) esac @@ -48,7 +47,6 @@ case "$COMMAND" in fonts-open-sans \ fonts-ubuntu \ g++ \ - libavformat-dev \ libchromaprint-dev \ libdistro-info-perl \ libebur128-dev \ diff --git a/tools/githelper.py b/tools/githelper.py index 99954e753ffe..da0f6456173e 100644 --- a/tools/githelper.py +++ b/tools/githelper.py @@ -24,10 +24,44 @@ def get_toplevel_path() -> str: return subprocess.check_output(cmd, text=True).strip() +def get_moved_files( + changeset, include_files=None +) -> typing.Iterable[typing.Tuple[str, str]]: + """ + Inspect `git diff` output to find moved/renamed files. + + Yields tuples in the form (old_file, new_file). + + If include_files is set, this only yields results where at least one of the + two file names is in the list of file names to include. + """ + + logger = logging.getLogger(__name__) + + cmd = ["git", "diff", "--raw", "-z", changeset] + logger.debug("Executing: %r", cmd) + proc = subprocess.run(cmd, capture_output=True) + proc.check_returncode() + diff_output = proc.stdout.decode(errors="replace") + for line in diff_output.lstrip(":").split(":"): + change, _, files = line.partition("\0") + _, _, changetype = change.rpartition(" ") + if changetype.startswith("R"): + # A file was renamed + old_file, sep, new_file = files.rstrip("\0").partition("\0") + assert sep == "\0" + + move = (old_file, new_file) + if include_files and not any(x in include_files for x in move): + continue + + yield move + + def get_changed_lines( from_ref=None, to_ref=None, filter_lines=None, include_files=None ) -> typing.Iterable[Line]: - """Inspect `git diff-index` output, yields changed lines.""" + """Inspect `git diff` output, yields changed lines.""" logger = logging.getLogger(__name__) @@ -48,16 +82,31 @@ def get_changed_lines( # repository). Therefore we need to filter our all files outside of the # current repository before passing them to git diff. toplevel_path = get_toplevel_path() - include_files_filtered = [ + include_files = { path for path in include_files if os.path.commonprefix((os.path.abspath(path), toplevel_path)) == toplevel_path - ] - if not include_files_filtered: + } + if not include_files: # No files to check return - cmd.extend(["--", *include_files]) + + # If files were moved, it's possible that only the new filename is in + # the list of included files. For example, this is the case when the + # script is used by pre-commit. When calling `git diff` after a rename + # with a path argument where only the new file is listed, git treats + # the file as newly added and the whole file shows up as added lines. + # + # This leads to false positives because the lines were not actually + # changed. Hence, we check if any of the files were renamed, and make + # sure that both the old and new filename is included in the initial + # `git diff` call. + moved_files = get_moved_files(changeset, include_files=include_files) + include_files_with_moved = include_files.union( + itertools.chain.from_iterable(moved_files) + ) + cmd.extend(["--", *include_files_with_moved]) logger.debug("Executing: %r", cmd) proc = subprocess.run(cmd, capture_output=True) proc.check_returncode() @@ -115,6 +164,8 @@ def get_changed_lines( ) if filter_lines is None or filter_lines(lineobj): + if include_files and lineobj.sourcefile not in include_files: + continue yield lineobj # If we reach this part, the line does not contain a diff filename or a diff --git a/tools/qmlformat.py b/tools/qmlformat.py index b87730c752e2..d009c0f8a614 100755 --- a/tools/qmlformat.py +++ b/tools/qmlformat.py @@ -10,17 +10,25 @@ import re QMLFORMAT_MISSING_MESSAGE = """ -qmlformat is not installed or not in your $PATH. It is included in Qt 5.15 -and later. If that Qt version is not available on your system, please -use the SKIP environment variable when committing: - - $ SKIP=qmlformat git commit +qmlformat is not installed or not in your $PATH, please install. """ def main(argv=None): qmlformat_executable = shutil.which("qmlformat") if not qmlformat_executable: + # verify if qmlformat is available on this machine + moc_executable = shutil.which("moc") + if moc_executable: + moc_version = subprocess.check_output( + (moc_executable, "-v") + ).strip() + v = re.search("moc ([0-9]*)\\.([0-9]*)\\.[0-9]*", str(moc_version)) + if v: + version = (int(v.group(1)), int(v.group(2))) + if version < (5, 15): + # Succeed if a Qt Version < 5.15 is used without qmlformat + return 0 print(QMLFORMAT_MISSING_MESSAGE.strip(), file=sys.stderr) return 1