From 0b2b294b907fdac395c61142cfdd099ef7733af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 31 May 2021 14:38:38 +0200 Subject: [PATCH 01/56] only fail qmlformat stage if Qt >= 5.15 is used --- tools/qmlformat.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tools/qmlformat.py b/tools/qmlformat.py index 2c18fd9fa264..d0d2920bee73 100755 --- a/tools/qmlformat.py +++ b/tools/qmlformat.py @@ -7,19 +7,28 @@ import subprocess import pathlib import sys +import re QMLFORMAT_MISSING_MESSAGE = """ -qmlformat is not installed. 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 not found, 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: + if int(v.group(1)) < 5: + return 0 + if int(v.group(1)) == 5 and int(v.group(2)) < 15: + return 0 print(QMLFORMAT_MISSING_MESSAGE.strip(), file=sys.stderr) return 1 From 65a4f4471c9b4fe08379e1bea1ac7af4d0f64435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 31 May 2021 17:50:53 +0200 Subject: [PATCH 02/56] use version compare Co-authored-by: Jan Holthuis --- tools/qmlformat.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/qmlformat.py b/tools/qmlformat.py index d0d2920bee73..56f0cfa8f5f3 100755 --- a/tools/qmlformat.py +++ b/tools/qmlformat.py @@ -25,9 +25,8 @@ def main(argv=None): ).strip() v = re.search("moc ([0-9]*)\\.([0-9]*)\\.[0-9]*", str(moc_version)) if v: - if int(v.group(1)) < 5: - return 0 - if int(v.group(1)) == 5 and int(v.group(2)) < 15: + version = (int(v.group(1)), int(v.group(2))) + if version < (5, 15): return 0 print(QMLFORMAT_MISSING_MESSAGE.strip(), file=sys.stderr) return 1 From 1ce49e200cf29fef8516d7d09d1f67abef7bf9f3 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 9 Jun 2021 11:46:43 +0200 Subject: [PATCH 03/56] pre-commit: Use main.cpp for getting clang_format config That file name is less likely to change. Previously, `mixxx.cpp` was used, which might be renamed in a later refactoring. --- tools/clang_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, From d62208a94b45d3388e76fe862e5c800df5a8b5ec Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 9 Jun 2021 11:48:39 +0200 Subject: [PATCH 04/56] tools/githelper: Fix wrong docstring --- tools/githelper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/githelper.py b/tools/githelper.py index 99954e753ffe..51ffd4e07df9 100644 --- a/tools/githelper.py +++ b/tools/githelper.py @@ -27,7 +27,7 @@ def get_toplevel_path() -> str: 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__) From 803ee7f8868b212b05a4a48f85b96a8f7ad137bd Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 9 Jun 2021 12:06:53 +0200 Subject: [PATCH 05/56] tools/githelper: Actually use the filtered list of included files --- tools/githelper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/githelper.py b/tools/githelper.py index 51ffd4e07df9..fcb2443b6ac3 100644 --- a/tools/githelper.py +++ b/tools/githelper.py @@ -57,7 +57,7 @@ def get_changed_lines( if not include_files_filtered: # No files to check return - cmd.extend(["--", *include_files]) + cmd.extend(["--", *include_files_filtered]) logger.debug("Executing: %r", cmd) proc = subprocess.run(cmd, capture_output=True) proc.check_returncode() From 81991458f57c9d51e27ccc88818c256577d460d9 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Wed, 9 Jun 2021 12:05:20 +0200 Subject: [PATCH 06/56] tools/githelper: Fix misdetection of changed lines when file was moved --- tools/githelper.py | 59 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/tools/githelper.py b/tools/githelper.py index fcb2443b6ac3..da0f6456173e 100644 --- a/tools/githelper.py +++ b/tools/githelper.py @@ -24,6 +24,40 @@ 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]: @@ -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_filtered]) + + # 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 From 56abd4d0fdc697eb0157946a60391347d21877f8 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Tue, 8 Jun 2021 20:36:36 +0200 Subject: [PATCH 07/56] WLibrarySidebar: scale icons with library font --- src/widget/wlibrarysidebar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index 57915ce18b36..226f1a26d21a 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -231,4 +231,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)); } From c6b7412c1d87e7c3aaeed462b3fc7b8405362021 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Wed, 9 Jun 2021 03:32:26 +0200 Subject: [PATCH 08/56] Skins: move common properties to default.qss * menubar checkboxes * lib BPM lock * Played checkbox * menu arrows * menu separators --- res/skins/Deere/style.qss | 57 ++++--------------------- res/skins/LateNight/style.qss | 34 ++------------- res/skins/LateNight/style_classic.qss | 1 + res/skins/LateNight/style_palemoon.qss | 2 + res/skins/Shade/style.qss | 52 +++-------------------- res/skins/Tango/style.qss | 58 +++++--------------------- res/skins/default.qss | 24 +++++++++++ 7 files changed, 54 insertions(+), 174 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 65519e03febe..b9c27c82c7ab 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 */ @@ -2005,22 +2005,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 +2019,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,20 +2095,14 @@ 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; + border-top: 1px solid #999; } /* All menus that have at least one item with a checkbox*/ @@ -2190,13 +2162,6 @@ 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, @@ -2249,12 +2214,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/style.qss b/res/skins/LateNight/style.qss index a6adbd2cec59..33d036998ffe 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -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; } @@ -234,12 +214,6 @@ 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 { diff --git a/res/skins/LateNight/style_classic.qss b/res/skins/LateNight/style_classic.qss index 9fc0c651a88f..8403c8354459 100644 --- a/res/skins/LateNight/style_classic.qss +++ b/res/skins/LateNight/style_classic.qss @@ -2495,6 +2495,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 88df797fbf6b..1ad1aa525fb1 100644 --- a/res/skins/LateNight/style_palemoon.qss +++ b/res/skins/LateNight/style_palemoon.qss @@ -2898,8 +2898,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/Shade/style.qss b/res/skins/Shade/style.qss index dbc2a47ec8a5..68a4ace8b668 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -201,22 +201,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 +216,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, @@ -440,19 +418,12 @@ 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; } @@ -465,17 +436,6 @@ QLineEdit QMenu::separator { 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 +603,6 @@ WTrackTableView { /* checkbox in library "Played" column */ WTrackTableView::indicator { - width: 10px; - height: 10px; margin: 0px; padding: 0px; color: #cfcfcf; diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index a803527acd85..0e1cd431b689 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,14 +2159,18 @@ 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*/ @@ -2327,40 +2315,16 @@ 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; @@ -2994,8 +2958,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/default.qss b/res/skins/default.qss index 91cd71887fb0..620eb991a14b 100644 --- a/res/skins/default.qss +++ b/res/skins/default.qss @@ -73,3 +73,27 @@ WOverview #PassthroughLabel { #SearchClearButton:focus { image: url(:/images/library/ic_library_cross_orange.svg); } + +/* checkbox in library "Played" column */ +WTrackTableView::indicator, +/* BPM lock icon */ +#LibraryBPMButton::indicator { + width: 0.5em; + height: 0.5em; +} + + +#MainMenu QMenu::indicator { + width: 1em; + height: 1em; +} + +#MainMenu QMenu::separator, +WLibrarySidebar QMenu::separator, +WTrackMenu::separator, +WTrackMenu QMenu::separator, +QLineEdit QMenu::separator, +WLibraryTextBrowser QMenu::separator { + height: 0px; + margin: 0.25em; +} From 34fefa8ae3c705aa46449368c00e5a03962966de Mon Sep 17 00:00:00 2001 From: ronso0 Date: Wed, 9 Jun 2021 03:58:36 +0200 Subject: [PATCH 09/56] Shade (fix): use Open Sans in table header --- res/skins/Shade/style.qss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index 68a4ace8b668..74d1a7fd2878 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, From 7b3f4430cccfe51e5efe34e4130b1512ab97dfbc Mon Sep 17 00:00:00 2001 From: ronso0 Date: Wed, 9 Jun 2021 11:21:01 +0200 Subject: [PATCH 10/56] Skin context menus: scale checkboxes with font size --- res/skins/Deere/style.qss | 4 ++-- res/skins/LateNight/style.qss | 4 ++-- res/skins/Shade/style.qss | 6 +++--- res/skins/Tango/style.qss | 14 +++----------- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index b9c27c82c7ab..d270e86eae08 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -2153,8 +2153,8 @@ WTrackMenu QMenu QCheckBox { WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 13px; - height: 13px; + width: 0.7em; + height: 0.7em; border: 1px solid #555; border-radius: 1px; background-color: #0f0f0f; diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 33d036998ffe..ebaffbf1752d 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -217,8 +217,8 @@ WTrackMenu QMenu QCheckBox { WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 13px; - height: 13px; + width: 0.7em; + height: 0.7em; border: 1px solid #333; border-radius: 1px; background-color: #000; diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index 74d1a7fd2878..d12282973a67 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -432,8 +432,8 @@ WTrackMenu QMenu QCheckBox { WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 13px; - height: 13px; + width: 0.7em; + height: 0.7em; border-width: 1px; border-style: solid; } @@ -728,7 +728,7 @@ WTrackTableViewHeader::section { WTrackTableViewHeader::up-arrow, WTrackTableViewHeader::down-arrow { - width: 12px; + width: 0.6em; padding-right: 2px; margin-right: 1px; background-color: rgba(98,111,135,255); diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index 0e1cd431b689..381f468645af 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -2325,19 +2325,11 @@ QLineEdit QMenu::item:disabled { border-top: 1px solid #0a0a0a; } - 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; + width: 0.7em; + height: 0.7em; background-color: #0f0f0f; border: 1px solid #333; border-radius: 1px; @@ -2611,7 +2603,7 @@ WTrackTableViewHeader { WTrackTableViewHeader::up-arrow, WTrackTableViewHeader::down-arrow { - width: 12px; + width: 0.6em; padding-right: 2px; border-right: 1px solid #585858; background-color: rgba(51,51,51,200); From 820a3cabda7bbacd1064fcd493f2bf8430c03e96 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Wed, 9 Jun 2021 11:45:50 +0200 Subject: [PATCH 11/56] Skins, context menus: move common properties to default.qss --- res/skins/Deere/style.qss | 61 ------------------ res/skins/LateNight/style.qss | 47 -------------- res/skins/LateNight/style_classic.qss | 13 ++-- res/skins/LateNight/style_palemoon.qss | 7 +- res/skins/Shade/style.qss | 73 ++------------------- res/skins/Tango/style.qss | 57 ++--------------- res/skins/default.qss | 88 +++++++++++++++++++++++--- 7 files changed, 97 insertions(+), 249 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index d270e86eae08..1656decab2ea 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -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; @@ -2105,56 +2091,9 @@ QLineEdit QMenu::separator { border-top: 1px solid #999; } -/* 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::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 0.7em; - height: 0.7em; border: 1px solid #555; border-radius: 1px; background-color: #0f0f0f; diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index ebaffbf1752d..f2652b7868c6 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -169,56 +169,9 @@ QLineEdit QMenu::separator { 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; -} - WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 0.7em; - height: 0.7em; border: 1px solid #333; border-radius: 1px; background-color: #000; diff --git a/res/skins/LateNight/style_classic.qss b/res/skins/LateNight/style_classic.qss index 8403c8354459..a6d4f40364fb 100644 --- a/res/skins/LateNight/style_classic.qss +++ b/res/skins/LateNight/style_classic.qss @@ -2328,22 +2328,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; } diff --git a/res/skins/LateNight/style_palemoon.qss b/res/skins/LateNight/style_palemoon.qss index 1ad1aa525fb1..fe2e3f1b0f8d 100644 --- a/res/skins/LateNight/style_palemoon.qss +++ b/res/skins/LateNight/style_palemoon.qss @@ -2794,6 +2794,7 @@ WLibrarySidebar::branch:open:has-children:has-siblings { /************** common styles for WEffectSelector ****************************** *************** QSpinBox, QMenu, QToolTip *************************************/ QToolTip, +#MainMenu QMenu, WLibrarySidebar QMenu, WTrackTableViewHeader QMenu, WLibraryTextBrowser QMenu, @@ -2804,12 +2805,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; } diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index d12282973a67..8742672d245e 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -237,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 { @@ -374,51 +362,6 @@ 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; -} - #MainMenu QMenu::separator, WLibrarySidebar QMenu::separator, WTrackTableViewHeader QMenu::separator, @@ -432,8 +375,6 @@ WTrackMenu QMenu QCheckBox { WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 0.7em; - height: 0.7em; border-width: 1px; border-style: solid; } diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index 381f468645af..bb55b1ae7b6b 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -2173,51 +2173,6 @@ WEffectSelector::indicator:unchecked, 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 { font-weight: bold; @@ -2258,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; } @@ -2328,8 +2283,6 @@ QLineEdit QMenu::item:disabled { WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { - width: 0.7em; - height: 0.7em; background-color: #0f0f0f; border: 1px solid #333; border-radius: 1px; diff --git a/res/skins/default.qss b/res/skins/default.qss index 620eb991a14b..8bde1a97b0c6 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; @@ -74,20 +82,31 @@ WOverview #PassthroughLabel { image: url(:/images/library/ic_library_cross_orange.svg); } -/* checkbox in library "Played" column */ -WTrackTableView::indicator, -/* BPM lock icon */ -#LibraryBPMButton::indicator { - width: 0.5em; - height: 0.5em; -} - #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, @@ -97,3 +116,56 @@ 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.25em 0.6em 0.24em 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.25em 0.6em 0.25em 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.15em 0.5em 0.15em 0.25em; +} + +WLibrarySidebar QMenu::indicator, +WTrackTableViewHeader QMenu::indicator, +WTrackMenu QMenu QCheckBox::indicator { + width: 0.7em; + height: 0.7em; +} From cee94c967d5a926c52a7999485f3ed184080e146 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Wed, 9 Jun 2021 12:08:02 +0200 Subject: [PATCH 12/56] Skins: use SVGs for sidebar branch icons --- res/skins/Deere/image/style_branch_closed.png | Bin 705 -> 0 bytes res/skins/Deere/image/style_branch_closed.svg | 3 +++ res/skins/Deere/image/style_branch_open.png | Bin 694 -> 0 bytes res/skins/Deere/image/style_branch_open.svg | 3 +++ res/skins/Deere/style.qss | 4 ++-- .../classic/style/library_branch_closed.svg | 3 +++ .../classic/style/library_branch_closed_grey.png | Bin 705 -> 0 bytes .../style/library_branch_closed_selected.svg | 3 +++ .../library_branch_closed_selected_white.png | Bin 208 -> 0 bytes .../classic/style/library_branch_open.svg | 3 +++ .../classic/style/library_branch_open_grey.png | Bin 694 -> 0 bytes .../style/library_branch_open_selected.svg | 3 +++ .../style/library_branch_open_selected_white.png | Bin 215 -> 0 bytes .../LateNight/classic/style/menu_arrow_gold.svg | 3 --- .../palemoon/style/library_branch_closed.svg | 4 ++++ .../style/library_branch_closed_grey.png | Bin 2349 -> 0 bytes .../style/library_branch_closed_selected.svg | 4 ++++ .../library_branch_closed_selected_white.png | Bin 208 -> 0 bytes .../palemoon/style/library_branch_open.svg | 4 ++++ .../palemoon/style/library_branch_open_grey.png | Bin 2219 -> 0 bytes .../style/library_branch_open_selected.svg | 4 ++++ .../style/library_branch_open_selected_white.png | Bin 215 -> 0 bytes res/skins/LateNight/style_classic.qss | 9 ++++----- res/skins/LateNight/style_palemoon.qss | 8 ++++---- res/skins/Shade/style.qss | 8 ++++---- res/skins/Shade/style/style_branch_closed.png | Bin 705 -> 0 bytes res/skins/Shade/style/style_branch_closed.svg | 3 +++ .../Shade/style/style_branch_closed_selected.png | Bin 244 -> 0 bytes .../Shade/style/style_branch_closed_selected.svg | 3 +++ res/skins/Shade/style/style_branch_open.png | Bin 694 -> 0 bytes res/skins/Shade/style/style_branch_open.svg | 3 +++ .../Shade/style/style_branch_open_selected.png | Bin 238 -> 0 bytes .../Shade/style/style_branch_open_selected.svg | 3 +++ res/skins/Tango/graphics/branch_closed.png | Bin 705 -> 0 bytes res/skins/Tango/graphics/branch_closed.svg | 3 +++ res/skins/Tango/graphics/branch_open.png | Bin 694 -> 0 bytes res/skins/Tango/graphics/branch_open.svg | 3 +++ res/skins/Tango/style.qss | 4 ++-- 38 files changed, 68 insertions(+), 20 deletions(-) delete mode 100644 res/skins/Deere/image/style_branch_closed.png create mode 100644 res/skins/Deere/image/style_branch_closed.svg delete mode 100644 res/skins/Deere/image/style_branch_open.png create mode 100644 res/skins/Deere/image/style_branch_open.svg create mode 100644 res/skins/LateNight/classic/style/library_branch_closed.svg delete mode 100644 res/skins/LateNight/classic/style/library_branch_closed_grey.png create mode 100644 res/skins/LateNight/classic/style/library_branch_closed_selected.svg delete mode 100644 res/skins/LateNight/classic/style/library_branch_closed_selected_white.png create mode 100644 res/skins/LateNight/classic/style/library_branch_open.svg delete mode 100644 res/skins/LateNight/classic/style/library_branch_open_grey.png create mode 100644 res/skins/LateNight/classic/style/library_branch_open_selected.svg delete mode 100644 res/skins/LateNight/classic/style/library_branch_open_selected_white.png delete mode 100644 res/skins/LateNight/classic/style/menu_arrow_gold.svg create mode 100644 res/skins/LateNight/palemoon/style/library_branch_closed.svg delete mode 100644 res/skins/LateNight/palemoon/style/library_branch_closed_grey.png create mode 100644 res/skins/LateNight/palemoon/style/library_branch_closed_selected.svg delete mode 100644 res/skins/LateNight/palemoon/style/library_branch_closed_selected_white.png create mode 100644 res/skins/LateNight/palemoon/style/library_branch_open.svg delete mode 100644 res/skins/LateNight/palemoon/style/library_branch_open_grey.png create mode 100644 res/skins/LateNight/palemoon/style/library_branch_open_selected.svg delete mode 100644 res/skins/LateNight/palemoon/style/library_branch_open_selected_white.png delete mode 100644 res/skins/Shade/style/style_branch_closed.png create mode 100644 res/skins/Shade/style/style_branch_closed.svg delete mode 100644 res/skins/Shade/style/style_branch_closed_selected.png create mode 100644 res/skins/Shade/style/style_branch_closed_selected.svg delete mode 100644 res/skins/Shade/style/style_branch_open.png create mode 100644 res/skins/Shade/style/style_branch_open.svg delete mode 100644 res/skins/Shade/style/style_branch_open_selected.png create mode 100644 res/skins/Shade/style/style_branch_open_selected.svg delete mode 100644 res/skins/Tango/graphics/branch_closed.png create mode 100644 res/skins/Tango/graphics/branch_closed.svg delete mode 100644 res/skins/Tango/graphics/branch_open.png create mode 100644 res/skins/Tango/graphics/branch_open.svg 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 aac367c5b22afce61fa74571d44a0084e0464f5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmYk3Uq}=|9LKk^<2pDjkubHG4B|@Ky;F%SD?RVhrSz`uAnhSqcjxX#cXzg#*>10l zs6-SBA0&HFq?d@IBCvw!sS64Wq#&`EAbRQ#MD^5DG_!}$vcDPF-{<$8?|gSM-QN=q z)rTZW3ah<|6MPTy+7JxzwK`+Te5;~yH5=s5XwaAtO{aH|a(+eBns{W^;~%%MO-Q0j77 z0TXH1rJcN(r6E%`;G2U}M>w%8hy$YBCp3IVdgfBG^=am+&Jq2Uv4 z`y3BMVtXBLmpBCj7Gi z2KWW*#09$v)PxSmA`40_(O7Ixw2i-C@!U7g)K&s_iC&4@5`l`Wf6p)9<$cxHz)p#v ze1S=6cgRFKNMIhNy=qGLk2nW)Y+2l}m{vFi`QM<5<4+j=fHL^ + + 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 56ae3993ef5d872369085366178e053ef4aa38f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 694 zcmYk3Uq}=|9LF~jJ1>lah)aqFGq9xHJGnxlLeIVQf>iPzPUyjP_jh}vyF1IwthX1T zY=}o4-(ZwPtnXCLc{!KVCM7t{(keF^8m z74QLwmHu*YiMM4(Th2oyXMkPBV_$nY$L96Uk|T0v!O*}&uR z9*QkAVlbgD#RA&~Cc9#&NQsL|oco6~je}W|kUC~Xj%WjvjDpFT)*n`E@U%f*ap2E= zR1gnL$Om>)Fr*I3V;7Y6WGb~knHKXqnOhOe)|%k~HEVXe(opI3&-ta>;yxE?5WhmP zUE<0>Fyden=|ouRtuhh^?m5EO)b2o;cjyF4r zjrBWhEpc4W|GqVu$?n>+@Fn^2?B&OB?Rux4=5GhzRllzOYH40A{8*g%Fn#g;-Qq-L Xeap?=k8nfXK2crCW&89ync=B_gXZ+l 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 1656decab2ea..42fe4e5cf222 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -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 */ 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 aac367c5b22afce61fa74571d44a0084e0464f5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmYk3Uq}=|9LKk^<2pDjkubHG4B|@Ky;F%SD?RVhrSz`uAnhSqcjxX#cXzg#*>10l zs6-SBA0&HFq?d@IBCvw!sS64Wq#&`EAbRQ#MD^5DG_!}$vcDPF-{<$8?|gSM-QN=q z)rTZW3ah<|6MPTy+7JxzwK`+Te5;~yH5=s5XwaAtO{aH|a(+eBns{W^;~%%MO-Q0j77 z0TXH1rJcN(r6E%`;G2U}M>w%8hy$YBCp3IVdgfBG^=am+&Jq2Uv4 z`y3BMVtXBLmpBCj7Gi z2KWW*#09$v)PxSmA`40_(O7Ixw2i-C@!U7g)K&s_iC&4@5`l`Wf6p)9<$cxHz)p#v ze1S=6cgRFKNMIhNy=qGLk2nW)Y+2l}m{vFi`QM<5<4+j=fHL^ + + 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 d55311cfc0d6eadc7635159d589e6f3bf43d449b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^96-#;!3HGxgLCzO6kC$Fy9>jA5L~c#`DBoEfk$L9 zP{(x;W^~e+T>%tiFY)wsWq-sf%%>%g8a6EtC=~1I;us=vx%a|G-ev~@my4FmzdR5- z5!-Wnp)7k|tC@#^7-t>J4Nj{G`?p-I>n&5CadDyJH(_aEwmX4Yhx)~3L9hFM;O0~@Y`yPJjzAP8^`v0k7f7ToAK#LeWUHx3vIVCg!09Z*yT>t<8 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 56ae3993ef5d872369085366178e053ef4aa38f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 694 zcmYk3Uq}=|9LF~jJ1>lah)aqFGq9xHJGnxlLeIVQf>iPzPUyjP_jh}vyF1IwthX1T zY=}o4-(ZwPtnXCLc{!KVCM7t{(keF^8m z74QLwmHu*YiMM4(Th2oyXMkPBV_$nY$L96Uk|T0v!O*}&uR z9*QkAVlbgD#RA&~Cc9#&NQsL|oco6~je}W|kUC~Xj%WjvjDpFT)*n`E@U%f*ap2E= zR1gnL$Om>)Fr*I3V;7Y6WGb~knHKXqnOhOe)|%k~HEVXe(opI3&-ta>;yxE?5WhmP zUE<0>Fyden=|ouRtuhh^?m5EO)b2o;cjyF4r zjrBWhEpc4W|GqVu$?n>+@Fn^2?B&OB?Rux4=5GhzRllzOYH40A{8*g%Fn#g;-Qq-L Xeap?=k8nfXK2crCW&89ync=B_gXZ+l 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 ee4730690ed34dae08551a914fcf1d83df820d6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRM!3HF?&tBaMq}Y|gW!U_%O``B6nI1y z19e;nVMZs7*%d%R_7YEDSN2D&!hBi^&i%^{0fkaLT^vIsE|;F#$a^S2gxR59s_V@G z1)jrRk*%o_$|jyHLZ>d;2z33((}}+R!K28>{=D-f!;`ldvnLr!82p^i=`0Xq@cuwd zz1@n3ZEFvN?f$#yLC?|)LDtnGF&|g?@y{(-|L - - 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 8db3c12ddba3248d61c96be09314d8a49c93330a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2349 zcmV+|3DWk7P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|clIti8{bv=k1SAlG`^o#a-jnmWp5x)km+2CeUcVrD?fmWHJH_GbISfC%i0uZwwp5+SbaN0G@*~! z3LEEud4l%XLgaLu0^lO(78pYT2>3)nD3MoYC4wI_0IIN@u{RnJAQ2ugl4A&oopNT= zjc=6pToz7j!^lklLP81(Y)YsAD@H;5Xv~PADnX)%BvHvuiqsTROp;R4WJ#`S(5RwG zRkIeYIpmlnr>r^Wl561-kOQTpq9vD7YGqfUs6tl7{ECsrEwtFArKT;n(rQQe^w_1R zu08kC>);Uv(!@wZM;>L=Np2!j%s6GHsWZq4xpu;P-Hmae?YsyEc=+_ulxH&CM! zHQq?sJiVcYQKx!|AWJ7=m;o`41jN-4KtQu$<}<~}hMZyM3u99V!$>h~+#o{?5XMO? zi*DF`Aomt-PV!s0@mI(>gYMrz&H=jLaeINb5?13JM)39 zFbdZkx|-LB1XI>AE9ad&ku$NKE#c0cTU{Y)Ypcxlh006erSDGLaRk2fxl5ttYnyl~ zv`tC!jjZI}nke9PRtwon+r|ATg)ucO1LmMAfsJ@R+_tMyWUC!Dd?)Yk)_p(EqtfMp zyaUowLuh5fDjfXc0P8wRrWMRP+sJIgKnru3?@_KS{TL8gjD{`Uv%^%irKy3~f!Elz zJTqWhSGf#Fxda*$jsgj9)VkCdLHz9m3JzB!5zcUKrXXO&^{4d4y|)RzrZ?{5H$SB} z?&3FZ&~`s)cIFXzj>$NN3_*xXaW1n{J0c%SEJa{&FlMcF{pF)m9hL;6vf)2fg+WCuF-cwk00D(*LqkwWLqi~Na&Km7Y-Iodc$|HaJxIe) z6opSyYelLK?I7Zip*mR*6>-!m6rn<>6<9(cW&*8oM0HI!Hn$;Ji;9VMSRbJ|`YC>4LCuVzld|SV+-%yn}zp^-JVZ$W;O(#{w$QAiI9>KlnXcD?d5m zC57TZ;Kgx1Mu6Zh(5N}i_p#$NP5}QiaHY5Wl{zr + + + 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 d55311cfc0d6eadc7635159d589e6f3bf43d449b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^96-#;!3HGxgLCzO6kC$Fy9>jA5L~c#`DBoEfk$L9 zP{(x;W^~e+T>%tiFY)wsWq-sf%%>%g8a6EtC=~1I;us=vx%a|G-ev~@my4FmzdR5- z5!-Wnp)7k|tC@#^7-t>J4Nj{G`?p-I>n&5CadDyJH(_aEwmX4Yhx)~3L9hFM;O0~@Y`yPJjzAP8^`v0k7f7ToAK#LeWUHx3vIVCg!09Z*yT>t<8 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 5f90ac334789f635124e97d7bb8a6ea7787f8991..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2219 zcmV;c2vqlpP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ak}M|-{O1%t0z!bqaabdK10UZhs(PJn&*slJ z6(7J^o^eB~*NRa-dPeoow~ zoWFHZOOD3=clRApfYM0Vh(nl6?Dty_4fyy~{1V>8(dMDG9(KFyViEv(Fz?cOe-F?j z_~(~R^XX9= zY`TcS#0JQDFUxoYzl3kuPr;+U`VPv6@4n&bR49Ozqc$@5s5PkxG7vgR*VV$BT?Z)HF1h5rJN+GOC{CJIp&memTXC`3QLqESwvKdRAr5t zG^?m;(ON=bj;Af z(!|I^hK@4oBsY;MW}Io}DN|>eb-~vbuej36OO~#(>Xo&V)ep}%Sfi7*u$i)Xa%By@ zPUIqjES)6d42*?HU|fs=ICL=1yi$z8m^03N2?&Z5pky*`+#q8N6vjy*ExK}dWA015 zxujp>EqunDGwS{i<{YT|$lD9nhMjZWAJJ%0Xqb9N^bM^+tHXKb?c=xYA3=Wv{ZIfx za807t`dY=!;$@8$W#JTDOJkmJ>nRmS;1c9yJ2~pKwK!(dx-Gq5SrH;@md3d(Oe%Fy z%d1aD9uY+HXk)e(>%`<}B3GDgi^g6hqEJ|aVzR2urSs#r?Xw_~*;_1S!UPUbgEaZk zWM(_+ySF&5jki`hhN-%uLO-{vA(kqNh^;gXk7cbiwkd&9Gx2?op`s8e_QfN3Yuhwj z6OeSzl25_o$pArb5I`)+1n4FK;Av=(OuXFct?u3S4i%L%*4XM~rSI2U_nifj-UHw$ z>Dr^`7|gKI6P%AEU2KFfv(jwb7P__<)8=7YX*T}ALibH5?k#+Aohy-o`nz{aR=PgI{cbF4g}hiVKN*_hAoreKh0_@?6NkP zT?V`>Bg*;XN?TzIsa8ADV{&+9)Q%lTWTB~s0cSmeJ$$2ePaP7oj?lH?e$yN3iHa*= z;Uw)7ecc;{uXX}{TX|cTx$_nk{49XHRiq%?X8_kUFKI z^owhwLl%#6A0k>aEjP9kSIp0!|#1d&YYxIjIP@EGCae*Oe^5GThEkgnPw#@0QKn3&|hu z$nDM@v$^Ar%scGwkOxk(aZ0#eYC$DkqM|N$0Ln+12!i^n)Bj+N2`4GC5WL>5(XB$) zm>cTiS^3S#E6;w$t~K0b%`m@kymz}tz{X_pmQl*1OKJKep&+{sIK3VA`~Dt33Srw9{9Ym`E4@YrxPE^yr=5{758n%c7n|M zS?PBz0kNvMe*vkRABT#Cf5iX*0flKpLr_UWLm+T+Z)Rz1WdHzpoPCi!NW)MRg-=s! zMXC<%AmWgrI$01Eanvdlp+cw?T6Hja=^r#{NK#xJ1=oUuKZ{id7iV1^Tm?b!2gJ$I zNzp}0ye}!Vi1otbeVljC;l29+p2$=}p_ zTyR<7nGrLcnkSABi-k5;+L#qhjd+SUs%kpr3mK19&Rd+da+Njj$zK@C=_|`zr!|ZO z7O?~gA{10nLK!wRRSZ&0xHlTyMFLL_&r-IKRMwgh2lWq z#c@7HfZ#6Bs5#E}vEwvO0RJ;^rMLW*IxzD|dab2JkAQ(~;NrTaDSN=>4lwv+$foQ{ zep*6454@kzH)VnFEzrB>&8>Nk(+40;vr66o2Zz9DfwI>-yt}7;ZvXZ)=l28J({gG@ z1)2H)000JJOGiWim;jIf8*f9VvH$=832;bRa{vGh*8l(w*8xH(n|J^K00(qQO+^Rf z1r8Gf4I;uhAOHXWaY;l$R2b8B%rOpvP!vSb<8R#7+YGH?5%jdbXBqVF!!?i(QW$KW zCYo@Y$xLqMQfqzU>YTk`#CjsE7z+mMXD=8^L^Skhe?mha5v}Af;ejLjk$r*!5pkfy tmePhUcb_K_amS1o=Inl? + + + 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 ee4730690ed34dae08551a914fcf1d83df820d6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRM!3HF?&tBaMq}Y|gW!U_%O``B6nI1y z19e;nVMZs7*%d%R_7YEDSN2D&!hBi^&i%^{0fkaLT^vIsE|;F#$a^S2gxR59s_V@G z1)jrRk*%o_$|jyHLZ>d;2z33((}}+R!K28>{=D-f!;`ldvnLr!82p^i=`0Xq@cuwd zz1@n3ZEFvN?f$#yLC?|)LDtnGF&|g?@y{(-|L10l zs6-SBA0&HFq?d@IBCvw!sS64Wq#&`EAbRQ#MD^5DG_!}$vcDPF-{<$8?|gSM-QN=q z)rTZW3ah<|6MPTy+7JxzwK`+Te5;~yH5=s5XwaAtO{aH|a(+eBns{W^;~%%MO-Q0j77 z0TXH1rJcN(r6E%`;G2U}M>w%8hy$YBCp3IVdgfBG^=am+&Jq2Uv4 z`y3BMVtXBLmpBCj7Gi z2KWW*#09$v)PxSmA`40_(O7Ixw2i-C@!U7g)K&s_iC&4@5`l`Wf6p)9<$cxHz)p#v ze1S=6cgRFKNMIhNy=qGLk2nW)Y+2l}m{vFi`QM<5<4+j=fHL^ + + 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 082109a21aa25b388d5ad2af6f0ef649ccf3df5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^96-#;!3HGxgLCzO6kC$Fy9>jA5L~c#`DBoEfk$L9 zP{(x;W^~e+T>%tiFY)wsWq-`g$R;APc;c%hpirZyi(`ny<d$a?$wRZx-V>g_*a@0$Z&f&TeA&i})*~m4D}$eN)wC!Ov*|Wjm521=Cj?y01UW h?na`p;N61z>~pp4Yo562e+N2-!PC{xWt~$(698^ORR910 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 56ae3993ef5d872369085366178e053ef4aa38f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 694 zcmYk3Uq}=|9LF~jJ1>lah)aqFGq9xHJGnxlLeIVQf>iPzPUyjP_jh}vyF1IwthX1T zY=}o4-(ZwPtnXCLc{!KVCM7t{(keF^8m z74QLwmHu*YiMM4(Th2oyXMkPBV_$nY$L96Uk|T0v!O*}&uR z9*QkAVlbgD#RA&~Cc9#&NQsL|oco6~je}W|kUC~Xj%WjvjDpFT)*n`E@U%f*ap2E= zR1gnL$Om>)Fr*I3V;7Y6WGb~knHKXqnOhOe)|%k~HEVXe(opI3&-ta>;yxE?5WhmP zUE<0>Fyden=|ouRtuhh^?m5EO)b2o;cjyF4r zjrBWhEpc4W|GqVu$?n>+@Fn^2?B&OB?Rux4=5GhzRllzOYH40A{8*g%Fn#g;-Qq-L Xeap?=k8nfXK2crCW&89ync=B_gXZ+l 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 c0d06861b1f1fe71b1085cd1250046612aa0c15a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRM!3HF?&tBaMq}Y|gW!U_%O``B6nI1y z19e;nVMZs7*%d%R_7YEDSN6x;jBLWz?u?FqfI`)tE{-7*mrKtXavcf~aJ~3AUuR89 z*7WINn}o$D@}_tvStlrZinQc^=2UuiFu7uS^cg+l`8RH#Tm7J^(s@SV&D3X%<}&|1 z%IA2w_`ERu%OU)$V}=(q^STwe*SE222ndSGPE*r;A+`M4E;HlfXKK=){WyF2ynMRN ct=P|u`Zukj&AfKp2Rehn)78&qol`;+0E=)`Jpcdz 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/Tango/graphics/branch_closed.png b/res/skins/Tango/graphics/branch_closed.png deleted file mode 100644 index aac367c5b22afce61fa74571d44a0084e0464f5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmYk3Uq}=|9LKk^<2pDjkubHG4B|@Ky;F%SD?RVhrSz`uAnhSqcjxX#cXzg#*>10l zs6-SBA0&HFq?d@IBCvw!sS64Wq#&`EAbRQ#MD^5DG_!}$vcDPF-{<$8?|gSM-QN=q z)rTZW3ah<|6MPTy+7JxzwK`+Te5;~yH5=s5XwaAtO{aH|a(+eBns{W^;~%%MO-Q0j77 z0TXH1rJcN(r6E%`;G2U}M>w%8hy$YBCp3IVdgfBG^=am+&Jq2Uv4 z`y3BMVtXBLmpBCj7Gi z2KWW*#09$v)PxSmA`40_(O7Ixw2i-C@!U7g)K&s_iC&4@5`l`Wf6p)9<$cxHz)p#v ze1S=6cgRFKNMIhNy=qGLk2nW)Y+2l}m{vFi`QM<5<4+j=fHL^ + + diff --git a/res/skins/Tango/graphics/branch_open.png b/res/skins/Tango/graphics/branch_open.png deleted file mode 100644 index 56ae3993ef5d872369085366178e053ef4aa38f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 694 zcmYk3Uq}=|9LF~jJ1>lah)aqFGq9xHJGnxlLeIVQf>iPzPUyjP_jh}vyF1IwthX1T zY=}o4-(ZwPtnXCLc{!KVCM7t{(keF^8m z74QLwmHu*YiMM4(Th2oyXMkPBV_$nY$L96Uk|T0v!O*}&uR z9*QkAVlbgD#RA&~Cc9#&NQsL|oco6~je}W|kUC~Xj%WjvjDpFT)*n`E@U%f*ap2E= zR1gnL$Om>)Fr*I3V;7Y6WGb~knHKXqnOhOe)|%k~HEVXe(opI3&-ta>;yxE?5WhmP zUE<0>Fyden=|ouRtuhh^?m5EO)b2o;cjyF4r zjrBWhEpc4W|GqVu$?n>+@Fn^2?B&OB?Rux4=5GhzRllzOYH40A{8*g%Fn#g;-Qq-L Xeap?=k8nfXK2crCW&89ync=B_gXZ+l 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 bb55b1ae7b6b..aaa25c6efb3a 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -2493,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 { @@ -2503,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 { From 743b968b5bc604ab9d3e41ace0ba1e18b6110033 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Wed, 9 Jun 2021 12:09:50 +0200 Subject: [PATCH 13/56] Skins: fix menubar checkbox selection highlight on Linux --- res/skins/default-menu-styles-linux.qss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } From 58a998f34143fb504bdeb26aee9f42f3b13fc024 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Wed, 9 Jun 2021 22:52:34 +0200 Subject: [PATCH 14/56] Skins, context menus: dim all disabled menu items --- res/skins/Deere/style.qss | 5 ++--- res/skins/LateNight/style_classic.qss | 4 ++-- res/skins/LateNight/style_palemoon.qss | 5 +++-- res/skins/Shade/style.qss | 4 +++- res/skins/Shade/style_dark.qss | 4 +++- res/skins/Tango/style.qss | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 42fe4e5cf222..9d23567fc39b 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -2107,15 +2107,14 @@ 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 { diff --git a/res/skins/LateNight/style_classic.qss b/res/skins/LateNight/style_classic.qss index d6c51a243673..46b2e1096ed2 100644 --- a/res/skins/LateNight/style_classic.qss +++ b/res/skins/LateNight/style_classic.qss @@ -2411,10 +2411,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, diff --git a/res/skins/LateNight/style_palemoon.qss b/res/skins/LateNight/style_palemoon.qss index 39b21b24b36c..19ab4070f6cb 100644 --- a/res/skins/LateNight/style_palemoon.qss +++ b/res/skins/LateNight/style_palemoon.qss @@ -2881,9 +2881,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, diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index f1497c470884..849df4b9d844 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -350,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, diff --git a/res/skins/Shade/style_dark.qss b/res/skins/Shade/style_dark.qss index a6c06f79c3df..7ba324e84720 100644 --- a/res/skins/Shade/style_dark.qss +++ b/res/skins/Shade/style_dark.qss @@ -100,7 +100,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/Tango/style.qss b/res/skins/Tango/style.qss index aaa25c6efb3a..ad947a7dfca5 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -2259,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, From cb8e82cc402aadc7f1fb88a9b75f360fb9719f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 10 Jun 2021 13:51:55 +0200 Subject: [PATCH 15/56] Add a comment spelling the Qt version literaly --- tools/qmlformat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/qmlformat.py b/tools/qmlformat.py index dfedf14d36e2..d009c0f8a614 100755 --- a/tools/qmlformat.py +++ b/tools/qmlformat.py @@ -27,6 +27,7 @@ def main(argv=None): 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 From c84bd755e954653f362cbd6f81b0b1a6535c896c Mon Sep 17 00:00:00 2001 From: ronso0 Date: Fri, 11 Jun 2021 18:40:13 +0200 Subject: [PATCH 16/56] Skin context menus: decrease item padding a bit --- res/skins/default.qss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/skins/default.qss b/res/skins/default.qss index 8bde1a97b0c6..e7090c3cf692 100644 --- a/res/skins/default.qss +++ b/res/skins/default.qss @@ -125,7 +125,7 @@ WTrackTableViewHeader QMenu::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.25em 0.6em 0.24em 1.3em; + padding: 0.17em 0.6em 0.17em 1.3em; } WTrackMenu::item, @@ -139,7 +139,7 @@ QLineEdit QMenu::item, WCoverArtMenu::item, /* for the sake of completeness: html root view of Crates, Rec etc. */ WLibraryTextBrowser QMenu::item { - padding: 0.25em 0.6em 0.25em 0.6em; + padding: 0.17em 0.6em 0.17em 0.6em; } /* Icons in those menus (copy, paste, cut, delete) */ @@ -160,7 +160,7 @@ WTrackTableViewHeader QMenu::indicator { /* items in Crate sub menu */ WTrackMenu QMenu QCheckBox { - padding: 0.15em 0.5em 0.15em 0.25em; + padding: 0.17em 0.6em 0.17em 0.25em; } WLibrarySidebar QMenu::indicator, From 77051f868a1642980e152fa4896d08af329b6c95 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Fri, 11 Jun 2021 18:54:09 +0200 Subject: [PATCH 17/56] Skins: replace remaining px with em for the table header --- res/skins/Deere/style.qss | 2 +- res/skins/LateNight/style.qss | 15 +++------------ res/skins/Shade/style.qss | 4 ++-- res/skins/Tango/style.qss | 4 ++-- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index 9d23567fc39b..c34c46e70183 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -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; diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index f2652b7868c6..49ad463ce1e2 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -160,15 +160,6 @@ WEffectSelector::item:selected, border: 0px; } -WLibrarySidebar QMenu::separator, -WLibraryTextBrowser QMenu::separator, -WTrackMenu::separator, -WTrackMenu QMenu::separator, -QLineEdit QMenu::separator { - height: 0px; - margin: 4px; -} - WLibrarySidebar QMenu::indicator, WTrackTableViewHeader QMenu::indicator, WTrackMenu QMenu QCheckBox::indicator { @@ -293,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/Shade/style.qss b/res/skins/Shade/style.qss index 849df4b9d844..e0fadce86088 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -661,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; @@ -672,7 +672,7 @@ WTrackTableViewHeader::section { WTrackTableViewHeader::up-arrow, WTrackTableViewHeader::down-arrow { width: 0.6em; - padding-right: 2px; + padding-right: 0.1em; margin-right: 1px; background-color: rgba(98,111,135,255); } diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index ad947a7dfca5..2f8e4871126a 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -2542,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; @@ -2557,7 +2557,7 @@ WTrackTableViewHeader { WTrackTableViewHeader::up-arrow, WTrackTableViewHeader::down-arrow { width: 0.6em; - padding-right: 2px; + padding-right: 0.1em; border-right: 1px solid #585858; background-color: rgba(51,51,51,200); } From 3e9e2f8446f2049b6c347887f27bf1ebe94fdbf3 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Fri, 11 Jun 2021 18:55:35 +0200 Subject: [PATCH 18/56] Skin qss: add/fix missing menu separators, fix font in LateNight --- res/skins/LateNight/style.qss | 2 +- res/skins/Shade/style_dark.qss | 1 + res/skins/Shade/style_summer_sunset.qss | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index 49ad463ce1e2..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, diff --git a/res/skins/Shade/style_dark.qss b/res/skins/Shade/style_dark.qss index 7ba324e84720..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; } 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; } From 5ce36cbb39229b4eadedd42babe4f820cb0bdef9 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Fri, 11 Jun 2021 01:53:13 +0200 Subject: [PATCH 19/56] Waveforms on macOS: don't offer simple renderers (RGB, HSV, Filtered) --- src/waveform/waveformwidgetfactory.cpp | 16 ++++++++++++ src/waveform/widgets/waveformwidgettype.h | 30 +++++++++++------------ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/waveform/waveformwidgetfactory.cpp b/src/waveform/waveformwidgetfactory.cpp index 5c80bb39fd52..b0e05e55eedc 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/widgets/waveformwidgettype.h b/src/waveform/widgets/waveformwidgettype.h index a2a889a033bb..dfb9c7625c4f 100644 --- a/src/waveform/widgets/waveformwidgettype.h +++ b/src/waveform/widgets/waveformwidgettype.h @@ -6,21 +6,21 @@ class WaveformWidgetType { // The order must not be changed because the waveforms are referenced // from the sorted preferences by a number. EmptyWaveform = 0, - SoftwareSimpleWaveform, //TODO - SoftwareWaveform, - QtSimpleWaveform, - QtWaveform, - GLSimpleWaveform, - GLFilteredWaveform, - GLSLFilteredWaveform, - HSVWaveform, - GLVSyncTest, - RGBWaveform, - GLRGBWaveform, - GLSLRGBWaveform, - QtVSyncTest, - QtHSVWaveform, - QtRGBWaveform, + SoftwareSimpleWaveform, //TODO + SoftwareWaveform, // Filtered + QtSimpleWaveform, // Simple Qt + QtWaveform, // Filtered Qt + GLSimpleWaveform, // Simple GL + GLFilteredWaveform, // Filtered GL + GLSLFilteredWaveform, // Filtered GLSL + HSVWaveform, // HSV + GLVSyncTest, // VSync GL + RGBWaveform, // RGB + GLRGBWaveform, // RGB GL + GLSLRGBWaveform, // RGB GLSL + QtVSyncTest, // VSync Qt + QtHSVWaveform, // HSV Qt + QtRGBWaveform, // RGB Qt Count_WaveformwidgetType // Also used as invalid value }; }; From 74fded22c2a22eeb7740611eea46f140c948ed31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 12 Jun 2021 02:03:24 +0200 Subject: [PATCH 20/56] Fix package dependency for ffmpeg --- packaging/CPackDebInstall.cmake | 2 +- packaging/CPackDebUploadPPA.cmake | 2 +- tools/debian_buildenv.sh | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) 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 6a2f5ec5f240..b817b3f7631f 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/tools/debian_buildenv.sh b/tools/debian_buildenv.sh index 7705bd10194a..73a9ecc00b3e 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 \ From 257ebb9520ad5978f1abae142e1b9eff9cb815da Mon Sep 17 00:00:00 2001 From: Geovanni Pacheco Date: Fri, 11 Jun 2021 22:16:19 -0300 Subject: [PATCH 21/56] [DDJ 200] Fix headphone master button led The led button was turned on when disabled and off when enabled. This PR fix this behavior. --- res/controllers/Pioneer-DDJ-200-scripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 } }; From eb738d559b41814ff172c3e2a41e1ec3056b403b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Sat, 12 Jun 2021 03:10:05 +0200 Subject: [PATCH 22/56] Fix not working cmake default_option() with braces in the default string --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ef98feaa283..7a03f7c83b2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2265,12 +2265,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.") From 3da172f06bbc262b4439cc983327296e5f438bdf Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 12 Jun 2021 13:51:03 +0200 Subject: [PATCH 23/56] CI: Use custom CMake version on macOS/Ubuntu 18.04 only --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 48835fa32327..c9f20f76cf77 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -180,8 +180,11 @@ jobs: # Possibly related: actions/checkout#290 run: git fetch origin --force --tags - - name: "Set up cmake" + - name: "[macOS/Ubuntu 18.04] Set up cmake" uses: jwlawson/actions-setup-cmake@v1.4 + # 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' || matrix.os == 'ubuntu-18.04' with: # This should always match the mininum required version in # our CMakeLists.txt From a91affac2590bfc9f8d3345b8186c2897739021d Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 12 Jun 2021 16:26:03 +0200 Subject: [PATCH 24/56] CI: Remove references to ubuntu-18.04 from build --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 88fb417f7d35..a0ac0a6e5c5a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -157,11 +157,11 @@ jobs: # Possibly related: actions/checkout#290 run: git fetch origin --force --tags - - name: "[macOS/Ubuntu 18.04] Set up cmake" + - name: "[macOS] Set up cmake" uses: jwlawson/actions-setup-cmake@v1.4 # 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' || matrix.os == 'ubuntu-18.04' + if: runner.os == 'macOS' with: # This should always match the mininum required version in # our CMakeLists.txt From 0d4f6fdc0ec44c4f264c20d4e1a87d80e0812243 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 12 Jun 2021 16:26:43 +0200 Subject: [PATCH 25/56] CI: Upgrade jwlawson/actions-setup-cmake from v1.4 to v1.9 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0ac0a6e5c5a..ef9513853f96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -158,7 +158,7 @@ jobs: run: git fetch origin --force --tags - name: "[macOS] Set up cmake" - uses: jwlawson/actions-setup-cmake@v1.4 + 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' From b5616dd76fe2f56c9de43afd9aaf3522007d6cfc Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 12 Jun 2021 16:28:55 +0200 Subject: [PATCH 26/56] Enable StatementMacros in .clang-format --- .clang-format | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) 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 From 7bfc8ac3d657a3556bdb562e80f9242af010fa2e Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 12 Jun 2021 16:34:13 +0200 Subject: [PATCH 27/56] Delete obsolete comments referencing Ubuntu Bionic 18.04 --- src/encoder/encoderfdkaac.cpp | 2 +- src/encoder/encodersndfileflac.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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) { From 97218633ef4497bcea62dfd9b1b6cd0895c58d93 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Sat, 12 Jun 2021 16:34:42 +0200 Subject: [PATCH 28/56] Delete obsolete workaround when casting a double into an enum --- src/widget/whotcuebutton.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/widget/whotcuebutton.cpp b/src/widget/whotcuebutton.cpp index 49942996f826..d8d954f1582d 100644 --- a/src/widget/whotcuebutton.cpp +++ b/src/widget/whotcuebutton.cpp @@ -175,11 +175,7 @@ void WHotcueButton::slotColorChanged(double color) { } void WHotcueButton::slotTypeChanged(double type) { - // If the cast is put directly into the switch case, this seems to trigger - // a false positive warning on gcc 7.5.0 on Ubuntu 18.04.4 Bionic, so we cast - // it to int first and save to a local const variable. - const mixxx::CueType cueType = static_cast(static_cast(type)); - switch (cueType) { + switch (static_cast(static_cast(type))) { case mixxx::CueType::Invalid: m_type = QLatin1String(""); break; From 068d4b9758da9469cb9a5f1651b451f1b74b1b46 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sat, 12 Jun 2021 23:54:42 +0200 Subject: [PATCH 29/56] skins/QMLDemo: Move image sources to theme singleton --- res/skins/QMLDemo/Button.qml | 8 ++++---- res/skins/QMLDemo/CrossfaderRow.qml | 4 ++-- res/skins/QMLDemo/Deck.qml | 2 +- res/skins/QMLDemo/HotcuePopup.qml | 2 +- res/skins/QMLDemo/Knob.qml | 4 ++-- res/skins/QMLDemo/MixerColumn.qml | 2 +- res/skins/QMLDemo/Slider.qml | 2 +- res/skins/QMLDemo/Theme/Theme.qml | 10 ++++++++++ 8 files changed, 22 insertions(+), 12 deletions(-) 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/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index 1c1c106c7e58..21910e55e391 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -28,8 +28,8 @@ Item { key: "crossfader" barColor: Theme.crossfaderBarColor barStart: 0.5 - fg: "images/slider_handle_crossfader.svg" - bg: "images/slider_crossfader.svg" + fg: Theme.imgCrossfaderHandle + bg: Theme.imgCrossfaderBackground } Item { diff --git a/res/skins/QMLDemo/Deck.qml b/res/skins/QMLDemo/Deck.qml index f30c7edcee80..fb96ba9438f0 100644 --- a/res/skins/QMLDemo/Deck.qml +++ b/res/skins/QMLDemo/Deck.qml @@ -37,7 +37,7 @@ Item { key: "rate" barStart: 0.5 barColor: Theme.bpmSliderBarColor - bg: "images/slider_bpm.svg" + bg: Theme.imgBpmSliderBackground FadeBehavior on visible { fadeTarget: rateSlider 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/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/Slider.qml b/res/skins/QMLDemo/Slider.qml index 7a5d67d09012..750cd0b1461f 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 } diff --git a/res/skins/QMLDemo/Theme/Theme.qml b/res/skins/QMLDemo/Theme/Theme.qml index 4bf19a9c3b25..dcfe8796cad1 100644 --- a/res/skins/QMLDemo/Theme/Theme.qml +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -35,4 +35,14 @@ QtObject { 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 imgPopupBackground: imgButton + property string imgKnob: "images/knob.svg" + property string imgKnobShadow: "images/knob_shadow.svg" } From 97c85416ef8351ce4ca7ddd7fdf257bb13e5c6de Mon Sep 17 00:00:00 2001 From: ronso0 Date: Sun, 13 Jun 2021 16:57:57 +0200 Subject: [PATCH 30/56] LateNight: fix scaling of icons still using background-image --- res/skins/LateNight/style_classic.qss | 2 +- res/skins/LateNight/style_palemoon.qss | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/res/skins/LateNight/style_classic.qss b/res/skins/LateNight/style_classic.qss index 46b2e1096ed2..3a4e3f4f089d 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; diff --git a/res/skins/LateNight/style_palemoon.qss b/res/skins/LateNight/style_palemoon.qss index 19ab4070f6cb..d0cb1fb57524 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; @@ -2131,21 +2131,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"] { @@ -2718,11 +2712,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 From 876db3ef1dd86c64794f7b57c6a5cec64533c494 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Sun, 13 Jun 2021 17:12:55 +0200 Subject: [PATCH 31/56] Skins, waveforms: remove I-beam from in/outro marker to equalize marker size --- res/skins/Deere/deck_waveform.xml | 8 ++++---- res/skins/Shade/waveform.xml | 8 ++++---- res/skins/Tango/waveform.xml | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/res/skins/Deere/deck_waveform.xml b/res/skins/Deere/deck_waveform.xml index 52a290eb3fa6..775e017d02ea 100644 --- a/res/skins/Deere/deck_waveform.xml +++ b/res/skins/Deere/deck_waveform.xml @@ -83,7 +83,7 @@ intro_start_position [Skin],show_intro_outro_cues - |◢ + bottom #0000FF #FFFFFF @@ -91,7 +91,7 @@ intro_end_position [Skin],show_intro_outro_cues - ◢| + bottom #0000FF #FFFFFF @@ -107,7 +107,7 @@ outro_start_position [Skin],show_intro_outro_cues - |◣ + bottom #0000FF #FFFFFF @@ -115,7 +115,7 @@ outro_end_position [Skin],show_intro_outro_cues - ◣| + bottom #0000FF #FFFFFF diff --git a/res/skins/Shade/waveform.xml b/res/skins/Shade/waveform.xml index ed974b6e874f..0ded5f03150d 100644 --- a/res/skins/Shade/waveform.xml +++ b/res/skins/Shade/waveform.xml @@ -68,7 +68,7 @@ intro_start_position [Skin],show_intro_outro_cues - |◢ + bottom #0000FF #FFFFFF @@ -77,7 +77,7 @@ intro_end_position [Skin],show_intro_outro_cues - ◢| + bottom #0000FF 0.1 @@ -86,7 +86,7 @@ outro_start_position [Skin],show_intro_outro_cues - |◣ + bottom #0000FF #FFFFFF @@ -94,7 +94,7 @@ outro_end_position [Skin],show_intro_outro_cues - ◣| + bottom #0000FF #FFFFFF diff --git a/res/skins/Tango/waveform.xml b/res/skins/Tango/waveform.xml index 03418eb8c26c..4aafc64b4cc7 100644 --- a/res/skins/Tango/waveform.xml +++ b/res/skins/Tango/waveform.xml @@ -76,7 +76,7 @@ Variables: intro_start_position [Skin],show_intro_outro_cues - |◢ + bottom #0000FF #FFFFFF @@ -84,7 +84,7 @@ Variables: intro_end_position [Skin],show_intro_outro_cues - ◢| + bottom #0000FF #FFFFFF @@ -99,7 +99,7 @@ Variables: outro_start_position [Skin],show_intro_outro_cues - |◣ + bottom #0000FF #FFFFFF @@ -107,7 +107,7 @@ Variables: outro_end_position [Skin],show_intro_outro_cues - ◣| + bottom #0000FF #FFFFFF From f63a674d85f93076d7b7ca03a98edfd289451835 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Sun, 13 Jun 2021 03:55:38 +0200 Subject: [PATCH 32/56] DlgPrefWaveforms: sort waveform types alphabetically --- src/preferences/dialog/dlgprefwaveform.cpp | 15 ++++++---- src/waveform/waveformwidgetfactory.h | 3 ++ src/waveform/widgets/waveformwidgettype.h | 32 +++++++++++----------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/preferences/dialog/dlgprefwaveform.cpp b/src/preferences/dialog/dlgprefwaveform.cpp index 5d341bdf0885..7bb1cdde9eba 100644 --- a/src/preferences/dialog/dlgprefwaveform.cpp +++ b/src/preferences/dialog/dlgprefwaveform.cpp @@ -24,11 +24,15 @@ DlgPrefWaveform::DlgPrefWaveform(QWidget* pParent, MixxxMainWindow* pMixxx, // 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); @@ -141,8 +145,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); } @@ -244,7 +248,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/waveform/waveformwidgetfactory.h b/src/waveform/waveformwidgetfactory.h index 514a1a9402b2..04111e96c932 100644 --- a/src/waveform/waveformwidgetfactory.h +++ b/src/waveform/waveformwidgetfactory.h @@ -92,6 +92,9 @@ class WaveformWidgetFactory : public QObject, public Singleton Date: Sun, 13 Jun 2021 16:37:55 +0200 Subject: [PATCH 33/56] DlgPrefWaveforms: adjust ResetToDefault to new combobox content --- src/preferences/dialog/dlgprefwaveform.cpp | 8 ++++---- src/waveform/waveformwidgetfactory.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/preferences/dialog/dlgprefwaveform.cpp b/src/preferences/dialog/dlgprefwaveform.cpp index 7bb1cdde9eba..8bf3f5682a11 100644 --- a/src/preferences/dialog/dlgprefwaveform.cpp +++ b/src/preferences/dialog/dlgprefwaveform.cpp @@ -195,10 +195,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); } diff --git a/src/waveform/waveformwidgetfactory.h b/src/waveform/waveformwidgetfactory.h index 04111e96c932..483ea4caad85 100644 --- a/src/waveform/waveformwidgetfactory.h +++ b/src/waveform/waveformwidgetfactory.h @@ -95,6 +95,7 @@ class WaveformWidgetFactory : public QObject, public Singleton Date: Mon, 14 Jun 2021 01:00:39 +0200 Subject: [PATCH 34/56] Skins, waveforms: position in/outro markers inside the range --- res/skins/Deere/deck_waveform.xml | 8 ++++---- res/skins/Shade/waveform.xml | 24 ++++++++++++------------ res/skins/Tango/waveform.xml | 8 ++++---- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/res/skins/Deere/deck_waveform.xml b/res/skins/Deere/deck_waveform.xml index 775e017d02ea..344879676d4c 100644 --- a/res/skins/Deere/deck_waveform.xml +++ b/res/skins/Deere/deck_waveform.xml @@ -84,7 +84,7 @@ intro_start_position [Skin],show_intro_outro_cues - bottom + bottom|right #0000FF #FFFFFF @@ -92,7 +92,7 @@ intro_end_position [Skin],show_intro_outro_cues - bottom + bottom|left #0000FF #FFFFFF @@ -108,7 +108,7 @@ outro_start_position [Skin],show_intro_outro_cues - bottom + bottom|right #0000FF #FFFFFF @@ -116,7 +116,7 @@ outro_end_position [Skin],show_intro_outro_cues - bottom + bottom|left #0000FF #FFFFFF diff --git a/res/skins/Shade/waveform.xml b/res/skins/Shade/waveform.xml index 0ded5f03150d..739ac9e64a82 100644 --- a/res/skins/Shade/waveform.xml +++ b/res/skins/Shade/waveform.xml @@ -59,35 +59,35 @@ #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 @@ -95,7 +95,7 @@ outro_end_position [Skin],show_intro_outro_cues - bottom + bottom|left #0000FF #FFFFFF diff --git a/res/skins/Tango/waveform.xml b/res/skins/Tango/waveform.xml index 4aafc64b4cc7..3225d6a004ce 100644 --- a/res/skins/Tango/waveform.xml +++ b/res/skins/Tango/waveform.xml @@ -77,7 +77,7 @@ Variables: intro_start_position [Skin],show_intro_outro_cues - bottom + bottom|right #0000FF #FFFFFF @@ -85,7 +85,7 @@ Variables: intro_end_position [Skin],show_intro_outro_cues - bottom + bottom|left #0000FF #FFFFFF @@ -100,7 +100,7 @@ Variables: outro_start_position [Skin],show_intro_outro_cues - bottom + bottom|right #0000FF #FFFFFF @@ -108,7 +108,7 @@ Variables: outro_end_position [Skin],show_intro_outro_cues - bottom + bottom|left #0000FF #FFFFFF From 6e50a347093886f0e4a8e42daf560c628595b2ad Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Mon, 14 Jun 2021 20:09:26 +0200 Subject: [PATCH 35/56] SoundSourceFLAC: Fix armv7hl build on gcc 11.1 ../src/sources/soundsourceflac.cpp: In member function 'FLAC__StreamDecoderWriteStatus mixxx::SoundSourceFLAC::flacWrite(const FLAC__Frame*, const FLAC__int32* const*)': ../src/sources/soundsourceflac.cpp:426:41: error: comparison of integer expressions of different signedness: 'mixxx::audio::SampleRate::value_t' {aka 'unsigned int'} and 'SINT' {aka 'int'} [-Werror=sign-compare] 426 | if (getSignalInfo().getSampleRate() != SINT(frame->header.sample_rate)) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1plus: all warnings being treated as errors --- src/sources/soundsourceflac.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) 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) From a7b827b42010634e727f4432127cb4cbb6cf6f2f Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 13 Jun 2021 14:55:27 +0200 Subject: [PATCH 36/56] skins/QMLDemo: Add section background --- res/skins/QMLDemo/CrossfaderRow.qml | 42 +++++++++++++++----- res/skins/QMLDemo/Deck.qml | 9 +++++ res/skins/QMLDemo/DeckInfoBar.qml | 13 +++++-- res/skins/QMLDemo/DeckRow.qml | 4 +- res/skins/QMLDemo/Mixer.qml | 51 ++++++++++++++++--------- res/skins/QMLDemo/SectionBackground.qml | 16 ++++++++ res/skins/QMLDemo/Theme/Theme.qml | 2 + res/skins/QMLDemo/images/section.svg | 2 + res/skins/QMLDemo/main.qml | 10 ++--- 9 files changed, 107 insertions(+), 42 deletions(-) create mode 100644 res/skins/QMLDemo/SectionBackground.qml create mode 100644 res/skins/QMLDemo/images/section.svg diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index 21910e55e391..b0bbc07fb05a 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -8,36 +8,58 @@ Item { property real crossfaderWidth // required - implicitHeight: crossfaderSlider.height + 5 + implicitHeight: crossfader.height Item { id: effectUnitLeftPlaceholder anchors.top: parent.top anchors.left: parent.left + anchors.right: crossfader.left anchors.bottom: parent.bottom + + Skin.SectionBackground { + anchors.fill: parent + } + } - 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: Theme.imgCrossfaderHandle - bg: Theme.imgCrossfaderBackground + height: crossfaderSlider.height + 20 + + Skin.ControlSlider { + id: crossfaderSlider + + anchors.left: parent.left + anchors.right: parent.right + 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 anchors.top: parent.top + anchors.left: crossfader.right anchors.right: parent.right anchors.bottom: parent.bottom + + Skin.SectionBackground { + anchors.fill: parent + } + } } diff --git a/res/skins/QMLDemo/Deck.qml b/res/skins/QMLDemo/Deck.qml index fb96ba9438f0..bc4fa84ccbf1 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 @@ -298,6 +305,8 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 5 + anchors.rightMargin: 5 + anchors.bottomMargin: 5 height: 56 visible: !root.minimized diff --git a/res/skins/QMLDemo/DeckInfoBar.qml b/res/skins/QMLDemo/DeckInfoBar.qml index de084eaa99d5..39698b790712 100644 --- a/res/skins/QMLDemo/DeckInfoBar.qml +++ b/res/skins/QMLDemo/DeckInfoBar.qml @@ -13,6 +13,8 @@ Rectangle { property color textColor: Theme.deckTextColor property color lineColor: Theme.deckLineColor + border.width: 2 + border.color: Theme.deckBackgroundColor radius: 5 height: 56 @@ -226,15 +228,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/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/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/Theme/Theme.qml b/res/skins/QMLDemo/Theme/Theme.qml index dcfe8796cad1..2b07bcd333c6 100644 --- a/res/skins/QMLDemo/Theme/Theme.qml +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -29,6 +29,7 @@ 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 @@ -45,4 +46,5 @@ QtObject { property string imgPopupBackground: imgButton property string imgKnob: "images/knob.svg" property string imgKnobShadow: "images/knob_shadow.svg" + property string imgSectionBackground: "images/section.svg" } 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/main.qml b/res/skins/QMLDemo/main.qml index 9a4a3f643bc3..933eee3304c6 100644 --- a/res/skins/QMLDemo/main.qml +++ b/res/skins/QMLDemo/main.qml @@ -17,7 +17,6 @@ Rectangle { Column { anchors.fill: parent - spacing: 10 Rectangle { id: toolbar @@ -56,8 +55,7 @@ Rectangle { leftDeckGroup: "[Channel1]" rightDeckGroup: "[Channel2]" - width: parent.width - 10 - x: 5 + width: parent.width minimized: root.maximizeLibrary } @@ -65,8 +63,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 +77,7 @@ Rectangle { leftDeckGroup: "[Channel3]" rightDeckGroup: "[Channel4]" - width: parent.width - 10 - x: 5 + width: parent.width minimized: root.maximizeLibrary visible: root.show4decks From 809a57b16642e821f5f080eab72e3f2ef75285ec Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Sun, 13 Jun 2021 16:43:16 +0200 Subject: [PATCH 37/56] skins/QMLDemo: Add sampler row --- res/skins/QMLDemo/ControlMiniKnob.qml | 22 +++ res/skins/QMLDemo/EmbeddedBackground.qml | 10 ++ res/skins/QMLDemo/MiniKnob.qml | 58 +++++++ res/skins/QMLDemo/Sampler.qml | 159 +++++++++++++++++++ res/skins/QMLDemo/SamplerRow.qml | 18 +++ res/skins/QMLDemo/Theme/Theme.qml | 2 + res/skins/QMLDemo/images/miniknob.svg | 2 + res/skins/QMLDemo/images/miniknob_shadow.svg | 2 + res/skins/QMLDemo/main.qml | 21 +++ 9 files changed, 294 insertions(+) create mode 100644 res/skins/QMLDemo/ControlMiniKnob.qml create mode 100644 res/skins/QMLDemo/EmbeddedBackground.qml create mode 100644 res/skins/QMLDemo/MiniKnob.qml create mode 100644 res/skins/QMLDemo/Sampler.qml create mode 100644 res/skins/QMLDemo/SamplerRow.qml create mode 100644 res/skins/QMLDemo/images/miniknob.svg create mode 100644 res/skins/QMLDemo/images/miniknob_shadow.svg 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/EmbeddedBackground.qml b/res/skins/QMLDemo/EmbeddedBackground.qml new file mode 100644 index 000000000000..657b3903bbdc --- /dev/null +++ b/res/skins/QMLDemo/EmbeddedBackground.qml @@ -0,0 +1,10 @@ +import QtQuick 2.12 +import "Theme" + +Rectangle { + id: root + + border.width: 2 + border.color: Theme.deckBackgroundColor + radius: 5 +} diff --git a/res/skins/QMLDemo/MiniKnob.qml b/res/skins/QMLDemo/MiniKnob.qml new file mode 100644 index 000000000000..1a738428dd2d --- /dev/null +++ b/res/skins/QMLDemo/MiniKnob.qml @@ -0,0 +1,58 @@ +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 { + id: inidicator + + 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/Sampler.qml b/res/skins/QMLDemo/Sampler.qml new file mode 100644 index 000000000000..02b2a8dcc71c --- /dev/null +++ b/res/skins/QMLDemo/Sampler.qml @@ -0,0 +1,159 @@ +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 + color: Theme.deckBackgroundColor + } + + 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.gainKnobColor + } + + Skin.ControlButton { + id: playButton + + anchors.top: embedded.top + anchors.left: embedded.left + activeColor: Theme.gainKnobColor + width: 40 + height: 40 + text: "Play" + group: root.group + key: "play" + highlight: playControl.value + + Mixxx.ControlProxy { + id: playControl + + group: root.group + key: "play_indicator" + } + + } + + 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.gainKnobColor + + Mixxx.ControlProxy { + id: playPositionControl + + group: root.group + key: "playposition" + } + + } + + MouseArea { + id: mousearea + + anchors.fill: progressContainer + cursorShape: Qt.PointingHandCursor + hoverEnabled: true + onPressed: { + playPositionControl.value = mouse.x / mousearea.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 + } + + DropArea { + 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); + } + } + } + +} 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/Theme/Theme.qml b/res/skins/QMLDemo/Theme/Theme.qml index 2b07bcd333c6..a34043da011f 100644 --- a/res/skins/QMLDemo/Theme/Theme.qml +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -46,5 +46,7 @@ QtObject { 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/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/main.qml b/res/skins/QMLDemo/main.qml index 933eee3304c6..8447c2cf255f 100644 --- a/res/skins/QMLDemo/main.qml +++ b/res/skins/QMLDemo/main.qml @@ -8,6 +8,7 @@ Rectangle { id: root property alias show4decks: show4DecksButton.checked + property alias showSamplers: showSamplersButton.checked property alias maximizeLibrary: maximizeLibraryButton.checked width: 1920 @@ -46,6 +47,14 @@ Rectangle { checkable: true } + Skin.Button { + id: showSamplersButton + + text: "Sampler" + activeColor: Theme.white + checkable: true + } + } } @@ -87,6 +96,18 @@ Rectangle { } + SamplerRow { + id: samplers + + width: parent.width + visible: root.showSamplers + + FadeBehavior on visible { + fadeTarget: samplers + } + + } + Library { width: parent.width height: parent.height - y From e04eb9a9670c54f8e813c9c01da7433c9ec33efe Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 14 Jun 2021 00:14:48 +0200 Subject: [PATCH 38/56] QML: Add arcStart property to Knob control --- res/skins/QMLDemo/Mixxx/Controls/Knob.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml index ad7a709b1a39..9b4f1a7bd3ef 100644 --- a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml +++ b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml @@ -15,6 +15,7 @@ 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 @@ -50,8 +51,8 @@ Item { fillColor: "transparent" PathAngleArc { - startAngle: -90 - sweepAngle: (root.value - (root.max - root.min) / 2) * 2 * root.angle + startAngle: -90 + root.angle * 2 * (root.arcStart - (root.max - root.min) / 2) + sweepAngle: (root.value - root.arcStart) * 2 * root.angle radiusX: root.arcRadius radiusY: root.arcRadius centerX: root.width / 2 + root.arcOffsetX From fb16c6da6517e30ca783604b87270139109ffe23 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 14 Jun 2021 00:16:03 +0200 Subject: [PATCH 39/56] skins/QMLDemo: Add basic effect units --- res/skins/QMLDemo/ComboBox.qml | 65 +++++++++++++++++ res/skins/QMLDemo/CrossfaderRow.qml | 20 ++---- res/skins/QMLDemo/EffectUnit.qml | 104 ++++++++++++++++++++++++++++ res/skins/QMLDemo/Theme/Theme.qml | 2 + 4 files changed, 177 insertions(+), 14 deletions(-) create mode 100644 res/skins/QMLDemo/ComboBox.qml create mode 100644 res/skins/QMLDemo/EffectUnit.qml diff --git a/res/skins/QMLDemo/ComboBox.qml b/res/skins/QMLDemo/ComboBox.qml new file mode 100644 index 000000000000..539de34449e6 --- /dev/null +++ b/res/skins/QMLDemo/ComboBox.qml @@ -0,0 +1,65 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import "Theme" + +ComboBox { + id: root + + background: Skin.EmbeddedBackground { + color: Theme.embeddedBackgroundColor + } + + 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 { + color: Theme.embeddedBackgroundColor + } + + } + +} diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index b0bbc07fb05a..922e42b8047e 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -10,18 +10,14 @@ Item { implicitHeight: crossfader.height - Item { - id: effectUnitLeftPlaceholder + Skin.EffectUnit { + id: effectUnit1 anchors.top: parent.top anchors.left: parent.left anchors.right: crossfader.left anchors.bottom: parent.bottom - - Skin.SectionBackground { - anchors.fill: parent - } - + unitNumber: 1 } Skin.SectionBackground { @@ -48,18 +44,14 @@ Item { } - Item { - id: effectUnitRightPlaceholder + Skin.EffectUnit { + id: effectUnit2 anchors.top: parent.top anchors.left: crossfader.right anchors.right: parent.right anchors.bottom: parent.bottom - - Skin.SectionBackground { - anchors.fill: parent - } - + unitNumber: 2 } } diff --git a/res/skins/QMLDemo/EffectUnit.qml b/res/skins/QMLDemo/EffectUnit.qml new file mode 100644 index 000000000000..3961603b9dea --- /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: parent.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: parent.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/Theme/Theme.qml b/res/skins/QMLDemo/Theme/Theme.qml index a34043da011f..010b654c128f 100644 --- a/res/skins/QMLDemo/Theme/Theme.qml +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -16,6 +16,8 @@ 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 From 5fb7a98394985f9f1fd4b43f6605d560d9c0dce4 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 14 Jun 2021 00:48:01 +0200 Subject: [PATCH 40/56] skins/QMLDemo: Move effects to separate row --- res/skins/QMLDemo/CrossfaderRow.qml | 20 -------------------- res/skins/QMLDemo/EffectRow.qml | 26 ++++++++++++++++++++++++++ res/skins/QMLDemo/main.qml | 21 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 res/skins/QMLDemo/EffectRow.qml diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index 922e42b8047e..fffedf67e22b 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -10,16 +10,6 @@ Item { implicitHeight: crossfader.height - Skin.EffectUnit { - id: effectUnit1 - - anchors.top: parent.top - anchors.left: parent.left - anchors.right: crossfader.left - anchors.bottom: parent.bottom - unitNumber: 1 - } - Skin.SectionBackground { id: crossfader @@ -44,14 +34,4 @@ Item { } - Skin.EffectUnit { - id: effectUnit2 - - anchors.top: parent.top - anchors.left: crossfader.right - anchors.right: parent.right - anchors.bottom: parent.bottom - unitNumber: 2 - } - } 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/main.qml b/res/skins/QMLDemo/main.qml index 8447c2cf255f..5ff7b56db8b0 100644 --- a/res/skins/QMLDemo/main.qml +++ b/res/skins/QMLDemo/main.qml @@ -8,6 +8,7 @@ Rectangle { id: root property alias show4decks: show4DecksButton.checked + property alias showEffects: showEffectsButton.checked property alias showSamplers: showSamplersButton.checked property alias maximizeLibrary: maximizeLibraryButton.checked @@ -47,6 +48,14 @@ Rectangle { checkable: true } + Skin.Button { + id: showEffectsButton + + text: "Effects" + activeColor: Theme.white + checkable: true + } + Skin.Button { id: showSamplersButton @@ -108,6 +117,18 @@ Rectangle { } + EffectRow { + id: effects + + width: parent.width + visible: root.showEffects + + FadeBehavior on visible { + fadeTarget: effects + } + + } + Library { width: parent.width height: parent.height - y From 2da6388e54cc4e0b9d3e52f2b7030d1066de388b Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 14 Jun 2021 01:32:17 +0200 Subject: [PATCH 41/56] skins/QMLDemo: Add basic microphone/aux inputs to crossfader row --- res/skins/QMLDemo/AuxiliaryUnit.qml | 64 ++++++++++++++++++++++++++ res/skins/QMLDemo/CrossfaderRow.qml | 61 +++++++++++++++++++++++++ res/skins/QMLDemo/MicrophoneUnit.qml | 68 ++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 res/skins/QMLDemo/AuxiliaryUnit.qml create mode 100644 res/skins/QMLDemo/MicrophoneUnit.qml diff --git a/res/skins/QMLDemo/AuxiliaryUnit.qml b/res/skins/QMLDemo/AuxiliaryUnit.qml new file mode 100644 index 000000000000..8524919c95f6 --- /dev/null +++ b/res/skins/QMLDemo/AuxiliaryUnit.qml @@ -0,0 +1,64 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import "Theme" + +Row { + id: root + + property string group // required + + 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.ControlButton { + id: pflButton + + group: root.group + key: "pfl" + text: "PFL" + activeColor: Theme.pflActiveButtonColor + toggleable: true + } + + Skin.OrientationToggleButton { + group: root.group + key: "orientation" + color: Theme.crossfaderOrientationColor + } + + } + +} diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index fffedf67e22b..e0c7cb08c153 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -10,6 +10,38 @@ Item { implicitHeight: crossfader.height + Skin.SectionBackground { + anchors.fill: microphoneRow + } + + Row { + id: microphoneRow + + anchors.left: parent.left + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: crossfader.left + padding: 5 + spacing: 20 + + Skin.MicrophoneUnit { + group: "[Microphone]" + } + + Skin.MicrophoneUnit { + group: "[Microphone2]" + } + + Skin.MicrophoneUnit { + group: "[Microphone3]" + } + + Skin.MicrophoneUnit { + group: "[Microphone4]" + } + + } + Skin.SectionBackground { id: crossfader @@ -34,4 +66,33 @@ Item { } + Row { + id: auxiliaryRow + + anchors.left: crossfader.right + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + layoutDirection: Qt.RightToLeft + padding: 5 + spacing: 20 + + Skin.AuxiliaryUnit { + group: "[Auxiliary4]" + } + + Skin.AuxiliaryUnit { + group: "[Auxiliary3]" + } + + Skin.AuxiliaryUnit { + group: "[Auxiliary2]" + } + + Skin.AuxiliaryUnit { + group: "[Auxiliary1]" + } + + } + } diff --git a/res/skins/QMLDemo/MicrophoneUnit.qml b/res/skins/QMLDemo/MicrophoneUnit.qml new file mode 100644 index 000000000000..e562f6d22c01 --- /dev/null +++ b/res/skins/QMLDemo/MicrophoneUnit.qml @@ -0,0 +1,68 @@ +import "." as Skin +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 +import "Theme" + +Row { + id: root + + property string group // required + + 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.ControlButton { + id: pflButton + + group: root.group + key: "pfl" + text: "PFL" + activeColor: Theme.pflActiveButtonColor + toggleable: true + } + + Skin.ControlButton { + id: talkButton + + group: root.group + key: "talkover" + text: "Talk" + activeColor: Theme.pflActiveButtonColor + toggleable: true + } + + } + +} From 2b24fe3b09d7cc41d90d32cea93a967451c00820 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 14 Jun 2021 22:09:49 +0200 Subject: [PATCH 42/56] skins/QMLDemo: Improve microphone/aux units and add ducking controls --- res/skins/QMLDemo/AuxiliaryUnit.qml | 77 ++++++++++++++- res/skins/QMLDemo/CrossfaderRow.qml | 73 ++++++++++++--- res/skins/QMLDemo/MicrophoneUnit.qml | 93 ++++++++++++++++++- res/skins/QMLDemo/Slider.qml | 2 +- res/skins/QMLDemo/Theme/Theme.qml | 2 + .../images/slider_handle_micducking.svg | 2 + .../QMLDemo/images/slider_micducking.svg | 2 + 7 files changed, 232 insertions(+), 19 deletions(-) create mode 100644 res/skins/QMLDemo/images/slider_handle_micducking.svg create mode 100644 res/skins/QMLDemo/images/slider_micducking.svg diff --git a/res/skins/QMLDemo/AuxiliaryUnit.qml b/res/skins/QMLDemo/AuxiliaryUnit.qml index 8524919c95f6..61f86dd21a9a 100644 --- a/res/skins/QMLDemo/AuxiliaryUnit.qml +++ b/res/skins/QMLDemo/AuxiliaryUnit.qml @@ -7,7 +7,8 @@ import "Theme" Row { id: root - property string group // required + property int unitNumber // required + property string group: "[Auxiliary" + unitNumber + "]" spacing: 5 @@ -43,6 +44,19 @@ Row { } Column { + Text { + width: parent.width + height: root.height / 2 + text: "AUX " + root.unitNumber + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + font.bold: true + color: Theme.buttonNormalColor + } + Skin.ControlButton { id: pflButton @@ -53,12 +67,73 @@ Row { toggleable: true } + } + + Skin.EmbeddedBackground { + id: embedded + + color: Theme.embeddedBackgroundColor + 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: Text { + anchors.centerIn: parent + text: "FX1" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.pixelSize: Theme.buttonFontPixelSize + font.bold: true + color: Theme.deckTextColor + } + + } + + 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: Text { + anchors.centerIn: parent + text: "FX2" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.pixelSize: Theme.buttonFontPixelSize + font.bold: true + color: Theme.deckTextColor + } + + } + } } diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index e0c7cb08c153..50e0f942057a 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" @@ -17,27 +18,72 @@ Item { Row { id: microphoneRow - anchors.left: parent.left anchors.top: parent.top anchors.bottom: parent.bottom + anchors.left: parent.left anchors.right: crossfader.left + layoutDirection: Qt.RightToLeft padding: 5 - spacing: 20 + spacing: 10 Skin.MicrophoneUnit { - group: "[Microphone]" + unitNumber: 1 } Skin.MicrophoneUnit { - group: "[Microphone2]" + unitNumber: 2 } Skin.MicrophoneUnit { - group: "[Microphone3]" + unitNumber: 3 } Skin.MicrophoneUnit { - group: "[Microphone4]" + unitNumber: 4 + } + + Column { + 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: { + switch (duckingControl.value) { + case 1: + return "Auto"; + case 2: + return "Manual"; + default: + return "Off"; + } + } + activeColor: Theme.pflActiveButtonColor + highlight: { + let value = duckingControl.value; + return (value == 1 || value == 2); + } + onClicked: duckingControl.value = (duckingControl.value + 1) % 3 + + Mixxx.ControlProxy { + id: duckingControl + + group: "[Master]" + key: "talkoverDucking" + } + + } + } } @@ -73,24 +119,27 @@ Item { anchors.top: parent.top anchors.bottom: parent.bottom anchors.right: parent.right - layoutDirection: Qt.RightToLeft padding: 5 - spacing: 20 + spacing: 10 Skin.AuxiliaryUnit { - group: "[Auxiliary4]" + layoutDirection: Qt.RightToLeft + unitNumber: 1 } Skin.AuxiliaryUnit { - group: "[Auxiliary3]" + layoutDirection: Qt.RightToLeft + unitNumber: 2 } Skin.AuxiliaryUnit { - group: "[Auxiliary2]" + layoutDirection: Qt.RightToLeft + unitNumber: 3 } Skin.AuxiliaryUnit { - group: "[Auxiliary1]" + layoutDirection: Qt.RightToLeft + unitNumber: 4 } } diff --git a/res/skins/QMLDemo/MicrophoneUnit.qml b/res/skins/QMLDemo/MicrophoneUnit.qml index e562f6d22c01..db70f6e69fcb 100644 --- a/res/skins/QMLDemo/MicrophoneUnit.qml +++ b/res/skins/QMLDemo/MicrophoneUnit.qml @@ -7,7 +7,8 @@ import "Theme" Row { id: root - property string group // required + property int unitNumber // required + property string group: unitNumber === 1 ? "[Microphone]" : "[Microphone" + unitNumber + "]" spacing: 5 @@ -43,6 +44,19 @@ Row { } Column { + Text { + width: parent.width + height: root.height / 2 + text: "MIC " + root.unitNumber + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + font.family: Theme.fontFamily + font.pixelSize: Theme.textFontPixelSize + font.bold: true + color: Theme.buttonNormalColor + } + Skin.ControlButton { id: pflButton @@ -53,14 +67,83 @@ Row { toggleable: true } - Skin.ControlButton { + } + + Skin.EmbeddedBackground { + id: embedded + + color: Theme.embeddedBackgroundColor + 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" - text: "Talk" - activeColor: Theme.pflActiveButtonColor - toggleable: true + activeColor: Theme.deckActiveColor + + foreground: Text { + anchors.centerIn: parent + text: "TALK" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.pixelSize: Theme.buttonFontPixelSize + font.bold: true + color: Theme.deckTextColor + } + + } + + 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: Text { + anchors.centerIn: parent + text: "FX1" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.pixelSize: Theme.buttonFontPixelSize + font.bold: true + color: Theme.deckTextColor + } + + } + + 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: Text { + anchors.centerIn: parent + text: "FX2" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: Theme.fontFamily + font.pixelSize: Theme.buttonFontPixelSize + font.bold: true + color: Theme.deckTextColor + } + } } diff --git a/res/skins/QMLDemo/Slider.qml b/res/skins/QMLDemo/Slider.qml index 750cd0b1461f..7d7a83006d78 100644 --- a/res/skins/QMLDemo/Slider.qml +++ b/res/skins/QMLDemo/Slider.qml @@ -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 010b654c128f..9967bfa959a0 100644 --- a/res/skins/QMLDemo/Theme/Theme.qml +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -45,6 +45,8 @@ QtObject { 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" 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 @@ + + From 9d88f9f115268adb412971327da493601632428b Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Mon, 14 Jun 2021 22:13:07 +0200 Subject: [PATCH 43/56] skins/QMLDemo: Fix crossfader margins --- res/skins/QMLDemo/CrossfaderRow.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index 50e0f942057a..d429feff4ac7 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -100,6 +100,8 @@ Item { anchors.left: parent.left anchors.right: parent.right + anchors.leftMargin: 5 + anchors.rightMargin: 5 anchors.verticalCenter: parent.verticalCenter orientation: Qt.Horizontal group: "[Master]" From f88fb1a2353aead8ac1cabc8ee062bca53ba8758 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 10:13:37 +0200 Subject: [PATCH 44/56] skins/QMLDemo: Use explicit id in EffectUnit instead of "parent" --- res/skins/QMLDemo/EffectUnit.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/skins/QMLDemo/EffectUnit.qml b/res/skins/QMLDemo/EffectUnit.qml index 3961603b9dea..02b89d26d2ad 100644 --- a/res/skins/QMLDemo/EffectUnit.qml +++ b/res/skins/QMLDemo/EffectUnit.qml @@ -37,7 +37,7 @@ Item { anchors.bottom: parent.bottom anchors.margins: 5 width: 40 - group: parent.group + group: effect.group key: "enabled" toggleable: true text: "ON" @@ -65,7 +65,7 @@ Item { anchors.margins: 5 arcStart: 0 width: 40 - group: parent.group + group: effect.group key: "meta" color: Theme.effectColor } From ca6d7d814a4c3773535bda884f4b3f3ce1e2b9eb Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 10:16:45 +0200 Subject: [PATCH 45/56] skins/QMLDemo: Move EmbeddedBackground color into component --- res/skins/QMLDemo/AuxiliaryUnit.qml | 1 - res/skins/QMLDemo/ComboBox.qml | 2 -- res/skins/QMLDemo/EmbeddedBackground.qml | 1 + res/skins/QMLDemo/MicrophoneUnit.qml | 1 - res/skins/QMLDemo/Sampler.qml | 1 - 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/res/skins/QMLDemo/AuxiliaryUnit.qml b/res/skins/QMLDemo/AuxiliaryUnit.qml index 61f86dd21a9a..e7105c5b9de0 100644 --- a/res/skins/QMLDemo/AuxiliaryUnit.qml +++ b/res/skins/QMLDemo/AuxiliaryUnit.qml @@ -72,7 +72,6 @@ Row { Skin.EmbeddedBackground { id: embedded - color: Theme.embeddedBackgroundColor height: parent.height width: 56 diff --git a/res/skins/QMLDemo/ComboBox.qml b/res/skins/QMLDemo/ComboBox.qml index 539de34449e6..db2e97e0dc68 100644 --- a/res/skins/QMLDemo/ComboBox.qml +++ b/res/skins/QMLDemo/ComboBox.qml @@ -7,7 +7,6 @@ ComboBox { id: root background: Skin.EmbeddedBackground { - color: Theme.embeddedBackgroundColor } delegate: ItemDelegate { @@ -57,7 +56,6 @@ ComboBox { } background: Skin.EmbeddedBackground { - color: Theme.embeddedBackgroundColor } } diff --git a/res/skins/QMLDemo/EmbeddedBackground.qml b/res/skins/QMLDemo/EmbeddedBackground.qml index 657b3903bbdc..85a2e5f17a96 100644 --- a/res/skins/QMLDemo/EmbeddedBackground.qml +++ b/res/skins/QMLDemo/EmbeddedBackground.qml @@ -7,4 +7,5 @@ Rectangle { border.width: 2 border.color: Theme.deckBackgroundColor radius: 5 + color: Theme.embeddedBackgroundColor } diff --git a/res/skins/QMLDemo/MicrophoneUnit.qml b/res/skins/QMLDemo/MicrophoneUnit.qml index db70f6e69fcb..a01e0a90841d 100644 --- a/res/skins/QMLDemo/MicrophoneUnit.qml +++ b/res/skins/QMLDemo/MicrophoneUnit.qml @@ -72,7 +72,6 @@ Row { Skin.EmbeddedBackground { id: embedded - color: Theme.embeddedBackgroundColor height: parent.height width: 56 diff --git a/res/skins/QMLDemo/Sampler.qml b/res/skins/QMLDemo/Sampler.qml index 02b2a8dcc71c..33b745cf8b15 100644 --- a/res/skins/QMLDemo/Sampler.qml +++ b/res/skins/QMLDemo/Sampler.qml @@ -34,7 +34,6 @@ Rectangle { anchors.left: parent.left anchors.right: vuMeter.left anchors.bottom: parent.bottom - color: Theme.deckBackgroundColor } Skin.ControlMiniKnob { From f00100ec0d44b2c81ae8dd466bb2a680b6b2f1f4 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 10:42:26 +0200 Subject: [PATCH 46/56] skins/QMLDemo: Move Microphone Ducking panel to separate component --- res/skins/QMLDemo/CrossfaderRow.qml | 43 +------------- res/skins/QMLDemo/MicrophoneDuckingPanel.qml | 62 ++++++++++++++++++++ 2 files changed, 63 insertions(+), 42 deletions(-) create mode 100644 res/skins/QMLDemo/MicrophoneDuckingPanel.qml diff --git a/res/skins/QMLDemo/CrossfaderRow.qml b/res/skins/QMLDemo/CrossfaderRow.qml index d429feff4ac7..a3a35530b10c 100644 --- a/res/skins/QMLDemo/CrossfaderRow.qml +++ b/res/skins/QMLDemo/CrossfaderRow.qml @@ -42,48 +42,7 @@ Item { unitNumber: 4 } - Column { - 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: { - switch (duckingControl.value) { - case 1: - return "Auto"; - case 2: - return "Manual"; - default: - return "Off"; - } - } - activeColor: Theme.pflActiveButtonColor - highlight: { - let value = duckingControl.value; - return (value == 1 || value == 2); - } - onClicked: duckingControl.value = (duckingControl.value + 1) % 3 - - Mixxx.ControlProxy { - id: duckingControl - - group: "[Master]" - key: "talkoverDucking" - } - - } - + Skin.MicrophoneDuckingPanel { } } 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" + } + + } + +} From 4336dc56b4909aa8ce169966d23fa53b3b525961 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 11:15:15 +0200 Subject: [PATCH 47/56] QML: Introduce reusable PlayerDropArea component --- res/skins/QMLDemo/Deck.qml | 10 ++-------- res/skins/QMLDemo/Mixxx/PlayerDropArea.qml | 16 ++++++++++++++++ res/skins/QMLDemo/Mixxx/qmldir | 1 + res/skins/QMLDemo/Sampler.qml | 10 ++-------- 4 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 res/skins/QMLDemo/Mixxx/PlayerDropArea.qml diff --git a/res/skins/QMLDemo/Deck.qml b/res/skins/QMLDemo/Deck.qml index bc4fa84ccbf1..3765ef0792e4 100644 --- a/res/skins/QMLDemo/Deck.qml +++ b/res/skins/QMLDemo/Deck.qml @@ -379,15 +379,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/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 index 33b745cf8b15..478404909eca 100644 --- a/res/skins/QMLDemo/Sampler.qml +++ b/res/skins/QMLDemo/Sampler.qml @@ -144,15 +144,9 @@ Rectangle { anchors.right: gainKnob.left } - 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 } } From 365e47082e0f630a8dbb4ed583b2e458aa01cfee Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 11:16:11 +0200 Subject: [PATCH 48/56] skins/QMLDemo: Fix typo in MiniKnob foreground id --- res/skins/QMLDemo/MiniKnob.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/skins/QMLDemo/MiniKnob.qml b/res/skins/QMLDemo/MiniKnob.qml index 1a738428dd2d..b55bbc411bfc 100644 --- a/res/skins/QMLDemo/MiniKnob.qml +++ b/res/skins/QMLDemo/MiniKnob.qml @@ -38,8 +38,6 @@ MixxxControls.Knob { } foreground: Item { - id: inidicator - anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right From cc6150bbc058ca068b038758ba7ca810aac6f432 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 11:33:13 +0200 Subject: [PATCH 49/56] skins/QMLDemo: Remove unnecessary mousearea id from sampler --- res/skins/QMLDemo/Sampler.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/res/skins/QMLDemo/Sampler.qml b/res/skins/QMLDemo/Sampler.qml index 478404909eca..df80c2113499 100644 --- a/res/skins/QMLDemo/Sampler.qml +++ b/res/skins/QMLDemo/Sampler.qml @@ -115,13 +115,11 @@ Rectangle { } MouseArea { - id: mousearea - anchors.fill: progressContainer cursorShape: Qt.PointingHandCursor hoverEnabled: true onPressed: { - playPositionControl.value = mouse.x / mousearea.width; + playPositionControl.value = mouse.x / width; } onPositionChanged: { if (containsPress) From c2785e43b94128eb42151ed3ae8270ed995ea7c8 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 11:38:17 +0200 Subject: [PATCH 50/56] skins/QMLDemo: Introduce samplerColor --- res/skins/QMLDemo/Sampler.qml | 6 +++--- res/skins/QMLDemo/Theme/Theme.qml | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/res/skins/QMLDemo/Sampler.qml b/res/skins/QMLDemo/Sampler.qml index df80c2113499..05b85c4a57c1 100644 --- a/res/skins/QMLDemo/Sampler.qml +++ b/res/skins/QMLDemo/Sampler.qml @@ -46,7 +46,7 @@ Rectangle { width: 40 group: root.group key: "pregain" - color: Theme.gainKnobColor + color: Theme.samplerColor } Skin.ControlButton { @@ -54,7 +54,7 @@ Rectangle { anchors.top: embedded.top anchors.left: embedded.left - activeColor: Theme.gainKnobColor + activeColor: Theme.samplerColor width: 40 height: 40 text: "Play" @@ -103,7 +103,7 @@ Rectangle { width: playPositionControl.value * parent.width height: parent.height radius: height / 2 - color: Theme.gainKnobColor + color: Theme.samplerColor Mixxx.ControlProxy { id: playPositionControl diff --git a/res/skins/QMLDemo/Theme/Theme.qml b/res/skins/QMLDemo/Theme/Theme.qml index 9967bfa959a0..23301140a0b5 100644 --- a/res/skins/QMLDemo/Theme/Theme.qml +++ b/res/skins/QMLDemo/Theme/Theme.qml @@ -21,6 +21,7 @@ QtObject { 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 From 9c687d453812cc67e81e0c1d0beb9cd9337afd16 Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 11:53:23 +0200 Subject: [PATCH 51/56] skins/QMLDemo: Use shared text components on samplers/decks/mic/aux --- res/skins/QMLDemo/AuxiliaryUnit.qml | 25 ++------------- res/skins/QMLDemo/Deck.qml | 23 ++------------ res/skins/QMLDemo/DeckInfoBar.qml | 44 +++++++------------------- res/skins/QMLDemo/EmbeddedText.qml | 6 ++++ res/skins/QMLDemo/MicrophoneUnit.qml | 33 +++---------------- res/skins/QMLDemo/SectionText.qml | 12 +++++++ res/skins/QMLDemo/WaveformOverview.qml | 6 ++-- 7 files changed, 41 insertions(+), 108 deletions(-) create mode 100644 res/skins/QMLDemo/EmbeddedText.qml create mode 100644 res/skins/QMLDemo/SectionText.qml diff --git a/res/skins/QMLDemo/AuxiliaryUnit.qml b/res/skins/QMLDemo/AuxiliaryUnit.qml index e7105c5b9de0..a433cfab3f24 100644 --- a/res/skins/QMLDemo/AuxiliaryUnit.qml +++ b/res/skins/QMLDemo/AuxiliaryUnit.qml @@ -44,17 +44,10 @@ Row { } Column { - Text { + Skin.SectionText { width: parent.width height: root.height / 2 text: "AUX " + root.unitNumber - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - font.family: Theme.fontFamily - font.pixelSize: Theme.textFontPixelSize - font.bold: true - color: Theme.buttonNormalColor } Skin.ControlButton { @@ -98,15 +91,9 @@ Row { key: "group_" + root.group + "_enable" activeColor: Theme.deckActiveColor - foreground: Text { + foreground: Skin.EmbeddedText { anchors.centerIn: parent text: "FX1" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.pixelSize: Theme.buttonFontPixelSize - font.bold: true - color: Theme.deckTextColor } } @@ -120,15 +107,9 @@ Row { key: "group_" + root.group + "_enable" activeColor: Theme.deckActiveColor - foreground: Text { + foreground: Skin.EmbeddedText { anchors.centerIn: parent text: "FX2" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.pixelSize: Theme.buttonFontPixelSize - font.bold: true - color: Theme.deckTextColor } } diff --git a/res/skins/QMLDemo/Deck.qml b/res/skins/QMLDemo/Deck.qml index 3765ef0792e4..0d10bc96ee9d 100644 --- a/res/skins/QMLDemo/Deck.qml +++ b/res/skins/QMLDemo/Deck.qml @@ -105,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 } } @@ -138,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 } } @@ -162,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)) diff --git a/res/skins/QMLDemo/DeckInfoBar.qml b/res/skins/QMLDemo/DeckInfoBar.qml index 39698b790712..6d43f93cd4bd 100644 --- a/res/skins/QMLDemo/DeckInfoBar.qml +++ b/res/skins/QMLDemo/DeckInfoBar.qml @@ -10,7 +10,6 @@ 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 @@ -93,7 +92,7 @@ Rectangle { } - Text { + Skin.EmbeddedText { id: infoBarTitle text: root.deckPlayer.title @@ -101,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 { @@ -119,7 +116,7 @@ Rectangle { color: infoBar.lineColor } - Text { + Skin.EmbeddedText { id: infoBarArtist text: root.deckPlayer.artist @@ -128,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 { @@ -147,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 { @@ -174,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 @@ -198,7 +181,7 @@ Rectangle { } - Text { + Skin.EmbeddedText { id: infoBarRateRatio property real ratio: ((rateRatioControl.value - 1) * 100).toPrecision(2) @@ -208,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 { 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/MicrophoneUnit.qml b/res/skins/QMLDemo/MicrophoneUnit.qml index a01e0a90841d..aef83afb799f 100644 --- a/res/skins/QMLDemo/MicrophoneUnit.qml +++ b/res/skins/QMLDemo/MicrophoneUnit.qml @@ -44,17 +44,10 @@ Row { } Column { - Text { + SectionText { width: parent.width height: root.height / 2 text: "MIC " + root.unitNumber - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - elide: Text.ElideRight - font.family: Theme.fontFamily - font.pixelSize: Theme.textFontPixelSize - font.bold: true - color: Theme.buttonNormalColor } Skin.ControlButton { @@ -86,15 +79,9 @@ Row { key: "talkover" activeColor: Theme.deckActiveColor - foreground: Text { + foreground: Skin.EmbeddedText { anchors.centerIn: parent text: "TALK" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.pixelSize: Theme.buttonFontPixelSize - font.bold: true - color: Theme.deckTextColor } } @@ -110,15 +97,9 @@ Row { key: "group_" + root.group + "_enable" activeColor: Theme.deckActiveColor - foreground: Text { + foreground: Skin.EmbeddedText { anchors.centerIn: parent text: "FX1" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.pixelSize: Theme.buttonFontPixelSize - font.bold: true - color: Theme.deckTextColor } } @@ -132,15 +113,9 @@ Row { key: "group_" + root.group + "_enable" activeColor: Theme.deckActiveColor - foreground: Text { + foreground: Skin.EmbeddedText { anchors.centerIn: parent text: "FX2" - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - font.family: Theme.fontFamily - font.pixelSize: Theme.buttonFontPixelSize - font.bold: true - color: Theme.deckTextColor } } 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/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" } From 314c4748fd21653364908c887765611b30c92f5e Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 12:07:13 +0200 Subject: [PATCH 52/56] QML: Make Knob arc calculation more readable --- res/skins/QMLDemo/Mixxx/Controls/Knob.qml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml index 9b4f1a7bd3ef..303ef760774a 100644 --- a/res/skins/QMLDemo/Mixxx/Controls/Knob.qml +++ b/res/skins/QMLDemo/Mixxx/Controls/Knob.qml @@ -22,9 +22,14 @@ Item { 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 @@ -35,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 { @@ -51,8 +56,8 @@ Item { fillColor: "transparent" PathAngleArc { - startAngle: -90 + root.angle * 2 * (root.arcStart - (root.max - root.min) / 2) - sweepAngle: (root.value - root.arcStart) * 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 From 5d0d7d0deb26a8e0a2061c29b13a41b6d6cb6fcf Mon Sep 17 00:00:00 2001 From: Jan Holthuis Date: Tue, 15 Jun 2021 13:44:34 +0200 Subject: [PATCH 53/56] skins/QMLDemo: Play on click, stop/eject on doubleclick --- res/skins/QMLDemo/Sampler.qml | 46 +++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/res/skins/QMLDemo/Sampler.qml b/res/skins/QMLDemo/Sampler.qml index 05b85c4a57c1..ca56973c3896 100644 --- a/res/skins/QMLDemo/Sampler.qml +++ b/res/skins/QMLDemo/Sampler.qml @@ -59,16 +59,8 @@ Rectangle { height: 40 text: "Play" group: root.group - key: "play" - highlight: playControl.value - - Mixxx.ControlProxy { - id: playControl - - group: root.group - key: "play_indicator" - } - + key: "cue_gotoandplay" + highlight: playControl.playing } Text { @@ -142,6 +134,40 @@ Rectangle { 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 From fa980d97f37da09a1508ccdbaba0fe700ffe2afc Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Mon, 15 Mar 2021 15:51:51 -0400 Subject: [PATCH 54/56] Sync Lock: rename functions to make them clearer --- src/engine/controls/bpmcontrol.cpp | 2 +- src/engine/controls/bpmcontrol.h | 2 +- src/engine/sync/clock.h | 4 +- src/engine/sync/enginesync.cpp | 62 +++++++++++++++++------------- src/engine/sync/enginesync.h | 11 ++++-- src/engine/sync/internalclock.cpp | 18 ++++----- src/engine/sync/internalclock.h | 8 ++-- src/engine/sync/syncable.h | 16 ++++---- src/engine/sync/synccontrol.cpp | 24 ++++++------ src/engine/sync/synccontrol.h | 11 +++--- 10 files changed, 87 insertions(+), 71 deletions(-) diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp index fac2e68e87d5..d72f6ff7921f 100644 --- a/src/engine/controls/bpmcontrol.cpp +++ b/src/engine/controls/bpmcontrol.cpp @@ -1104,7 +1104,7 @@ void BpmControl::setTargetBeatDistance(double beatDistance) { m_dSyncTargetBeatDistance.setValue(beatDistance); } -void BpmControl::setInstantaneousBpm(double instantaneousBpm) { +void BpmControl::updateInstantaneousBpm(double instantaneousBpm) { m_dSyncInstantaneousBpm = instantaneousBpm; } diff --git a/src/engine/controls/bpmcontrol.h b/src/engine/controls/bpmcontrol.h index f5cca122262d..7e5e3446b267 100644 --- a/src/engine/controls/bpmcontrol.h +++ b/src/engine/controls/bpmcontrol.h @@ -47,7 +47,7 @@ class BpmControl : public EngineControl { } void setTargetBeatDistance(double beatDistance); - void setInstantaneousBpm(double instantaneousBpm); + void updateInstantaneousBpm(double instantaneousBpm); void resetSyncAdjustment(); double updateLocalBpm(); /// updateBeatDistance is adjusted to include the user offset so diff --git a/src/engine/sync/clock.h b/src/engine/sync/clock.h index 75d987fc2aeb..9814bf1d441f 100644 --- a/src/engine/sync/clock.h +++ b/src/engine/sync/clock.h @@ -5,8 +5,8 @@ class Clock { virtual ~Clock() = default; virtual double getBeatDistance() const = 0; - virtual void setMasterBeatDistance(double beatDistance) = 0; + virtual void updateMasterBeatDistance(double beatDistance) = 0; virtual double getBpm() const = 0; - virtual void setMasterBpm(double bpm) = 0; + virtual void updateMasterBpm(double bpm) = 0; }; diff --git a/src/engine/sync/enginesync.cpp b/src/engine/sync/enginesync.cpp index 474ff418e99d..595be45439cc 100644 --- a/src/engine/sync/enginesync.cpp +++ b/src/engine/sync/enginesync.cpp @@ -19,7 +19,7 @@ EngineSync::EngineSync(UserSettingsPointer pConfig) m_pInternalClock(new InternalClock(kInternalClockGroup, this)), m_pMasterSyncable(nullptr) { qRegisterMetaType("SyncMode"); - m_pInternalClock->setMasterBpm(124.0); + m_pInternalClock->updateMasterBpm(124.0); } EngineSync::~EngineSync() { @@ -90,14 +90,19 @@ void EngineSync::requestSyncMode(Syncable* pSyncable, SyncMode mode) { pParamsSyncable = findBpmMatchTarget(pSyncable); if (!pParamsSyncable) { // We weren't able to find anything to match to, so set ourselves as the - // target. That way we'll use our own params when we setMasterParams below. + // target. That way we'll use our own params when we updateMasterBpm below. pParamsSyncable = pSyncable; } } // Now that all of the decks have their assignments, reinit master params if needed. if (pParamsSyncable) { - setMasterParams(pParamsSyncable); - pSyncable->setInstantaneousBpm(pParamsSyncable->getBpm()); + if (kLogger.traceEnabled()) { + kLogger.trace() + << "EngineSync::requestSyncMode setting master params from " + << pParamsSyncable->getGroup(); + } + reinitMasterParams(pParamsSyncable); + pSyncable->updateInstantaneousBpm(pParamsSyncable->getBpm()); if (pParamsSyncable != pSyncable) { pSyncable->requestSync(); } @@ -194,6 +199,9 @@ void EngineSync::deactivateSync(Syncable* pSyncable) { } Syncable* EngineSync::pickMaster(Syncable* enabling_syncable) { + if (kLogger.traceEnabled()) { + kLogger.trace() << "EngineSync::pickMaster"; + } if (m_pMasterSyncable && m_pMasterSyncable->getSyncMode() == SYNC_MASTER_EXPLICIT && m_pMasterSyncable->getBaseBpm() != 0.0) { @@ -354,14 +362,14 @@ void EngineSync::notifyPlayingAudible(Syncable* pSyncable, bool playingAudible) if (newMaster != nullptr && newMaster != m_pMasterSyncable) { activateMaster(newMaster, SYNC_MASTER_SOFT); - setMasterParams(newMaster); + reinitMasterParams(newMaster); } else { Syncable* pOnlyPlayer = getUniquePlayingSyncedDeck(); if (pOnlyPlayer) { // Even if we didn't change master, if there is only one player (us), then we should - // reinit the beat distance. + // update the beat distance. pOnlyPlayer->notifyUniquePlaying(); - setMasterBeatDistance(pOnlyPlayer, pOnlyPlayer->getBeatDistance()); + updateMasterBeatDistance(pOnlyPlayer, pOnlyPlayer->getBeatDistance()); } } @@ -380,7 +388,7 @@ void EngineSync::notifyBaseBpmChanged(Syncable* pSyncable, double bpm) { } if (isSyncMaster(pSyncable)) { - setMasterBpm(pSyncable, bpm); + updateMasterBpm(pSyncable, bpm); } } @@ -389,7 +397,7 @@ void EngineSync::notifyRateChanged(Syncable* pSyncable, double bpm) { kLogger.trace() << "EngineSync::notifyRateChanged" << pSyncable->getGroup() << bpm; } - setMasterBpm(pSyncable, bpm); + updateMasterBpm(pSyncable, bpm); } void EngineSync::requestBpmUpdate(Syncable* pSyncable, double bpm) { @@ -408,10 +416,10 @@ void EngineSync::requestBpmUpdate(Syncable* pSyncable, double bpm) { if (mbaseBpm != 0.0) { // resync to current master - pSyncable->setMasterParams(beatDistance, mbaseBpm, mbpm); + pSyncable->reinitMasterParams(beatDistance, mbaseBpm, mbpm); } else { // There is no other master, adopt this bpm as master - pSyncable->setMasterParams(0.0, 0.0, bpm); + pSyncable->reinitMasterParams(0.0, 0.0, bpm); } } @@ -425,7 +433,7 @@ void EngineSync::notifyInstantaneousBpmChanged(Syncable* pSyncable, double bpm) // Do not update the master rate slider because instantaneous changes are // not user visible. - setMasterInstantaneousBpm(pSyncable, bpm); + updateMasterInstantaneousBpm(pSyncable, bpm); } void EngineSync::notifyBeatDistanceChanged(Syncable* pSyncable, double beatDistance) { @@ -437,7 +445,7 @@ void EngineSync::notifyBeatDistanceChanged(Syncable* pSyncable, double beatDista return; } - setMasterBeatDistance(pSyncable, beatDistance); + updateMasterBeatDistance(pSyncable, beatDistance); } Syncable* EngineSync::pickNonSyncSyncTarget(EngineChannel* pDontPick) const { @@ -564,52 +572,52 @@ double EngineSync::masterBaseBpm() const { return m_pInternalClock->getBaseBpm(); } -void EngineSync::setMasterBpm(Syncable* pSource, double bpm) { - //qDebug() << "EngineSync::setMasterBpm" << pSource << bpm; +void EngineSync::updateMasterBpm(Syncable* pSource, double bpm) { + //qDebug() << "EngineSync::updateMasterBpm" << pSource << bpm; if (pSource != m_pInternalClock) { - m_pInternalClock->setMasterBpm(bpm); + m_pInternalClock->updateMasterBpm(bpm); } foreach (Syncable* pSyncable, m_syncables) { if (pSyncable == pSource || !pSyncable->isSynchronized()) { continue; } - pSyncable->setMasterBpm(bpm); + pSyncable->updateMasterBpm(bpm); } } -void EngineSync::setMasterInstantaneousBpm(Syncable* pSource, double bpm) { +void EngineSync::updateMasterInstantaneousBpm(Syncable* pSource, double bpm) { if (pSource != m_pInternalClock) { - m_pInternalClock->setInstantaneousBpm(bpm); + m_pInternalClock->updateInstantaneousBpm(bpm); } foreach (Syncable* pSyncable, m_syncables) { if (pSyncable == pSource || !pSyncable->isSynchronized()) { continue; } - pSyncable->setInstantaneousBpm(bpm); + pSyncable->updateInstantaneousBpm(bpm); } } -void EngineSync::setMasterBeatDistance(Syncable* pSource, double beatDistance) { +void EngineSync::updateMasterBeatDistance(Syncable* pSource, double beatDistance) { if (kLogger.traceEnabled()) { kLogger.trace() << "EngineSync::setMasterBeatDistance" << (pSource ? pSource->getGroup() : "null") << beatDistance; } if (pSource != m_pInternalClock) { - m_pInternalClock->setMasterBeatDistance(beatDistance); + m_pInternalClock->updateMasterBeatDistance(beatDistance); } foreach (Syncable* pSyncable, m_syncables) { if (pSyncable == pSource || !pSyncable->isSynchronized()) { continue; } - pSyncable->setMasterBeatDistance(beatDistance); + pSyncable->updateMasterBeatDistance(beatDistance); } } -void EngineSync::setMasterParams(Syncable* pSource) { +void EngineSync::reinitMasterParams(Syncable* pSource) { // Important note! Because of the way sync works, the new master is usually not the same // as the Syncable setting the master parameters (here, pSource). Notify the proper Syncable // so it can prepare itself. (This is a hack to undo half/double math so that we initialize @@ -644,17 +652,17 @@ void EngineSync::setMasterParams(Syncable* pSource) { bpm = baseBpm; } if (kLogger.traceEnabled()) { - kLogger.trace() << "BaseSyncableListener::setMasterParams, source is" + kLogger.trace() << "BaseSyncableListener::reinitMasterParams, source is" << pSource->getGroup() << beatDistance << baseBpm << bpm; } if (pSource != m_pInternalClock) { - m_pInternalClock->setMasterParams(beatDistance, baseBpm, bpm); + m_pInternalClock->reinitMasterParams(beatDistance, baseBpm, bpm); } foreach (Syncable* pSyncable, m_syncables) { if (!pSyncable->isSynchronized()) { continue; } - pSyncable->setMasterParams(beatDistance, baseBpm, bpm); + pSyncable->reinitMasterParams(beatDistance, baseBpm, bpm); } } diff --git a/src/engine/sync/enginesync.h b/src/engine/sync/enginesync.h index 5ce7574b520a..0e3118010b21 100644 --- a/src/engine/sync/enginesync.h +++ b/src/engine/sync/enginesync.h @@ -103,17 +103,20 @@ class EngineSync : public SyncableListener { double masterBaseBpm() const; /// Set the BPM on every sync-enabled Syncable except pSource. - void setMasterBpm(Syncable* pSource, double bpm); + void updateMasterBpm(Syncable* pSource, double bpm); /// Set the master instantaneous BPM on every sync-enabled Syncable except /// pSource. - void setMasterInstantaneousBpm(Syncable* pSource, double bpm); + void updateMasterInstantaneousBpm(Syncable* pSource, double bpm); /// Set the master beat distance on every sync-enabled Syncable except /// pSource. - void setMasterBeatDistance(Syncable* pSource, double beatDistance); + void updateMasterBeatDistance(Syncable* pSource, double beatDistance); - void setMasterParams(Syncable* pSource); + /// Initialize the master parameters using the provided syncable as the source. + /// This should only be called for "major" updates, like a new track or change in + /// master. Should not be called on every buffer callback. + void reinitMasterParams(Syncable* pSource); /// Iff there is a single playing syncable in sync mode, return it. /// This is used to initialize master params. diff --git a/src/engine/sync/internalclock.cpp b/src/engine/sync/internalclock.cpp index 734523d7e83e..4beec9733fb8 100644 --- a/src/engine/sync/internalclock.cpp +++ b/src/engine/sync/internalclock.cpp @@ -103,7 +103,7 @@ double InternalClock::getBeatDistance() const { return m_dClockPosition / m_dBeatLength; } -void InternalClock::setMasterBeatDistance(double beatDistance) { +void InternalClock::updateMasterBeatDistance(double beatDistance) { if (kLogger.traceEnabled()) { kLogger.trace() << "InternalClock::setMasterBeatDistance" << beatDistance; } @@ -121,7 +121,7 @@ double InternalClock::getBpm() const { return m_pClockBpm->get(); } -void InternalClock::setMasterBpm(double bpm) { +void InternalClock::updateMasterBpm(double bpm) { if (kLogger.traceEnabled()) { kLogger.trace() << "InternalClock::setBpm" << bpm; } @@ -132,7 +132,7 @@ void InternalClock::setMasterBpm(double bpm) { updateBeatLength(m_iOldSampleRate, bpm); } -void InternalClock::setInstantaneousBpm(double bpm) { +void InternalClock::updateInstantaneousBpm(double bpm) { if (kLogger.traceEnabled()) { kLogger.trace() << "InternalClock::setInstantaneousBpm" << bpm; } @@ -143,16 +143,16 @@ void InternalClock::setInstantaneousBpm(double bpm) { void InternalClock::notifyMasterParamSource() { } -void InternalClock::setMasterParams(double beatDistance, double baseBpm, double bpm) { +void InternalClock::reinitMasterParams(double beatDistance, double baseBpm, double bpm) { if (kLogger.traceEnabled()) { - kLogger.trace() << "InternalClock::setMasterParams" << beatDistance << baseBpm << bpm; + kLogger.trace() << "InternalClock::reinitMasterParams" << beatDistance << baseBpm << bpm; } if (bpm <= 0.0 || baseBpm <= 0.0) { return; } m_dBaseBpm = baseBpm; - setMasterBpm(bpm); - setMasterBeatDistance(beatDistance); + updateMasterBpm(bpm); + updateMasterBeatDistance(beatDistance); } void InternalClock::slotBaseBpmChanged(double baseBpm) { @@ -168,7 +168,7 @@ void InternalClock::slotBeatDistanceChanged(double beatDistance) { if (beatDistance < 0.0 || beatDistance > 1.0) { return; } - setMasterBeatDistance(beatDistance); + updateMasterBeatDistance(beatDistance); } void InternalClock::updateBeatLength(int sampleRate, double bpm) { @@ -204,7 +204,7 @@ void InternalClock::updateBeatLength(int sampleRate, double bpm) { m_iOldSampleRate = sampleRate; // Restore the old beat distance. - setMasterBeatDistance(oldBeatDistance); + updateMasterBeatDistance(oldBeatDistance); } void InternalClock::onCallbackStart(int sampleRate, int bufferSize) { diff --git a/src/engine/sync/internalclock.h b/src/engine/sync/internalclock.h index da0ddde7509c..d27e3939fd0d 100644 --- a/src/engine/sync/internalclock.h +++ b/src/engine/sync/internalclock.h @@ -48,14 +48,14 @@ class InternalClock : public QObject, public Clock, public Syncable { } double getBeatDistance() const override; - void setMasterBeatDistance(double beatDistance) override; + void updateMasterBeatDistance(double beatDistance) override; double getBaseBpm() const override; - void setMasterBpm(double bpm) override; + void updateMasterBpm(double bpm) override; void notifyMasterParamSource() override; double getBpm() const override; - void setInstantaneousBpm(double bpm) override; - void setMasterParams(double beatDistance, double baseBpm, double bpm) override; + void updateInstantaneousBpm(double bpm) override; + void reinitMasterParams(double beatDistance, double baseBpm, double bpm) override; void onCallbackStart(int sampleRate, int bufferSize); void onCallbackEnd(int sampleRate, int bufferSize); diff --git a/src/engine/sync/syncable.h b/src/engine/sync/syncable.h index 1596b378cbb6..f96b01536902 100644 --- a/src/engine/sync/syncable.h +++ b/src/engine/sync/syncable.h @@ -106,26 +106,28 @@ class Syncable { // current Sync Master. // Must never result in a call to // SyncableListener::notifyBeatDistanceChanged or signal loops could occur. - virtual void setMasterBeatDistance(double beatDistance) = 0; + virtual void updateMasterBeatDistance(double beatDistance) = 0; + // Update the current playback speed (not including scratch values) + // of the current master. // Must never result in a call to SyncableListener::notifyBpmChanged or // signal loops could occur. - virtual void setMasterBpm(double bpm) = 0; + virtual void updateMasterBpm(double bpm) = 0; // Tells a Syncable that it's going to be used as a source for master // params. This is a gross hack so that the SyncControl can undo its // half/double adjustment so bpms are initialized correctly. virtual void notifyMasterParamSource() = 0; - // Combines the above three calls into one, since they are often set - // simultaneously. Avoids redundant recalculation that would occur by - // using the three calls separately. - virtual void setMasterParams(double beatDistance, double baseBpm, double bpm) = 0; + // Perform a reset of Master parameters. This function also triggers recalculation + // of half-double multiplier. + virtual void reinitMasterParams(double beatDistance, double baseBpm, double bpm) = 0; + // Update the playback speed of the master, including scratch values. // Must never result in a call to // SyncableListener::notifyInstantaneousBpmChanged or signal loops could // occur. - virtual void setInstantaneousBpm(double bpm) = 0; + virtual void updateInstantaneousBpm(double bpm) = 0; }; /// SyncableListener is an interface class used by EngineSync to receive diff --git a/src/engine/sync/synccontrol.cpp b/src/engine/sync/synccontrol.cpp index 728a51d9b39a..604a55db176a 100644 --- a/src/engine/sync/synccontrol.cpp +++ b/src/engine/sync/synccontrol.cpp @@ -22,8 +22,10 @@ namespace { const mixxx::Logger kLogger("SyncControl"); } // namespace -SyncControl::SyncControl(const QString& group, UserSettingsPointer pConfig, - EngineChannel* pChannel, SyncableListener* pEngineSync) +SyncControl::SyncControl(const QString& group, + UserSettingsPointer pConfig, + EngineChannel* pChannel, + SyncableListener* pEngineSync) : EngineControl(group, pConfig), m_sGroup(group), m_pChannel(pChannel), @@ -159,7 +161,7 @@ void SyncControl::requestSync() { if (isPlaying() && m_pQuantize->toBool()) { // only sync phase if the deck is playing and if quantize is enabled. // this way the it is up to the user to decide if a seek is desired or not. - // This is helpful if the beatgrid of the track doe not fit at the current + // This is helpful if the beatgrid of the track does not fit at the current // playposition m_pChannel->getEngineBuffer()->requestSyncPhase(); } @@ -177,7 +179,7 @@ double SyncControl::adjustSyncBeatDistance(double beatDistance) const { // Similar to adjusting the target beat distance, when we report our beat // distance we need to adjust it by the master bpm adjustment factor. If // we've been doubling the master bpm, we need to divide it in half. If - // we'be been halving the master bpm, we need to double it. Both operations + // we've been halving the master bpm, we need to double it. Both operations // also need to account for if the longer beat is past its halfway point. // // This is the inverse of the updateTargetBeatDistance function below. @@ -204,7 +206,7 @@ double SyncControl::getBaseBpm() const { return m_pLocalBpm->get() / m_masterBpmAdjustFactor; } -void SyncControl::setMasterBeatDistance(double beatDistance) { +void SyncControl::updateMasterBeatDistance(double beatDistance) { if (kLogger.traceEnabled()) { kLogger.trace() << getGroup() << "SyncControl::setMasterBeatDistance" << beatDistance; @@ -217,7 +219,7 @@ void SyncControl::setMasterBeatDistance(double beatDistance) { updateTargetBeatDistance(); } -void SyncControl::setMasterBpm(double bpm) { +void SyncControl::updateMasterBpm(double bpm) { if (kLogger.traceEnabled()) { kLogger.trace() << getGroup() << "SyncControl::setMasterBpm" << bpm; } @@ -242,15 +244,15 @@ void SyncControl::notifyMasterParamSource() { m_masterBpmAdjustFactor = kBpmUnity; } -void SyncControl::setMasterParams( +void SyncControl::reinitMasterParams( double beatDistance, double baseBpm, double bpm) { if (kLogger.traceEnabled()) { kLogger.trace() << "SyncControl::setMasterParams" << getGroup() << beatDistance << baseBpm << bpm; } m_masterBpmAdjustFactor = determineBpmMultiplier(fileBpm(), baseBpm); - setMasterBpm(bpm); - setMasterBeatDistance(beatDistance); + updateMasterBpm(bpm); + updateMasterBeatDistance(beatDistance); } double SyncControl::determineBpmMultiplier(double myBpm, double targetBpm) const { @@ -309,9 +311,9 @@ double SyncControl::getBpm() const { return m_pBpm->get() / m_masterBpmAdjustFactor; } -void SyncControl::setInstantaneousBpm(double bpm) { +void SyncControl::updateInstantaneousBpm(double bpm) { // Adjust the incoming bpm by the multiplier. - m_pBpmControl->setInstantaneousBpm(bpm * m_masterBpmAdjustFactor); + m_pBpmControl->updateInstantaneousBpm(bpm * m_masterBpmAdjustFactor); } void SyncControl::reportTrackPosition(double fractionalPlaypos) { diff --git a/src/engine/sync/synccontrol.h b/src/engine/sync/synccontrol.h index 69af12e6c658..1654a0208b10 100644 --- a/src/engine/sync/synccontrol.h +++ b/src/engine/sync/synccontrol.h @@ -47,17 +47,17 @@ class SyncControl : public EngineControl, public Syncable { // Must never result in a call to // SyncableListener::notifyBeatDistanceChanged or signal loops could occur. - void setMasterBeatDistance(double beatDistance) override; + void updateMasterBeatDistance(double beatDistance) override; // Must never result in a call to // SyncableListener::notifyBpmChanged or signal loops could occur. - void setMasterBpm(double bpm) override; + void updateMasterBpm(double bpm) override; void notifyMasterParamSource() override; - void setMasterParams(double beatDistance, double baseBpm, double bpm) override; + void reinitMasterParams(double beatDistance, double baseBpm, double bpm) override; // Must never result in a call to // SyncableListener::notifyInstantaneousBpmChanged or signal loops could // occur. - void setInstantaneousBpm(double bpm) override; + void updateInstantaneousBpm(double bpm) override; void setEngineControls(RateControl* pRateControl, BpmControl* pBpmControl); @@ -107,7 +107,8 @@ class SyncControl : public EngineControl, public Syncable { // When syncing, sometimes it's better to match half or double the // master bpm. FRIEND_TEST(EngineSyncTest, HalfDoubleBpmTest); - // The amount we should multiply the master BPM to find a good sync match. + FRIEND_TEST(EngineSyncTest, HalfDoubleThenPlay); + // The amount we should multiply the master BPM by to find a good sync match. // Sometimes this is 2 or 0.5. double m_masterBpmAdjustFactor; // It is handy to store the raw reported target beat distance in case the From 2d2b485c648e39223e0eaa36b85125148f696010 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Tue, 15 Jun 2021 22:21:04 -0400 Subject: [PATCH 55/56] Sync Lock: Don't recalc half/double multiplier on every callback --- src/engine/sync/enginesync.cpp | 10 ++++++---- src/test/enginesynctest.cpp | 35 +++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/engine/sync/enginesync.cpp b/src/engine/sync/enginesync.cpp index 595be45439cc..7be0f0fe283c 100644 --- a/src/engine/sync/enginesync.cpp +++ b/src/engine/sync/enginesync.cpp @@ -415,11 +415,13 @@ void EngineSync::requestBpmUpdate(Syncable* pSyncable, double bpm) { } if (mbaseBpm != 0.0) { - // resync to current master - pSyncable->reinitMasterParams(beatDistance, mbaseBpm, mbpm); + // update from current master + pSyncable->updateMasterBeatDistance(beatDistance); + pSyncable->updateMasterBpm(mbpm); } else { - // There is no other master, adopt this bpm as master - pSyncable->reinitMasterParams(0.0, 0.0, bpm); + // There is no master, adopt this bpm as master value + pSyncable->updateMasterBeatDistance(0.0); + pSyncable->updateMasterBpm(bpm); } } diff --git a/src/test/enginesynctest.cpp b/src/test/enginesynctest.cpp index 953c9405e62f..fc51115364a5 100644 --- a/src/test/enginesynctest.cpp +++ b/src/test/enginesynctest.cpp @@ -1670,18 +1670,22 @@ TEST_F(EngineSyncTest, HalfDoubleBpmTest) { mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 140, 0.0); m_pTrack2->trySetBeats(pBeats2); + // Mixxx will choose the first playing deck to be master. Let's start deck 2 first. + ControlObject::getControl(ConfigKey(m_sGroup1, "volume"))->set(1.0); + ControlObject::getControl(ConfigKey(m_sGroup2, "volume"))->set(1.0); + ProcessBuffer(); ControlObject::getControl(ConfigKey(m_sGroup1, "quantize"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0); - ControlObject::getControl(ConfigKey(m_sGroup2, "sync_mode")) - ->set(SYNC_FOLLOWER); - ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) - ->set(SYNC_FOLLOWER); - - // Mixxx will choose the first playing deck to be master. Let's start deck 2 first. + ControlObject::getControl(ConfigKey(m_sGroup2, "sync_enabled"))->set(1); + ControlObject::getControl(ConfigKey(m_sGroup1, "sync_enabled"))->set(1); + ProcessBuffer(); ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); ProcessBuffer(); + ASSERT_TRUE(isSoftMaster(m_sGroup2)); + ASSERT_TRUE(isFollower(m_sGroup1)); + EXPECT_EQ(0.5, m_pChannel1->getEngineBuffer() ->m_pSyncControl->m_masterBpmAdjustFactor); @@ -1777,9 +1781,15 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) { ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0); // We expect that m_sGroup1 has adjusted its own bpm to the second deck and becomes a single master. - // When the second deck is synced the master bpm is adopted by the internal clock + // The internal clock is initialized right away. EXPECT_TRUE(isSoftMaster(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); + EXPECT_DOUBLE_EQ(1.0, + m_pChannel1->getEngineBuffer() + ->m_pSyncControl->m_masterBpmAdjustFactor); + EXPECT_DOUBLE_EQ(2.0, + m_pChannel2->getEngineBuffer() + ->m_pSyncControl->m_masterBpmAdjustFactor); EXPECT_DOUBLE_EQ(87.5, ControlObject::getControl(ConfigKey(m_sInternalClockGroup, "bpm")) ->get()); @@ -1790,9 +1800,10 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) { EXPECT_DOUBLE_EQ(87.5 / 80, ControlObject::getControl(ConfigKey(m_sGroup1, "rate_ratio")) ->get()); - EXPECT_DOUBLE_EQ(1, + EXPECT_DOUBLE_EQ(1.0, ControlObject::getControl(ConfigKey(m_sGroup2, "rate_ratio")) ->get()); + // Local bpms are not adjusted by the multiplier EXPECT_DOUBLE_EQ(80, ControlObject::getControl(ConfigKey(m_sGroup1, "local_bpm")) ->get()); @@ -1828,13 +1839,19 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) { ProcessBuffer(); pButtonSyncEnabled2->slotSet(1.0); pButtonSyncEnabled1->slotSet(1.0); + EXPECT_DOUBLE_EQ(1.0, + m_pChannel1->getEngineBuffer() + ->m_pSyncControl->m_masterBpmAdjustFactor); + EXPECT_DOUBLE_EQ(1.0, + m_pChannel2->getEngineBuffer() + ->m_pSyncControl->m_masterBpmAdjustFactor); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); EXPECT_DOUBLE_EQ(87.5 / 80, ControlObject::getControl(ConfigKey(m_sGroup1, "rate_ratio")) ->get()); - EXPECT_DOUBLE_EQ(1, + EXPECT_DOUBLE_EQ(1.0, ControlObject::getControl(ConfigKey(m_sGroup2, "rate_ratio")) ->get()); From 9e857968c4fbeee2b114f16fff3d1064752af15b Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Fri, 28 May 2021 16:34:16 -0400 Subject: [PATCH 56/56] Rename Sync instances of "master" to "leader" Also add an alias from the sync_master CO to sync_leader --- .../Hercules DJ Control MP3 e2-scripts.js | 2 +- .../Hercules DJControl Starlight.midi.xml | 8 +- .../Hercules_DJControl_Inpulse_200.midi.xml | 8 +- .../Hercules_DJControl_Inpulse_300.midi.xml | 8 +- .../Hercules_DJControl_Jogvision.midi.xml | 8 +- .../Novation-Launchpad MK2-scripts.js | 8 +- res/skins/LateNight/decks/rate_controls.xml | 6 +- src/controllers/controlpickermenu.cpp | 9 +- src/engine/controls/bpmcontrol.cpp | 4 +- src/engine/controls/bpmcontrol.h | 4 +- src/engine/controls/ratecontrol.cpp | 6 +- src/engine/controls/ratecontrol.h | 2 +- src/engine/enginebuffer.cpp | 4 +- src/engine/enginebuffer.h | 2 +- src/engine/enginemaster.cpp | 6 +- src/engine/enginemaster.h | 4 +- src/engine/sync/clock.h | 4 +- src/engine/sync/enginesync.cpp | 232 +++--- src/engine/sync/enginesync.h | 72 +- src/engine/sync/internalclock.cpp | 58 +- src/engine/sync/internalclock.h | 18 +- src/engine/sync/syncable.h | 62 +- src/engine/sync/synccontrol.cpp | 120 +-- src/engine/sync/synccontrol.h | 24 +- src/mixer/basetrackplayer.cpp | 2 +- src/skin/legacy/tooltips.cpp | 6 +- src/test/enginesynctest.cpp | 694 +++++++++--------- src/test/synccontroltest.cpp | 2 +- 28 files changed, 695 insertions(+), 688 deletions(-) diff --git a/res/controllers/Hercules DJ Control MP3 e2-scripts.js b/res/controllers/Hercules DJ Control MP3 e2-scripts.js index a019e21604d6..cd811906bb7c 100644 --- a/res/controllers/Hercules DJ Control MP3 e2-scripts.js +++ b/res/controllers/Hercules DJ Control MP3 e2-scripts.js @@ -731,7 +731,7 @@ HerculesMP3e2.jogWheel = function(midino, control, value, status, group) { // drive master tempo led connected to sync_mode HerculesMP3e2.syncmode = function(value, group, control) { - // Following code was used for sync_master control. + // Following code was used for sync_leader control. // Deactivated for now due to https://bugs.launchpad.net/mixxx/+bug/1456801 // currently (2015-05-20) explicit master mode is not supported. // Switched to sync_enabled (binary) control diff --git a/res/controllers/Hercules DJControl Starlight.midi.xml b/res/controllers/Hercules DJControl Starlight.midi.xml index a33e8e83259d..78b8cd0a5ca2 100644 --- a/res/controllers/Hercules DJControl Starlight.midi.xml +++ b/res/controllers/Hercules DJControl Starlight.midi.xml @@ -202,7 +202,7 @@ // Sync [Channel1] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x94 0x05 @@ -266,7 +266,7 @@ // Sync [Channel2] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x95 0x05 @@ -1082,7 +1082,7 @@ [Channel1] - sync_master + sync_leader SYNC LED Deck A(SHIFT mode) 0.5 1 @@ -1130,7 +1130,7 @@ [Channel2] - sync_master + sync_leader SYNC LED Deck B(SHIFT mode) 0.5 1 diff --git a/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml index 1b87f171e74b..90b0d317c61a 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_200.midi.xml @@ -283,7 +283,7 @@ [Channel1] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x94 0x05 @@ -349,7 +349,7 @@ [Channel2] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x95 0x05 @@ -1181,7 +1181,7 @@ [Channel1] - sync_master + sync_leader SYNC LED Deck A(SHIFT mode) 0.5 1 @@ -1225,7 +1225,7 @@ [Channel2] - sync_master + sync_leader SYNC LED Deck B(SHIFT mode) 0.5 1 diff --git a/res/controllers/Hercules_DJControl_Inpulse_300.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_300.midi.xml index 840582ea61b8..ed31dcfb0fee 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_300.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_300.midi.xml @@ -364,7 +364,7 @@ [Channel1] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x94 0x05 @@ -443,7 +443,7 @@ [Channel2] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x95 0x05 @@ -1693,7 +1693,7 @@ [Channel1] - sync_master + sync_leader SYNC LED Deck A(SHIFT mode) 0.5 1 @@ -1759,7 +1759,7 @@ [Channel2] - sync_master + sync_leader SYNC LED Deck B(SHIFT mode) 0.5 1 diff --git a/res/controllers/Hercules_DJControl_Jogvision.midi.xml b/res/controllers/Hercules_DJControl_Jogvision.midi.xml index aeb87ae3216f..75e456d4a074 100644 --- a/res/controllers/Hercules_DJControl_Jogvision.midi.xml +++ b/res/controllers/Hercules_DJControl_Jogvision.midi.xml @@ -110,7 +110,7 @@ [Channel1] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x90 0x35 @@ -594,7 +594,7 @@ [Channel2] - sync_master + sync_leader SHIFT + Sync: Sync Master 0x91 0x35 @@ -1473,7 +1473,7 @@ [Channel1] - sync_master + sync_leader SYNC LED Deck A(SHIFT mode) 0.5 1 @@ -1550,7 +1550,7 @@ [Channel2] - sync_master + sync_leader SYNC LED Deck A(SHIFT mode) 0.5 1 diff --git a/res/controllers/Novation-Launchpad MK2-scripts.js b/res/controllers/Novation-Launchpad MK2-scripts.js index bcfc1eff159c..a201965e3d42 100644 --- a/res/controllers/Novation-Launchpad MK2-scripts.js +++ b/res/controllers/Novation-Launchpad MK2-scripts.js @@ -2202,9 +2202,9 @@ var NovationLaunchpadMK2 = (function () { name: 'sync_enabled', type: 'binary' }, - sync_master: { + sync_leader: { group: "[".concat(type).concat(i, "]"), - name: 'sync_master', + name: 'sync_leader', type: 'binary' }, sync_mode: { @@ -6765,9 +6765,9 @@ var NovationLaunchpadMK2 = (function () { } }, function () { if (bindings.syncMode.getValue() === 2) { - deck.sync_master.setValue(0); + deck.sync_leader.setValue(0); } else { - deck.sync_master.setValue(1); + deck.sync_leader.setValue(1); } }); } diff --git a/res/skins/LateNight/decks/rate_controls.xml b/res/skins/LateNight/decks/rate_controls.xml index 1f81ad23f126..4a67fc600b83 100644 --- a/res/skins/LateNight/decks/rate_controls.xml +++ b/res/skins/LateNight/decks/rate_controls.xml @@ -80,10 +80,10 @@ 48f,22f sync ,sync_enabled - ,sync_master + ,sync_leader - sync_master + sync_leader SyncLeader 48f,22f 3 @@ -103,7 +103,7 @@ skin://buttons/btn__sync_active.svg - ,sync_master + ,sync_leader LeftButton diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp index 1d99b08a0c12..1cc4efc161d5 100644 --- a/src/controllers/controlpickermenu.cpp +++ b/src/controllers/controlpickermenu.cpp @@ -224,8 +224,11 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) tr("One-time beat sync (phase only)"), syncMenu); syncMenu->addSeparator(); - addControl("[InternalClock]", "sync_master", tr("Internal Sync Master"), - tr("Toggle Internal Sync Master"), syncMenu); + addControl("[InternalClock]", + "sync_leader", + tr("Internal Sync Leader"), + tr("Toggle Internal Sync Leader"), + syncMenu); addControl("[InternalClock]", "bpm", tr("Internal Master BPM"), tr("Internal Master BPM"), syncMenu); addControl("[InternalClock]", "bpm_up", tr("Internal Master BPM +1"), @@ -239,7 +242,7 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent) addControl("[InternalClock]", "bpm_down_small", tr("Internal Master BPM -0.1"), tr("Decrease internal master BPM by 0.1"), syncMenu); syncMenu->addSeparator(); - addDeckAndSamplerControl("sync_master", tr("Sync Master"), tr("Toggle sync master"), syncMenu); + addDeckAndSamplerControl("sync_leader", tr("Sync Leader"), tr("Toggle sync master"), syncMenu); addDeckAndSamplerControl("sync_mode", tr("Sync Mode"), tr("Sync mode 3-state toggle (OFF, FOLLOWER, MASTER)"), syncMenu); diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp index d72f6ff7921f..6579826992a8 100644 --- a/src/engine/controls/bpmcontrol.cpp +++ b/src/engine/controls/bpmcontrol.cpp @@ -302,7 +302,7 @@ void BpmControl::slotControlBeatSync(double value) { } bool BpmControl::syncTempo() { - if (getSyncMode() == SYNC_MASTER_EXPLICIT) { + if (getSyncMode() == SYNC_LEADER_EXPLICIT) { return false; } EngineBuffer* pOtherEngineBuffer = pickSyncTarget(); @@ -1056,7 +1056,7 @@ void BpmControl::slotBeatsTranslateMatchAlignment(double v) { const mixxx::BeatsPointer pBeats = pTrack->getBeats(); if (pBeats && (pBeats->getCapabilities() & mixxx::Beats::BEATSCAP_TRANSLATE)) { // Must reset the user offset *before* calling getPhaseOffset(), - // otherwise it will always return 0 if master sync is active. + // otherwise it will always return 0 if sync lock is active. m_dUserOffset.setValue(0.0); double offset = getPhaseOffset(getSampleOfTrack().current); diff --git a/src/engine/controls/bpmcontrol.h b/src/engine/controls/bpmcontrol.h index 7e5e3446b267..540f93e4d2c0 100644 --- a/src/engine/controls/bpmcontrol.h +++ b/src/engine/controls/bpmcontrol.h @@ -27,7 +27,7 @@ class BpmControl : public EngineControl { double getBpm() const; double getLocalBpm() const { return m_pLocalBpm ? m_pLocalBpm->get() : 0.0; } - // When in master sync mode, ratecontrol calls calcSyncedRate to figure out + // When in sync lock mode, ratecontrol calls calcSyncedRate to figure out // how fast the track should play back. The returned rate is usually just // the correct pitch to match bpms. The usertweak argument represents // how much the user is nudging the pitch to get two tracks into sync, and @@ -173,5 +173,5 @@ class BpmControl : public EngineControl { mixxx::BeatsPointer m_pBeats; FRIEND_TEST(EngineSyncTest, UserTweakPreservedInSeek); - FRIEND_TEST(EngineSyncTest, FollowerUserTweakPreservedInMasterChange); + FRIEND_TEST(EngineSyncTest, FollowerUserTweakPreservedInLeaderChange); }; diff --git a/src/engine/controls/ratecontrol.cpp b/src/engine/controls/ratecontrol.cpp index 58fcfee17dd2..1ad1419ff221 100644 --- a/src/engine/controls/ratecontrol.cpp +++ b/src/engine/controls/ratecontrol.cpp @@ -57,7 +57,7 @@ RateControl::RateControl(const QString& group, this, &RateControl::slotRateRangeChanged, Qt::DirectConnection); - // Allow rate slider to go out of bounds so that master sync rate + // Allow rate slider to go out of bounds so that sync lock rate // adjustments are not capped. m_pRateSlider = new ControlPotmeter( ConfigKey(group, "rate"), -1.0, 1.0, true); @@ -461,11 +461,11 @@ double RateControl::calculateSpeed(double baserate, double speed, bool paused, rate = m_pScratchController->getRate(); *pReportScratching = true; } else { - // If master sync is on, respond to it -- but vinyl and scratch mode always override. + // If sync lock is on, respond to it -- but vinyl and scratch mode always override. if (toSynchronized(getSyncMode()) && !paused && !bVinylControlEnabled && !useScratch2Value) { if (m_pBpmControl == nullptr) { - qDebug() << "ERROR: calculateRate m_pBpmControl is null during master sync"; + qDebug() << "ERROR: calculateRate m_pBpmControl is null during sync lock"; return 1.0; } diff --git a/src/engine/controls/ratecontrol.h b/src/engine/controls/ratecontrol.h index 54accae3e036..efd2e7fce1ea 100644 --- a/src/engine/controls/ratecontrol.h +++ b/src/engine/controls/ratecontrol.h @@ -143,7 +143,7 @@ public slots: ControlObject* m_pSampleRate; - // For Master Sync + // For Sync Lock BpmControl* m_pBpmControl; ControlProxy* m_pSyncMode; diff --git a/src/engine/enginebuffer.cpp b/src/engine/enginebuffer.cpp index 80065ba2b25f..09b5aad2b0ed 100644 --- a/src/engine/enginebuffer.cpp +++ b/src/engine/enginebuffer.cpp @@ -1158,7 +1158,7 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) { } #endif - if (isMaster(m_pSyncControl->getSyncMode())) { + if (isLeader(m_pSyncControl->getSyncMode())) { // Report our speed to SyncControl immediately instead of waiting // for postProcess so we can broadcast this update to followers. m_pSyncControl->reportPlayerSpeed(m_speed_old, m_scratching_old); @@ -1300,7 +1300,7 @@ void EngineBuffer::postProcess(const int iBufferSize) { m_pSyncControl->setLocalBpm(localBpm); m_pSyncControl->updateAudible(); SyncMode mode = m_pSyncControl->getSyncMode(); - if (isMaster(mode)) { + if (isLeader(mode)) { m_pEngineSync->notifyBeatDistanceChanged(m_pSyncControl, beatDistance); } else if (isFollower(mode)) { // Report our speed to SyncControl. If we are master, we already did this. diff --git a/src/engine/enginebuffer.h b/src/engine/enginebuffer.h index bc2695a3d6fb..61090a22b932 100644 --- a/src/engine/enginebuffer.h +++ b/src/engine/enginebuffer.h @@ -256,7 +256,7 @@ class EngineBuffer : public EngineObject { FRIEND_TEST(EngineSyncTest, HalfDoubleThenPlay); FRIEND_TEST(EngineSyncTest, UserTweakBeatDistance); FRIEND_TEST(EngineSyncTest, UserTweakPreservedInSeek); - FRIEND_TEST(EngineSyncTest, FollowerUserTweakPreservedInMasterChange); + FRIEND_TEST(EngineSyncTest, FollowerUserTweakPreservedInLeaderChange); FRIEND_TEST(EngineSyncTest, BeatMapQuantizePlay); FRIEND_TEST(EngineBufferTest, ScalerNoTransport); EngineSync* m_pEngineSync; diff --git a/src/engine/enginemaster.cpp b/src/engine/enginemaster.cpp index 202fe0b13410..8b63b51360df 100644 --- a/src/engine/enginemaster.cpp +++ b/src/engine/enginemaster.cpp @@ -270,7 +270,7 @@ const CSAMPLE* EngineMaster::getSidechainBuffer() const { } void EngineMaster::processChannels(int iBufferSize) { - // Update internal master sync rate. + // Update internal sync lock rate. m_pMasterSync->onCallbackStart(m_iSampleRate, m_iBufferSize); m_activeBusChannels[EngineChannel::LEFT].clear(); @@ -281,7 +281,7 @@ void EngineMaster::processChannels(int iBufferSize) { m_activeChannels.clear(); //ScopedTimer timer("EngineMaster::processChannels"); - EngineChannel* pMasterChannel = m_pMasterSync->getMaster(); + EngineChannel* pMasterChannel = m_pMasterSync->getLeader(); // Reserve the first place for the master channel which // should be processed first m_activeChannels.append(NULL); @@ -367,7 +367,7 @@ void EngineMaster::processChannels(int iBufferSize) { } } - // Do internal master sync post-processing before the other + // Do internal sync lock post-processing before the other // channels. // Note, because we call this on the internal clock first, // it will have an up-to-date beatDistance, whereas the other diff --git a/src/engine/enginemaster.h b/src/engine/enginemaster.h index eed8ee0fa455..f85af0b11c1c 100644 --- a/src/engine/enginemaster.h +++ b/src/engine/enginemaster.h @@ -87,7 +87,7 @@ class EngineMaster : public QObject, public AudioSource { } } - // Provide access to the master sync so enginebuffers can know what their rate controller is. + // Provide access to the sync lock so enginebuffers can know what their rate controller is. EngineSync* getEngineSync() const{ return m_pMasterSync; } @@ -254,7 +254,7 @@ class EngineMaster : public QObject, public AudioSource { ControlObject* m_pBoothEnabled; private: - // Processes active channels. The master sync channel (if any) is processed + // Processes active channels. The sync lock channel (if any) is processed // first and all others are processed after. Populates m_activeChannels, // m_activeBusChannels, m_activeHeadphoneChannels, and // m_activeTalkoverChannels with each channel that is active for the diff --git a/src/engine/sync/clock.h b/src/engine/sync/clock.h index 9814bf1d441f..a0e8731fe51b 100644 --- a/src/engine/sync/clock.h +++ b/src/engine/sync/clock.h @@ -5,8 +5,8 @@ class Clock { virtual ~Clock() = default; virtual double getBeatDistance() const = 0; - virtual void updateMasterBeatDistance(double beatDistance) = 0; + virtual void updateLeaderBeatDistance(double beatDistance) = 0; virtual double getBpm() const = 0; - virtual void updateMasterBpm(double bpm) = 0; + virtual void updateLeaderBpm(double bpm) = 0; }; diff --git a/src/engine/sync/enginesync.cpp b/src/engine/sync/enginesync.cpp index 7be0f0fe283c..66b9f80032a1 100644 --- a/src/engine/sync/enginesync.cpp +++ b/src/engine/sync/enginesync.cpp @@ -17,9 +17,9 @@ const QString kInternalClockGroup = QStringLiteral("[InternalClock]"); EngineSync::EngineSync(UserSettingsPointer pConfig) : m_pConfig(pConfig), m_pInternalClock(new InternalClock(kInternalClockGroup, this)), - m_pMasterSyncable(nullptr) { + m_pLeaderSyncable(nullptr) { qRegisterMetaType("SyncMode"); - m_pInternalClock->updateMasterBpm(124.0); + m_pInternalClock->updateLeaderBpm(124.0); } EngineSync::~EngineSync() { @@ -41,14 +41,14 @@ void EngineSync::requestSyncMode(Syncable* pSyncable, SyncMode mode) { // the pSyncable's new mode (it may not be the one they requested), // and activating the appropriate modes in it as well as possibly other // decks that need to change as a result. - Syncable* oldMaster = m_pMasterSyncable; + Syncable* oldLeader = m_pLeaderSyncable; switch (mode) { - case SYNC_MASTER_EXPLICIT: - case SYNC_MASTER_SOFT: { + case SYNC_LEADER_EXPLICIT: + case SYNC_LEADER_SOFT: { if (pSyncable->getBaseBpm() > 0) { - activateMaster(pSyncable, mode); + activateLeader(pSyncable, mode); } else { - // Because we don't have a valid bpm, we can't be the master + // Because we don't have a valid bpm, we can't be the leader // (or else everyone would try to be syncing to zero bpm). // Override and make us a follower instead. activateFollower(pSyncable); @@ -57,12 +57,12 @@ void EngineSync::requestSyncMode(Syncable* pSyncable, SyncMode mode) { } case SYNC_FOLLOWER: { // A request for follower mode may be converted into an enabling of soft - // master mode. + // leader mode. activateFollower(pSyncable); - Syncable* newMaster = pickMaster(pSyncable); - if (newMaster && newMaster != m_pMasterSyncable) { - // if the master has changed, activate it (this updates m_pMasterSyncable) - activateMaster(newMaster, SYNC_MASTER_SOFT); + Syncable* newLeader = pickLeader(pSyncable); + if (newLeader && newLeader != m_pLeaderSyncable) { + // if the leader has changed, activate it (this updates m_pLeaderSyncable) + activateLeader(newLeader, SYNC_LEADER_SOFT); } break; } @@ -82,26 +82,26 @@ void EngineSync::requestSyncMode(Syncable* pSyncable, SyncMode mode) { pOnlyPlayer->notifyUniquePlaying(); } - // Second, figure out what Syncable should be used to initialize the master - // parameters, if any. Usually this is the new master. (Note, that pointer might be null!) - Syncable* pParamsSyncable = m_pMasterSyncable; - // But If we are newly soft master, we need to match to some other deck. - if (pSyncable == m_pMasterSyncable && pSyncable != oldMaster && mode != SYNC_MASTER_EXPLICIT) { + // Second, figure out what Syncable should be used to initialize the leader + // parameters, if any. Usually this is the new leader. (Note, that pointer might be null!) + Syncable* pParamsSyncable = m_pLeaderSyncable; + // But If we are newly soft leader, we need to match to some other deck. + if (pSyncable == m_pLeaderSyncable && pSyncable != oldLeader && mode != SYNC_LEADER_EXPLICIT) { pParamsSyncable = findBpmMatchTarget(pSyncable); if (!pParamsSyncable) { // We weren't able to find anything to match to, so set ourselves as the - // target. That way we'll use our own params when we updateMasterBpm below. + // target. That way we'll use our own params when we updateLeaderParams below. pParamsSyncable = pSyncable; } } - // Now that all of the decks have their assignments, reinit master params if needed. + // Now that all of the decks have their assignments, reinit leader params if needed. if (pParamsSyncable) { if (kLogger.traceEnabled()) { kLogger.trace() - << "EngineSync::requestSyncMode setting master params from " + << "EngineSync::requestSyncMode setting leader params from " << pParamsSyncable->getGroup(); } - reinitMasterParams(pParamsSyncable); + reinitLeaderParams(pParamsSyncable); pSyncable->updateInstantaneousBpm(pParamsSyncable->getBpm()); if (pParamsSyncable != pSyncable) { pSyncable->requestSync(); @@ -120,47 +120,47 @@ void EngineSync::activateFollower(Syncable* pSyncable) { << pSyncable->getGroup(); } - if (m_pMasterSyncable == pSyncable) { - m_pMasterSyncable = nullptr; + if (m_pLeaderSyncable == pSyncable) { + m_pLeaderSyncable = nullptr; } pSyncable->setSyncMode(SYNC_FOLLOWER); } -void EngineSync::activateMaster(Syncable* pSyncable, SyncMode masterType) { +void EngineSync::activateLeader(Syncable* pSyncable, SyncMode leaderType) { VERIFY_OR_DEBUG_ASSERT(pSyncable) { - qWarning() << "WARNING: Logic Error: Called activateMaster on a nullptr Syncable."; + qWarning() << "WARNING: Logic Error: Called activateLeader on a nullptr Syncable."; return; } - VERIFY_OR_DEBUG_ASSERT(masterType == SYNC_MASTER_SOFT || masterType == SYNC_MASTER_EXPLICIT) { - qWarning() << "WARNING: Logic Error: Called activateMaster with non-master mode"; + VERIFY_OR_DEBUG_ASSERT(leaderType == SYNC_LEADER_SOFT || leaderType == SYNC_LEADER_EXPLICIT) { + qWarning() << "WARNING: Logic Error: Called activateLeader with non-leader mode"; } if (kLogger.traceEnabled()) { - kLogger.trace() << "EngineSync::activateMaster: " + kLogger.trace() << "EngineSync::activateLeader: " << pSyncable->getGroup() << "type: " - << masterType; + << leaderType; } - if (m_pMasterSyncable == pSyncable) { - // Already master, update the master type. - if (m_pMasterSyncable->getSyncMode() != masterType) { - m_pMasterSyncable->setSyncMode(masterType); + if (m_pLeaderSyncable == pSyncable) { + // Already leader, update the leader type. + if (m_pLeaderSyncable->getSyncMode() != leaderType) { + m_pLeaderSyncable->setSyncMode(leaderType); } // nothing else to do return; } - // If a different channel is already master, disable it. - Syncable* pOldChannelMaster = m_pMasterSyncable; - m_pMasterSyncable = nullptr; - if (pOldChannelMaster) { - pOldChannelMaster->setSyncMode(SYNC_FOLLOWER); + // If a different channel is already leader, disable it. + Syncable* pOldChannelLeader = m_pLeaderSyncable; + m_pLeaderSyncable = nullptr; + if (pOldChannelLeader) { + pOldChannelLeader->setSyncMode(SYNC_FOLLOWER); } - m_pMasterSyncable = pSyncable; - pSyncable->setSyncMode(masterType); + m_pLeaderSyncable = pSyncable; + pSyncable->setSyncMode(leaderType); - if (m_pMasterSyncable != m_pInternalClock) { + if (m_pLeaderSyncable != m_pInternalClock) { // the internal clock gets activated and its values are overwritten with this // new deck. activateFollower(m_pInternalClock); @@ -174,9 +174,9 @@ void EngineSync::deactivateSync(Syncable* pSyncable) { if (kLogger.traceEnabled()) { kLogger.trace() << "EngineSync::deactivateSync" << pSyncable->getGroup(); } - bool wasMaster = isSyncMaster(pSyncable); - if (wasMaster) { - m_pMasterSyncable = nullptr; + bool wasLeader = isSyncLeader(pSyncable); + if (wasLeader) { + m_pLeaderSyncable = nullptr; } // Notifications happen after-the-fact. @@ -185,27 +185,27 @@ void EngineSync::deactivateSync(Syncable* pSyncable) { bool bSyncDeckExists = syncDeckExists(); if (pSyncable != m_pInternalClock && !bSyncDeckExists) { // Deactivate the internal clock if there are no more sync decks left. - m_pMasterSyncable = nullptr; + m_pLeaderSyncable = nullptr; m_pInternalClock->setSyncMode(SYNC_NONE); return; } - if (wasMaster) { - Syncable* newMaster = pickMaster(nullptr); - if (newMaster != nullptr) { - activateMaster(newMaster, SYNC_MASTER_SOFT); + if (wasLeader) { + Syncable* newLeader = pickLeader(nullptr); + if (newLeader != nullptr) { + activateLeader(newLeader, SYNC_LEADER_SOFT); } } } -Syncable* EngineSync::pickMaster(Syncable* enabling_syncable) { +Syncable* EngineSync::pickLeader(Syncable* enabling_syncable) { if (kLogger.traceEnabled()) { - kLogger.trace() << "EngineSync::pickMaster"; + kLogger.trace() << "EngineSync::pickLeader"; } - if (m_pMasterSyncable && - m_pMasterSyncable->getSyncMode() == SYNC_MASTER_EXPLICIT && - m_pMasterSyncable->getBaseBpm() != 0.0) { - return m_pMasterSyncable; + if (m_pLeaderSyncable && + m_pLeaderSyncable->getSyncMode() == SYNC_LEADER_EXPLICIT && + m_pLeaderSyncable->getBaseBpm() != 0.0) { + return m_pLeaderSyncable; } // First preference: some other sync deck that is not playing. @@ -252,10 +252,10 @@ Syncable* EngineSync::pickMaster(Syncable* enabling_syncable) { const SyncLockAlgorithm picker = static_cast( m_pConfig->getValue(ConfigKey("[BPM]", "sync_lock_algorithm"), - PREFER_IMPLICIT_MASTER)); + PREFER_IMPLICIT_LEADER)); switch (picker) { - case PREFER_IMPLICIT_MASTER: - // Always pick a deck for a new master. + case PREFER_IMPLICIT_LEADER: + // Always pick a deck for a new leader. if (playing_deck_count == 1) { return first_playing_deck; } else if (playing_deck_count > 1) { @@ -300,7 +300,7 @@ Syncable* EngineSync::findBpmMatchTarget(Syncable* requester) { if (pOtherSyncable == requester) { continue; } - // Skip non-master decks, like preview decks. + // Skip non-leader decks, like preview decks. if (!pOtherSyncable->getChannel()->isMasterEnabled()) { continue; } @@ -357,19 +357,19 @@ void EngineSync::notifyPlayingAudible(Syncable* pSyncable, bool playingAudible) return; } - // similar to enablesync -- we pick a new master and maybe reinit. - Syncable* newMaster = pickMaster(pSyncable); + // similar to enablesync -- we pick a new leader and maybe reinit. + Syncable* newLeader = pickLeader(pSyncable); - if (newMaster != nullptr && newMaster != m_pMasterSyncable) { - activateMaster(newMaster, SYNC_MASTER_SOFT); - reinitMasterParams(newMaster); + if (newLeader != nullptr && newLeader != m_pLeaderSyncable) { + activateLeader(newLeader, SYNC_LEADER_SOFT); + reinitLeaderParams(newLeader); } else { Syncable* pOnlyPlayer = getUniquePlayingSyncedDeck(); if (pOnlyPlayer) { - // Even if we didn't change master, if there is only one player (us), then we should + // Even if we didn't change leader, if there is only one player (us), then we should // update the beat distance. pOnlyPlayer->notifyUniquePlaying(); - updateMasterBeatDistance(pOnlyPlayer, pOnlyPlayer->getBeatDistance()); + updateLeaderBeatDistance(pOnlyPlayer, pOnlyPlayer->getBeatDistance()); } } @@ -387,8 +387,8 @@ void EngineSync::notifyBaseBpmChanged(Syncable* pSyncable, double bpm) { kLogger.trace() << "EngineSync::notifyBaseBpmChanged" << pSyncable->getGroup() << bpm; } - if (isSyncMaster(pSyncable)) { - updateMasterBpm(pSyncable, bpm); + if (isSyncLeader(pSyncable)) { + updateLeaderBpm(pSyncable, bpm); } } @@ -397,7 +397,7 @@ void EngineSync::notifyRateChanged(Syncable* pSyncable, double bpm) { kLogger.trace() << "EngineSync::notifyRateChanged" << pSyncable->getGroup() << bpm; } - updateMasterBpm(pSyncable, bpm); + updateLeaderBpm(pSyncable, bpm); } void EngineSync::requestBpmUpdate(Syncable* pSyncable, double bpm) { @@ -408,20 +408,20 @@ void EngineSync::requestBpmUpdate(Syncable* pSyncable, double bpm) { double mbaseBpm = 0.0; double mbpm = 0.0; double beatDistance = 0.0; - if (m_pMasterSyncable) { - mbaseBpm = m_pMasterSyncable->getBaseBpm(); - mbpm = m_pMasterSyncable->getBpm(); - beatDistance = m_pMasterSyncable->getBeatDistance(); + if (m_pLeaderSyncable) { + mbaseBpm = m_pLeaderSyncable->getBaseBpm(); + mbpm = m_pLeaderSyncable->getBpm(); + beatDistance = m_pLeaderSyncable->getBeatDistance(); } if (mbaseBpm != 0.0) { - // update from current master - pSyncable->updateMasterBeatDistance(beatDistance); - pSyncable->updateMasterBpm(mbpm); + // update from current leader + pSyncable->updateLeaderBeatDistance(beatDistance); + pSyncable->updateLeaderBpm(mbpm); } else { - // There is no master, adopt this bpm as master value - pSyncable->updateMasterBeatDistance(0.0); - pSyncable->updateMasterBpm(bpm); + // There is no leader, adopt this bpm as leader value + pSyncable->updateLeaderBeatDistance(0.0); + pSyncable->updateLeaderBpm(bpm); } } @@ -433,9 +433,9 @@ void EngineSync::notifyInstantaneousBpmChanged(Syncable* pSyncable, double bpm) return; } - // Do not update the master rate slider because instantaneous changes are + // Do not update the leader rate slider because instantaneous changes are // not user visible. - updateMasterInstantaneousBpm(pSyncable, bpm); + updateLeaderInstantaneousBpm(pSyncable, bpm); } void EngineSync::notifyBeatDistanceChanged(Syncable* pSyncable, double beatDistance) { @@ -447,15 +447,15 @@ void EngineSync::notifyBeatDistanceChanged(Syncable* pSyncable, double beatDista return; } - updateMasterBeatDistance(pSyncable, beatDistance); + updateLeaderBeatDistance(pSyncable, beatDistance); } Syncable* EngineSync::pickNonSyncSyncTarget(EngineChannel* pDontPick) const { - // First choice: the sync master, if it's a deck - if (m_pMasterSyncable && - m_pMasterSyncable->getChannel() && - m_pMasterSyncable->getChannel() != pDontPick) { - return m_pMasterSyncable; + // First choice: the sync leader, if it's a deck + if (m_pLeaderSyncable && + m_pLeaderSyncable->getChannel() && + m_pLeaderSyncable->getChannel() != pDontPick) { + return m_pLeaderSyncable; } Syncable* pFirstPlayingDeck = nullptr; @@ -467,7 +467,7 @@ Syncable* EngineSync::pickNonSyncSyncTarget(EngineChannel* pDontPick) const { continue; } - // Only consider channels that have a track loaded, are in the master + // Only consider channels that have a track loaded, are in the leader // mix, and are primary decks. if (pChannel->isActive() && pChannel->isMasterEnabled() && pChannel->isPrimaryDeck()) { EngineBuffer* pBuffer = pChannel->getEngineBuffer(); @@ -531,8 +531,8 @@ void EngineSync::onCallbackEnd(int sampleRate, int bufferSize) { m_pInternalClock->onCallbackEnd(sampleRate, bufferSize); } -EngineChannel* EngineSync::getMaster() const { - return m_pMasterSyncable ? m_pMasterSyncable->getChannel() : nullptr; +EngineChannel* EngineSync::getLeader() const { + return m_pLeaderSyncable ? m_pLeaderSyncable->getChannel() : nullptr; } Syncable* EngineSync::getSyncableForGroup(const QString& group) { @@ -553,42 +553,42 @@ bool EngineSync::syncDeckExists() const { return false; } -double EngineSync::masterBpm() const { - if (m_pMasterSyncable) { - return m_pMasterSyncable->getBpm(); +double EngineSync::leaderBpm() const { + if (m_pLeaderSyncable) { + return m_pLeaderSyncable->getBpm(); } return m_pInternalClock->getBpm(); } -double EngineSync::masterBeatDistance() const { - if (m_pMasterSyncable) { - return m_pMasterSyncable->getBeatDistance(); +double EngineSync::leaderBeatDistance() const { + if (m_pLeaderSyncable) { + return m_pLeaderSyncable->getBeatDistance(); } return m_pInternalClock->getBeatDistance(); } -double EngineSync::masterBaseBpm() const { - if (m_pMasterSyncable) { - return m_pMasterSyncable->getBaseBpm(); +double EngineSync::leaderBaseBpm() const { + if (m_pLeaderSyncable) { + return m_pLeaderSyncable->getBaseBpm(); } return m_pInternalClock->getBaseBpm(); } -void EngineSync::updateMasterBpm(Syncable* pSource, double bpm) { - //qDebug() << "EngineSync::updateMasterBpm" << pSource << bpm; +void EngineSync::updateLeaderBpm(Syncable* pSource, double bpm) { + //qDebug() << "EngineSync::updateLeaderBpm" << pSource << bpm; if (pSource != m_pInternalClock) { - m_pInternalClock->updateMasterBpm(bpm); + m_pInternalClock->updateLeaderBpm(bpm); } foreach (Syncable* pSyncable, m_syncables) { if (pSyncable == pSource || !pSyncable->isSynchronized()) { continue; } - pSyncable->updateMasterBpm(bpm); + pSyncable->updateLeaderBpm(bpm); } } -void EngineSync::updateMasterInstantaneousBpm(Syncable* pSource, double bpm) { +void EngineSync::updateLeaderInstantaneousBpm(Syncable* pSource, double bpm) { if (pSource != m_pInternalClock) { m_pInternalClock->updateInstantaneousBpm(bpm); } @@ -601,35 +601,35 @@ void EngineSync::updateMasterInstantaneousBpm(Syncable* pSource, double bpm) { } } -void EngineSync::updateMasterBeatDistance(Syncable* pSource, double beatDistance) { +void EngineSync::updateLeaderBeatDistance(Syncable* pSource, double beatDistance) { if (kLogger.traceEnabled()) { - kLogger.trace() << "EngineSync::setMasterBeatDistance" + kLogger.trace() << "EngineSync::updateLeaderBeatDistance" << (pSource ? pSource->getGroup() : "null") << beatDistance; } if (pSource != m_pInternalClock) { - m_pInternalClock->updateMasterBeatDistance(beatDistance); + m_pInternalClock->updateLeaderBeatDistance(beatDistance); } foreach (Syncable* pSyncable, m_syncables) { if (pSyncable == pSource || !pSyncable->isSynchronized()) { continue; } - pSyncable->updateMasterBeatDistance(beatDistance); + pSyncable->updateLeaderBeatDistance(beatDistance); } } -void EngineSync::reinitMasterParams(Syncable* pSource) { - // Important note! Because of the way sync works, the new master is usually not the same - // as the Syncable setting the master parameters (here, pSource). Notify the proper Syncable +void EngineSync::reinitLeaderParams(Syncable* pSource) { + // Important note! Because of the way sync works, the new leader is usually not the same + // as the Syncable setting the leader parameters (here, pSource). Notify the proper Syncable // so it can prepare itself. (This is a hack to undo half/double math so that we initialize // based on un-multiplied bpm values). - pSource->notifyMasterParamSource(); + pSource->notifyLeaderParamSource(); double beatDistance = pSource->getBeatDistance(); if (!pSource->isPlaying()) { // If the params source is not playing, but other syncables are, then we are a stopped - // explicit Master and we should not initialize the beat distance. Take it from the + // explicit Leader and we should not initialize the beat distance. Take it from the // internal clock instead, because that will be up to date with the playing deck(s). bool playingSyncables = false; for (Syncable* pSyncable : qAsConst(m_syncables)) { @@ -654,17 +654,17 @@ void EngineSync::reinitMasterParams(Syncable* pSource) { bpm = baseBpm; } if (kLogger.traceEnabled()) { - kLogger.trace() << "BaseSyncableListener::reinitMasterParams, source is" + kLogger.trace() << "BaseSyncableListener::reinitLeaderParams, source is" << pSource->getGroup() << beatDistance << baseBpm << bpm; } if (pSource != m_pInternalClock) { - m_pInternalClock->reinitMasterParams(beatDistance, baseBpm, bpm); + m_pInternalClock->reinitLeaderParams(beatDistance, baseBpm, bpm); } foreach (Syncable* pSyncable, m_syncables) { if (!pSyncable->isSynchronized()) { continue; } - pSyncable->reinitMasterParams(beatDistance, baseBpm, bpm); + pSyncable->reinitLeaderParams(beatDistance, baseBpm, bpm); } } diff --git a/src/engine/sync/enginesync.h b/src/engine/sync/enginesync.h index 0e3118010b21..9d759a743157 100644 --- a/src/engine/sync/enginesync.h +++ b/src/engine/sync/enginesync.h @@ -40,10 +40,10 @@ class EngineSync : public SyncableListener { void notifyPlayingAudible(Syncable* pSyncable, bool playingAudible) override; void notifyScratching(Syncable* pSyncable, bool scratching) override; - /// Used to pick a sync target for cases where master sync mode is not sufficient. + /// Used to pick a sync target for cases where Leader sync mode is not sufficient. /// Guaranteed to pick a Syncable that is a real deck and has an EngineBuffer, /// but can return nullptr if there are no choices. - /// First choice is master sync, if it's a real deck, + /// First choice is Leader sync, if it's a real deck, /// then it will fall back to the first playing syncable deck, /// then it will fall back to the first playing deck, /// then it will fall back to the first non-playing deck. @@ -56,32 +56,32 @@ class EngineSync : public SyncableListener { bool otherSyncedPlaying(const QString& group); void addSyncableDeck(Syncable* pSyncable); - EngineChannel* getMaster() const; + EngineChannel* getLeader() const; void onCallbackStart(int sampleRate, int bufferSize); void onCallbackEnd(int sampleRate, int bufferSize); private: - /// Iterate over decks, and based on sync and play status, pick a new master. + /// Iterate over decks, and based on sync and play status, pick a new Leader. /// if enabling_syncable is not null, we treat it as if it were enabled because we may /// be in the process of enabling it. - Syncable* pickMaster(Syncable* enabling_syncable); + Syncable* pickLeader(Syncable* enabling_syncable); - /// Find a deck to match against, used in the case where there is no sync master. + /// Find a deck to match against, used in the case where there is no sync Leader. /// Looks first for a playing deck, and falls back to the first non-playing deck. /// If the requester is playing, don't match against a non-playing deck because /// that would be strange behavior for the user. /// Returns nullptr if none can be found. Syncable* findBpmMatchTarget(Syncable* requester); - /// Activate a specific syncable as master. - void activateMaster(Syncable* pSyncable, bool explicitMaster); + /// Activate a specific syncable as Leader. + void activateLeader(Syncable* pSyncable, bool explicitLeader); /// Activate a specific channel as Follower. Sets the syncable's bpm and - /// beatDistance to match the master. + /// beatDistance to match the Leader. void activateFollower(Syncable* pSyncable); - // Activate a specific syncable as master, with the appropriate submode. - void activateMaster(Syncable* pSyncable, SyncMode masterType); + // Activate a specific syncable as Leader, with the appropriate submode. + void activateLeader(Syncable* pSyncable, SyncMode leaderType); /// Unsets all sync state on a Syncable. void deactivateSync(Syncable* pSyncable); @@ -89,50 +89,50 @@ class EngineSync : public SyncableListener { /// This utility method returns true if it finds a deck not in SYNC_NONE mode. bool syncDeckExists() const; - /// Return the current BPM of the master Syncable. If no master syncable is + /// Return the current BPM of the Leader Syncable. If no Leader syncable is /// set then returns the BPM of the internal clock. - double masterBpm() const; + double leaderBpm() const; - /// Returns the current beat distance of the master Syncable. If no master + /// Returns the current beat distance of the Leader Syncable. If no Leader /// Syncable is set, then returns the beat distance of the internal clock. - double masterBeatDistance() const; + double leaderBeatDistance() const; - /// Returns the overall average BPM of the master Syncable if it were playing + /// Returns the overall average BPM of the Leader Syncable if it were playing /// at 1.0 rate. This is used to calculate half/double multipliers and whether - /// the master has a bpm at all. - double masterBaseBpm() const; + /// the Leader has a bpm at all. + double leaderBaseBpm() const; /// Set the BPM on every sync-enabled Syncable except pSource. - void updateMasterBpm(Syncable* pSource, double bpm); + void updateLeaderBpm(Syncable* pSource, double bpm); - /// Set the master instantaneous BPM on every sync-enabled Syncable except + /// Set the Leader instantaneous BPM on every sync-enabled Syncable except /// pSource. - void updateMasterInstantaneousBpm(Syncable* pSource, double bpm); + void updateLeaderInstantaneousBpm(Syncable* pSource, double bpm); - /// Set the master beat distance on every sync-enabled Syncable except + /// Set the Leader beat distance on every sync-enabled Syncable except /// pSource. - void updateMasterBeatDistance(Syncable* pSource, double beatDistance); + void updateLeaderBeatDistance(Syncable* pSource, double beatDistance); - /// Initialize the master parameters using the provided syncable as the source. + /// Initialize the leader parameters using the provided syncable as the source. /// This should only be called for "major" updates, like a new track or change in - /// master. Should not be called on every buffer callback. - void reinitMasterParams(Syncable* pSource); + /// leader. Should not be called on every buffer callback. + void reinitLeaderParams(Syncable* pSource); /// Iff there is a single playing syncable in sync mode, return it. - /// This is used to initialize master params. + /// This is used to initialize leader params. Syncable* getUniquePlayingSyncedDeck() const; /// Only for testing. Do not use. Syncable* getSyncableForGroup(const QString& group); /// Only for testing. Do not use. - Syncable* getMasterSyncable() override { - return m_pMasterSyncable; + Syncable* getLeaderSyncable() override { + return m_pLeaderSyncable; } - bool isSyncMaster(Syncable* pSyncable) { - if (isMaster(pSyncable->getSyncMode())) { - DEBUG_ASSERT(m_pMasterSyncable == pSyncable); + bool isSyncLeader(Syncable* pSyncable) { + if (isLeader(pSyncable->getSyncMode())) { + DEBUG_ASSERT(m_pLeaderSyncable == pSyncable); return true; } return false; @@ -143,14 +143,14 @@ class EngineSync : public SyncableListener { // If this code makes it to release we will all be very sad. enum SyncLockAlgorithm { // New behavior, which should work if beatgrids are reliable. - PREFER_IMPLICIT_MASTER, + PREFER_IMPLICIT_LEADER, // Old 2.3 behavior, which works around some issues with bad beatgrid detection, mostly // for auto DJ mode. PREFER_LOCK_BPM }; - FRIEND_TEST(EngineSyncTest, EnableOneDeckInitsMaster); - FRIEND_TEST(EngineSyncTest, EnableOneDeckInitializesMaster); + FRIEND_TEST(EngineSyncTest, EnableOneDeckInitsLeader); + FRIEND_TEST(EngineSyncTest, EnableOneDeckInitializesLeader); FRIEND_TEST(EngineSyncTest, SyncToNonSyncDeck); FRIEND_TEST(EngineSyncTest, SetFileBpmUpdatesLocalBpm); FRIEND_TEST(EngineSyncTest, BpmAdjustFactor); @@ -161,7 +161,7 @@ class EngineSync : public SyncableListener { /// The InternalClock syncable. InternalClock* m_pInternalClock; /// The current Syncable that is the leader. - Syncable* m_pMasterSyncable; + Syncable* m_pLeaderSyncable; /// The list of all Syncables registered via addSyncableDeck. QList m_syncables; }; diff --git a/src/engine/sync/internalclock.cpp b/src/engine/sync/internalclock.cpp index 4beec9733fb8..7908ab290e86 100644 --- a/src/engine/sync/internalclock.cpp +++ b/src/engine/sync/internalclock.cpp @@ -24,7 +24,7 @@ InternalClock::InternalClock(const QString& group, SyncableListener* pEngineSync m_dBeatLength(m_iOldSampleRate * 60.0 / m_dOldBpm), m_dClockPosition(0) { // Pick a wide range (1 to 200) and allow out of bounds sets. This lets you - // map a soft-takeover MIDI knob to the master BPM. This also creates bpm_up + // map a soft-takeover MIDI knob to the leader BPM. This also creates bpm_up // and bpm_down controls. // bpm_up / bpm_down steps by 1 // bpm_up_small / bpm_down_small steps by 0.1 @@ -42,12 +42,14 @@ InternalClock::InternalClock(const QString& group, SyncableListener* pEngineSync this, &InternalClock::slotBeatDistanceChanged, Qt::DirectConnection); - m_pSyncMasterEnabled.reset( - new ControlPushButton(ConfigKey(m_group, "sync_master"))); - m_pSyncMasterEnabled->setButtonMode(ControlPushButton::TOGGLE); - m_pSyncMasterEnabled->setStates(3); - m_pSyncMasterEnabled->connectValueChangeRequest( - this, &InternalClock::slotSyncMasterEnabledChangeRequest, Qt::DirectConnection); + m_pSyncLeaderEnabled.reset( + new ControlPushButton(ConfigKey(m_group, "sync_leader"))); + m_pSyncLeaderEnabled->setButtonMode(ControlPushButton::TOGGLE); + m_pSyncLeaderEnabled->setStates(3); + m_pSyncLeaderEnabled->connectValueChangeRequest( + this, &InternalClock::slotSyncLeaderEnabledChangeRequest, Qt::DirectConnection); + ControlDoublePrivate::insertAlias(ConfigKey(m_group, "sync_master"), + ConfigKey(m_group, "sync_leader")); } InternalClock::~InternalClock() { @@ -57,7 +59,7 @@ void InternalClock::setSyncMode(SyncMode mode) { // Syncable has absolutely no say in the matter. This is what EngineSync // requires. Bypass confirmation by using setAndConfirm. m_mode = mode; - m_pSyncMasterEnabled->setAndConfirm(SyncModeToMasterLight(mode)); + m_pSyncLeaderEnabled->setAndConfirm(SyncModeToLeaderLight(mode)); } void InternalClock::notifyUniquePlaying() { @@ -68,27 +70,27 @@ void InternalClock::requestSync() { // TODO(owilliams): This should probably be how we reset the internal beat distance. } -void InternalClock::slotSyncMasterEnabledChangeRequest(double state) { +void InternalClock::slotSyncLeaderEnabledChangeRequest(double state) { SyncMode mode = m_mode; //Note: internal clock is always sync enabled if (state > 0.0) { - if (mode == SYNC_MASTER_EXPLICIT) { - // Already master. + if (mode == SYNC_LEADER_EXPLICIT) { + // Already leader. return; } - if (mode == SYNC_MASTER_SOFT) { - // user request: make master explicit - m_mode = SYNC_MASTER_EXPLICIT; + if (mode == SYNC_LEADER_SOFT) { + // user request: make leader explicit + m_mode = SYNC_LEADER_EXPLICIT; return; } if (mode == SYNC_NONE) { m_dBaseBpm = m_dOldBpm; } - m_pEngineSync->requestSyncMode(this, SYNC_MASTER_EXPLICIT); + m_pEngineSync->requestSyncMode(this, SYNC_LEADER_EXPLICIT); } else { - // Turning off master goes back to follower mode. + // Turning off leader goes back to follower mode. if (mode == SYNC_FOLLOWER) { - // Already not master. + // Already not leader. return; } m_pEngineSync->requestSyncMode(this, SYNC_FOLLOWER); @@ -103,9 +105,9 @@ double InternalClock::getBeatDistance() const { return m_dClockPosition / m_dBeatLength; } -void InternalClock::updateMasterBeatDistance(double beatDistance) { +void InternalClock::updateLeaderBeatDistance(double beatDistance) { if (kLogger.traceEnabled()) { - kLogger.trace() << "InternalClock::setMasterBeatDistance" << beatDistance; + kLogger.trace() << "InternalClock::updateLeaderBeatDistance" << beatDistance; } m_dClockPosition = beatDistance * m_dBeatLength; m_pClockBeatDistance->set(beatDistance); @@ -121,7 +123,7 @@ double InternalClock::getBpm() const { return m_pClockBpm->get(); } -void InternalClock::updateMasterBpm(double bpm) { +void InternalClock::updateLeaderBpm(double bpm) { if (kLogger.traceEnabled()) { kLogger.trace() << "InternalClock::setBpm" << bpm; } @@ -140,19 +142,19 @@ void InternalClock::updateInstantaneousBpm(double bpm) { Q_UNUSED(bpm); } -void InternalClock::notifyMasterParamSource() { +void InternalClock::notifyLeaderParamSource() { } -void InternalClock::reinitMasterParams(double beatDistance, double baseBpm, double bpm) { +void InternalClock::reinitLeaderParams(double beatDistance, double baseBpm, double bpm) { if (kLogger.traceEnabled()) { - kLogger.trace() << "InternalClock::reinitMasterParams" << beatDistance << baseBpm << bpm; + kLogger.trace() << "InternalClock::reinitLeaderParams" << beatDistance << baseBpm << bpm; } if (bpm <= 0.0 || baseBpm <= 0.0) { return; } m_dBaseBpm = baseBpm; - updateMasterBpm(bpm); - updateMasterBeatDistance(beatDistance); + updateLeaderBpm(bpm); + updateLeaderBeatDistance(beatDistance); } void InternalClock::slotBaseBpmChanged(double baseBpm) { @@ -168,7 +170,7 @@ void InternalClock::slotBeatDistanceChanged(double beatDistance) { if (beatDistance < 0.0 || beatDistance > 1.0) { return; } - updateMasterBeatDistance(beatDistance); + updateLeaderBeatDistance(beatDistance); } void InternalClock::updateBeatLength(int sampleRate, double bpm) { @@ -189,7 +191,7 @@ void InternalClock::updateBeatLength(int sampleRate, double bpm) { // that last term is 1 over bpm. if (qFuzzyCompare(bpm, 0)) { - qDebug() << "WARNING: Master bpm reported to be zero, internal clock guessing 124bpm"; + qDebug() << "WARNING: Leader bpm reported to be zero, internal clock guessing 124bpm"; m_dBeatLength = (sampleRate * 60.0) / 124.0; m_dOldBpm = 124.0; } else { @@ -204,7 +206,7 @@ void InternalClock::updateBeatLength(int sampleRate, double bpm) { m_iOldSampleRate = sampleRate; // Restore the old beat distance. - updateMasterBeatDistance(oldBeatDistance); + updateLeaderBeatDistance(oldBeatDistance); } void InternalClock::onCallbackStart(int sampleRate, int bufferSize) { diff --git a/src/engine/sync/internalclock.h b/src/engine/sync/internalclock.h index d27e3939fd0d..d8253899d36e 100644 --- a/src/engine/sync/internalclock.h +++ b/src/engine/sync/internalclock.h @@ -13,11 +13,11 @@ class ControlPushButton; class EngineSync; class EngineChannel; -/// Internal Clock is a Master Sync object that provides a source of constant +/// Internal Clock is a Sync Lock object that provides a source of constant /// tempo when needed. The EngineSync will decide when to make the Internal -/// Clock master. The Internal Clock should not be given any new sources of +/// Clock leader. The Internal Clock should not be given any new sources of /// bpm clock. If someone wants to write a Midi Clock source, it should be -/// a separate Syncable object that can become master. +/// a separate Syncable object that can become ledaer. class InternalClock : public QObject, public Clock, public Syncable { Q_OBJECT public: @@ -48,14 +48,14 @@ class InternalClock : public QObject, public Clock, public Syncable { } double getBeatDistance() const override; - void updateMasterBeatDistance(double beatDistance) override; + void updateLeaderBeatDistance(double beatDistance) override; double getBaseBpm() const override; - void updateMasterBpm(double bpm) override; - void notifyMasterParamSource() override; + void updateLeaderBpm(double bpm) override; + void notifyLeaderParamSource() override; double getBpm() const override; void updateInstantaneousBpm(double bpm) override; - void reinitMasterParams(double beatDistance, double baseBpm, double bpm) override; + void reinitLeaderParams(double beatDistance, double baseBpm, double bpm) override; void onCallbackStart(int sampleRate, int bufferSize); void onCallbackEnd(int sampleRate, int bufferSize); @@ -63,7 +63,7 @@ class InternalClock : public QObject, public Clock, public Syncable { private slots: void slotBaseBpmChanged(double baseBpm); void slotBeatDistanceChanged(double beatDistance); - void slotSyncMasterEnabledChangeRequest(double state); + void slotSyncLeaderEnabledChangeRequest(double state); private: void updateBeatLength(int sampleRate, double bpm); @@ -72,7 +72,7 @@ class InternalClock : public QObject, public Clock, public Syncable { SyncableListener* m_pEngineSync; QScopedPointer m_pClockBpm; QScopedPointer m_pClockBeatDistance; - QScopedPointer m_pSyncMasterEnabled; + QScopedPointer m_pSyncLeaderEnabled; SyncMode m_mode; int m_iOldSampleRate; diff --git a/src/engine/sync/syncable.h b/src/engine/sync/syncable.h index f96b01536902..53670cfc5b77 100644 --- a/src/engine/sync/syncable.h +++ b/src/engine/sync/syncable.h @@ -8,13 +8,13 @@ enum SyncMode { SYNC_INVALID = -1, SYNC_NONE = 0, SYNC_FOLLOWER = 1, - // SYNC_MASTER_SOFT is a master that Mixxx has chosen automatically. - // depending on how decks stop and start, it may reassign soft master at will. - SYNC_MASTER_SOFT = 2, - // SYNC_MASTER_EXPLICIT represents an explicit request that the synacable be - // master. Mixxx will only remove a SYNC_MASTER_SOFT if the track is stopped or + // SYNC_LEADER_SOFT is a leader that Mixxx has chosen automatically. + // depending on how decks stop and start, it may reassign soft leader at will. + SYNC_LEADER_SOFT = 2, + // SYNC_LEADER_EXPLICIT represents an explicit request that the synacable be + // leader. Mixxx will only remove a SYNC_LEADER_SOFT if the track is stopped or // ejected. - SYNC_MASTER_EXPLICIT = 3, + SYNC_LEADER_EXPLICIT = 3, SYNC_NUM_MODES }; @@ -35,36 +35,36 @@ inline bool isFollower(SyncMode mode) { return (mode == SYNC_FOLLOWER); } -inline bool isMaster(SyncMode mode) { - return (mode == SYNC_MASTER_SOFT || mode == SYNC_MASTER_EXPLICIT); +inline bool isLeader(SyncMode mode) { + return (mode == SYNC_LEADER_SOFT || mode == SYNC_LEADER_EXPLICIT); } -enum SyncMasterLight { - MASTER_INVALID = -1, - MASTER_OFF = 0, - MASTER_SOFT = 1, - MASTER_EXPLICIT = 2, +enum SyncLeaderLight { + LEADER_INVALID = -1, + LEADER_OFF = 0, + LEADER_SOFT = 1, + LEADER_EXPLICIT = 2, }; -inline SyncMasterLight SyncModeToMasterLight(SyncMode mode) { +inline SyncLeaderLight SyncModeToLeaderLight(SyncMode mode) { switch (mode) { case SYNC_INVALID: case SYNC_NONE: case SYNC_FOLLOWER: - return MASTER_OFF; - case SYNC_MASTER_SOFT: - return MASTER_SOFT; - case SYNC_MASTER_EXPLICIT: - return MASTER_EXPLICIT; + return LEADER_OFF; + case SYNC_LEADER_SOFT: + return LEADER_SOFT; + case SYNC_LEADER_EXPLICIT: + return LEADER_EXPLICIT; break; case SYNC_NUM_MODES: break; } - return MASTER_INVALID; + return LEADER_INVALID; } /// Syncable is an abstract base class for any object that wants to participate -/// in Master Sync. +/// in Sync Lock. class Syncable { public: virtual ~Syncable() = default; @@ -103,25 +103,25 @@ class Syncable { virtual double getBaseBpm() const = 0; // The following functions are used to tell syncables about the state of the - // current Sync Master. + // current Sync Leader. // Must never result in a call to // SyncableListener::notifyBeatDistanceChanged or signal loops could occur. - virtual void updateMasterBeatDistance(double beatDistance) = 0; + virtual void updateLeaderBeatDistance(double beatDistance) = 0; // Update the current playback speed (not including scratch values) - // of the current master. + // of the current leader. // Must never result in a call to SyncableListener::notifyBpmChanged or // signal loops could occur. - virtual void updateMasterBpm(double bpm) = 0; + virtual void updateLeaderBpm(double bpm) = 0; - // Tells a Syncable that it's going to be used as a source for master + // Tells a Syncable that it's going to be used as a source for leader // params. This is a gross hack so that the SyncControl can undo its // half/double adjustment so bpms are initialized correctly. - virtual void notifyMasterParamSource() = 0; + virtual void notifyLeaderParamSource() = 0; - // Perform a reset of Master parameters. This function also triggers recalculation + // Perform a reset of Leader parameters. This function also triggers recalculation // of half-double multiplier. - virtual void reinitMasterParams(double beatDistance, double baseBpm, double bpm) = 0; + virtual void reinitLeaderParams(double beatDistance, double baseBpm, double bpm) = 0; // Update the playback speed of the master, including scratch values. // Must never result in a call to @@ -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 setMasterBpm() + // 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; @@ -162,5 +162,5 @@ class SyncableListener { virtual void notifyPlayingAudible(Syncable* pSyncable, bool playingAudible) = 0; - virtual Syncable* getMasterSyncable() = 0; + virtual Syncable* getLeaderSyncable() = 0; }; diff --git a/src/engine/sync/synccontrol.cpp b/src/engine/sync/synccontrol.cpp index 604a55db176a..8268ead97a5d 100644 --- a/src/engine/sync/synccontrol.cpp +++ b/src/engine/sync/synccontrol.cpp @@ -33,14 +33,14 @@ SyncControl::SyncControl(const QString& group, m_pBpmControl(nullptr), m_pRateControl(nullptr), m_bOldScratching(false), - m_masterBpmAdjustFactor(kBpmUnity), + m_leaderBpmAdjustFactor(kBpmUnity), m_unmultipliedTargetBeatDistance(0.0), m_pBpm(nullptr), m_pLocalBpm(nullptr), m_pRateRatio(nullptr), m_pVCEnabled(nullptr), m_pSyncPhaseButton(nullptr) { - // Play button. We only listen to this to disable master if the deck is + // Play button. We only listen to this to disable leader if the deck is // stopped. m_pPlayButton = new ControlProxy(group, "play", this); m_pPlayButton->connectValueChanged(this, &SyncControl::slotControlPlay, @@ -52,12 +52,14 @@ SyncControl::SyncControl(const QString& group, m_pSyncMode->connectValueChangeRequest( this, &SyncControl::slotSyncModeChangeRequest, Qt::DirectConnection); - m_pSyncMasterEnabled.reset( - new ControlPushButton(ConfigKey(group, "sync_master"))); - m_pSyncMasterEnabled->setButtonMode(ControlPushButton::TOGGLE); - m_pSyncMasterEnabled->setStates(3); - m_pSyncMasterEnabled->connectValueChangeRequest( - this, &SyncControl::slotSyncMasterEnabledChangeRequest, Qt::DirectConnection); + m_pSyncLeaderEnabled.reset( + new ControlPushButton(ConfigKey(group, "sync_leader"))); + m_pSyncLeaderEnabled->setButtonMode(ControlPushButton::TOGGLE); + m_pSyncLeaderEnabled->setStates(3); + m_pSyncLeaderEnabled->connectValueChangeRequest( + this, &SyncControl::slotSyncLeaderEnabledChangeRequest, Qt::DirectConnection); + ControlDoublePrivate::insertAlias(ConfigKey(group, "sync_master"), + ConfigKey(group, "sync_leader")); m_pSyncEnabled.reset( new ControlPushButton(ConfigKey(group, "sync_enabled"))); @@ -127,7 +129,7 @@ void SyncControl::setSyncMode(SyncMode mode) { // requires. Bypass confirmation by using setAndConfirm. m_pSyncMode->setAndConfirm(mode); m_pSyncEnabled->setAndConfirm(mode != SYNC_NONE); - m_pSyncMasterEnabled->setAndConfirm(SyncModeToMasterLight(mode)); + m_pSyncLeaderEnabled->setAndConfirm(SyncModeToLeaderLight(mode)); if (mode == SYNC_FOLLOWER) { if (m_pVCEnabled && m_pVCEnabled->toBool()) { // If follower mode is enabled, disable vinyl control. @@ -143,7 +145,7 @@ void SyncControl::setSyncMode(SyncMode mode) { m_pPassthroughEnabled->set(0.0); } if (mode == SYNC_NONE) { - m_masterBpmAdjustFactor = kBpmUnity; + m_leaderBpmAdjustFactor = kBpmUnity; } } @@ -177,18 +179,18 @@ bool SyncControl::isAudible() const { double SyncControl::adjustSyncBeatDistance(double beatDistance) const { // Similar to adjusting the target beat distance, when we report our beat - // distance we need to adjust it by the master bpm adjustment factor. If - // we've been doubling the master bpm, we need to divide it in half. If - // we've been halving the master bpm, we need to double it. Both operations + // distance we need to adjust it by the leader bpm adjustment factor. If + // we've been doubling the leader bpm, we need to divide it in half. If + // we've been halving the leader bpm, we need to double it. Both operations // also need to account for if the longer beat is past its halfway point. // // This is the inverse of the updateTargetBeatDistance function below. - if (m_masterBpmAdjustFactor == kBpmDouble) { + if (m_leaderBpmAdjustFactor == kBpmDouble) { beatDistance /= kBpmDouble; if (m_unmultipliedTargetBeatDistance >= 0.5) { beatDistance += 0.5; } - } else if (m_masterBpmAdjustFactor == kBpmHalve) { + } else if (m_leaderBpmAdjustFactor == kBpmHalve) { if (beatDistance >= 0.5) { beatDistance -= 0.5; } @@ -203,12 +205,12 @@ double SyncControl::getBeatDistance() const { } double SyncControl::getBaseBpm() const { - return m_pLocalBpm->get() / m_masterBpmAdjustFactor; + return m_pLocalBpm->get() / m_leaderBpmAdjustFactor; } -void SyncControl::updateMasterBeatDistance(double beatDistance) { +void SyncControl::updateLeaderBeatDistance(double beatDistance) { if (kLogger.traceEnabled()) { - kLogger.trace() << getGroup() << "SyncControl::setMasterBeatDistance" + kLogger.trace() << getGroup() << "SyncControl::updateLeaderBeatDistance" << beatDistance; } // Set the BpmControl target beat distance to beatDistance, adjusted by @@ -219,9 +221,9 @@ void SyncControl::updateMasterBeatDistance(double beatDistance) { updateTargetBeatDistance(); } -void SyncControl::updateMasterBpm(double bpm) { +void SyncControl::updateLeaderBpm(double bpm) { if (kLogger.traceEnabled()) { - kLogger.trace() << getGroup() << "SyncControl::setMasterBpm" << bpm; + kLogger.trace() << getGroup() << "SyncControl::updateLeaderBpm" << bpm; } VERIFY_OR_DEBUG_ASSERT(isSynchronized()) { @@ -236,23 +238,23 @@ void SyncControl::updateMasterBpm(double bpm) { double localBpm = m_pLocalBpm->get(); if (localBpm > 0.0) { - m_pRateRatio->set(bpm * m_masterBpmAdjustFactor / localBpm); + m_pRateRatio->set(bpm * m_leaderBpmAdjustFactor / localBpm); } } -void SyncControl::notifyMasterParamSource() { - m_masterBpmAdjustFactor = kBpmUnity; +void SyncControl::notifyLeaderParamSource() { + m_leaderBpmAdjustFactor = kBpmUnity; } -void SyncControl::reinitMasterParams( +void SyncControl::reinitLeaderParams( double beatDistance, double baseBpm, double bpm) { if (kLogger.traceEnabled()) { - kLogger.trace() << "SyncControl::setMasterParams" << getGroup() + kLogger.trace() << "SyncControl::reinitLeaderParams" << getGroup() << beatDistance << baseBpm << bpm; } - m_masterBpmAdjustFactor = determineBpmMultiplier(fileBpm(), baseBpm); - updateMasterBpm(bpm); - updateMasterBeatDistance(beatDistance); + m_leaderBpmAdjustFactor = determineBpmMultiplier(fileBpm(), baseBpm); + updateLeaderBpm(bpm); + updateLeaderBeatDistance(beatDistance); } double SyncControl::determineBpmMultiplier(double myBpm, double targetBpm) const { @@ -277,7 +279,7 @@ void SyncControl::updateTargetBeatDistance() { kLogger.trace() << getGroup() << "SyncControl::updateTargetBeatDistance, unmult distance" - << targetDistance << m_masterBpmAdjustFactor; + << targetDistance << m_leaderBpmAdjustFactor; } // Determining the target distance is not as simple as x2 or /2. Since one @@ -285,12 +287,12 @@ void SyncControl::updateTargetBeatDistance() { // position of the longer beat is past its halfway point. e.g. 0.0 for the // long beat is 0.0 of the short beat, but 0.5 for the long beat is also // 0.0 for the short beat. - if (m_masterBpmAdjustFactor == kBpmDouble) { + if (m_leaderBpmAdjustFactor == kBpmDouble) { if (targetDistance >= 0.5) { targetDistance -= 0.5; } targetDistance *= kBpmDouble; - } else if (m_masterBpmAdjustFactor == kBpmHalve) { + } else if (m_leaderBpmAdjustFactor == kBpmHalve) { targetDistance *= kBpmHalve; // Our beat distance CO is still a buffer behind, so take the current value. if (m_pBpmControl->getBeatDistance(getSampleOfTrack().current) >= 0.5) { @@ -306,20 +308,20 @@ void SyncControl::updateTargetBeatDistance() { double SyncControl::getBpm() const { if (kLogger.traceEnabled()) { kLogger.trace() << getGroup() << "SyncControl::getBpm()" - << m_pBpm->get() << "/" << m_masterBpmAdjustFactor; + << m_pBpm->get() << "/" << m_leaderBpmAdjustFactor; } - return m_pBpm->get() / m_masterBpmAdjustFactor; + return m_pBpm->get() / m_leaderBpmAdjustFactor; } void SyncControl::updateInstantaneousBpm(double bpm) { // Adjust the incoming bpm by the multiplier. - m_pBpmControl->updateInstantaneousBpm(bpm * m_masterBpmAdjustFactor); + m_pBpmControl->updateInstantaneousBpm(bpm * m_leaderBpmAdjustFactor); } void SyncControl::reportTrackPosition(double fractionalPlaypos) { - // If we're close to the end, and master, disable master so we don't stop + // If we're close to the end, and leader, disable leader so we don't stop // the party. - if (isMaster(getSyncMode()) && fractionalPlaypos >= 1.0) { + if (isLeader(getSyncMode()) && fractionalPlaypos >= 1.0) { m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_FOLLOWER); } } @@ -346,23 +348,23 @@ void SyncControl::trackBeatsUpdated(mixxx::BeatsPointer pBeats) { } m_pBeats = pBeats; - m_masterBpmAdjustFactor = kBpmUnity; + m_leaderBpmAdjustFactor = kBpmUnity; SyncMode syncMode = getSyncMode(); - if (isMaster(syncMode)) { + if (isLeader(syncMode)) { if (!m_pBeats) { // If the track was ejected or suddenly has no beats, we can no longer - // be master. + // be leader. m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_FOLLOWER); } else { - // We are remaining master, so notify the engine with our update. + // We are remaining leader, so notify the engine with our update. m_pBpmControl->updateLocalBpm(); m_pEngineSync->notifyBaseBpmChanged(this, getBaseBpm()); } } else if (isFollower(syncMode)) { // If we were a follower, requesting sync mode refreshes - // the soft master -- if we went from having no bpm to having - // a bpm, we might need to become master. + // the soft leader -- if we went from having no bpm to having + // a bpm, we might need to become leader. m_pChannel->getEngineBuffer()->requestSyncMode(syncMode); m_pBpmControl->updateLocalBpm(); } @@ -401,9 +403,9 @@ void SyncControl::slotSyncModeChangeRequest(double state) { } } -void SyncControl::slotSyncMasterEnabledChangeRequest(double state) { +void SyncControl::slotSyncLeaderEnabledChangeRequest(double state) { if (kLogger.traceEnabled()) { - kLogger.trace() << "SyncControl::slotSyncMasterEnabledChangeRequest" << getGroup(); + kLogger.trace() << "SyncControl::slotSyncLeaderEnabledChangeRequest" << getGroup(); } SyncMode mode = getSyncMode(); if (state > 0.0) { @@ -411,14 +413,14 @@ void SyncControl::slotSyncMasterEnabledChangeRequest(double state) { qDebug() << "Disallowing enabling of sync mode when passthrough active"; return; } - m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_MASTER_EXPLICIT); + m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_LEADER_EXPLICIT); } else { - // Turning off master goes back to follower mode. + // Turning off leader goes back to follower mode. switch (mode) { - case SYNC_MASTER_EXPLICIT: - m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_MASTER_SOFT); + case SYNC_LEADER_EXPLICIT: + m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_LEADER_SOFT); break; - case SYNC_MASTER_SOFT: + case SYNC_LEADER_SOFT: m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_FOLLOWER); break; default: @@ -456,16 +458,16 @@ void SyncControl::setLocalBpm(double local_bpm) { double bpm = local_bpm * m_pRateRatio->get(); if (isFollower(syncMode)) { - // In this case we need an update from the current master to adjust - // the rate that we continue with the master BPM. If there is no - // master bpm, our bpm value is adopted and the m_masterBpmAdjustFactor + // In this case we need an update from the current leader to adjust + // the rate that we continue with the leader BPM. If there is no + // leader bpm, our bpm value is adopted and the m_leaderBpmAdjustFactor // is reset to 1; m_pEngineSync->requestBpmUpdate(this, bpm); } else { - DEBUG_ASSERT(isMaster(syncMode)); - // We might have adopted an adjust factor when becoming master. + DEBUG_ASSERT(isLeader(syncMode)); + // We might have adopted an adjust factor when becoming leader. // Keep it when reporting our bpm. - m_pEngineSync->notifyBaseBpmChanged(this, bpm / m_masterBpmAdjustFactor); + m_pEngineSync->notifyBaseBpmChanged(this, bpm / m_leaderBpmAdjustFactor); } } @@ -487,9 +489,9 @@ void SyncControl::slotRateChanged() { kLogger.trace() << getGroup() << "SyncControl::slotRateChanged" << m_pRateRatio->get() << bpm; } if (bpm > 0 && isSynchronized()) { - // When reporting our bpm, remove the multiplier so the masters all + // When reporting our bpm, remove the multiplier so the leaders all // think the followers have the same bpm. - m_pEngineSync->notifyRateChanged(this, bpm / m_masterBpmAdjustFactor); + m_pEngineSync->notifyRateChanged(this, bpm / m_leaderBpmAdjustFactor); } } @@ -500,9 +502,9 @@ void SyncControl::reportPlayerSpeed(double speed, bool scratching) { // No need to disable sync mode while scratching, the engine won't // get confused. } - // When reporting our speed, remove the multiplier so the masters all + // When reporting our speed, remove the multiplier so the leaders all // think the followers have the same bpm. - double instantaneous_bpm = m_pLocalBpm->get() * speed / m_masterBpmAdjustFactor; + double instantaneous_bpm = m_pLocalBpm->get() * speed / m_leaderBpmAdjustFactor; m_pEngineSync->notifyInstantaneousBpmChanged(this, instantaneous_bpm); } diff --git a/src/engine/sync/synccontrol.h b/src/engine/sync/synccontrol.h index 1654a0208b10..d0856f6c166c 100644 --- a/src/engine/sync/synccontrol.h +++ b/src/engine/sync/synccontrol.h @@ -13,7 +13,7 @@ class ControlObject; class ControlProxy; class ControlPushButton; -/// SyncControl is the Master Sync object for playback decks. +/// SyncControl is the Sync Lock object for playback decks. class SyncControl : public EngineControl, public Syncable { Q_OBJECT public: @@ -47,12 +47,12 @@ class SyncControl : public EngineControl, public Syncable { // Must never result in a call to // SyncableListener::notifyBeatDistanceChanged or signal loops could occur. - void updateMasterBeatDistance(double beatDistance) override; + void updateLeaderBeatDistance(double beatDistance) override; // Must never result in a call to // SyncableListener::notifyBpmChanged or signal loops could occur. - void updateMasterBpm(double bpm) override; - void notifyMasterParamSource() override; - void reinitMasterParams(double beatDistance, double baseBpm, double bpm) override; + void updateLeaderBpm(double bpm) override; + void notifyLeaderParamSource() override; + void reinitLeaderParams(double beatDistance, double baseBpm, double bpm) override; // Must never result in a call to // SyncableListener::notifyInstantaneousBpmChanged or signal loops could @@ -83,13 +83,13 @@ class SyncControl : public EngineControl, public Syncable { // Change request handlers for sync properties. void slotSyncModeChangeRequest(double state); void slotSyncEnabledChangeRequest(double enabled); - void slotSyncMasterEnabledChangeRequest(double state); + void slotSyncLeaderEnabledChangeRequest(double state); private: FRIEND_TEST(SyncControlTest, TestDetermineBpmMultiplier); // Sometimes it's best to match bpms based on half or double the target // bpm. e.g. 70 matches better with 140/2. This function returns the - // best factor for multiplying the master bpm to get a bpm this syncable + // best factor for multiplying the leader bpm to get a bpm this syncable // should match against. double determineBpmMultiplier(double myBpm, double targetBpm) const; double fileBpm() const; @@ -97,7 +97,7 @@ class SyncControl : public EngineControl, public Syncable { QString m_sGroup; // The only reason we have this pointer is an optimzation so that the // EngineSync can ask us what our EngineChannel is. EngineMaster in turn - // asks EngineSync what EngineChannel is the "master" channel. + // asks EngineSync what EngineChannel is the "leader" channel. EngineChannel* m_pChannel; SyncableListener* m_pEngineSync; BpmControl* m_pBpmControl; @@ -105,12 +105,12 @@ class SyncControl : public EngineControl, public Syncable { bool m_bOldScratching; // When syncing, sometimes it's better to match half or double the - // master bpm. + // leader bpm. FRIEND_TEST(EngineSyncTest, HalfDoubleBpmTest); FRIEND_TEST(EngineSyncTest, HalfDoubleThenPlay); - // The amount we should multiply the master BPM by to find a good sync match. + // The amount we should multiply the leader BPM by to find a good sync match. // Sometimes this is 2 or 0.5. - double m_masterBpmAdjustFactor; + double m_leaderBpmAdjustFactor; // It is handy to store the raw reported target beat distance in case the // multiplier changes and we need to recalculate the target distance. double m_unmultipliedTargetBeatDistance; @@ -118,7 +118,7 @@ class SyncControl : public EngineControl, public Syncable { QAtomicInt m_audible; QScopedPointer m_pSyncMode; - QScopedPointer m_pSyncMasterEnabled; + QScopedPointer m_pSyncLeaderEnabled; QScopedPointer m_pSyncEnabled; QScopedPointer m_pBeatDistance; diff --git a/src/mixer/basetrackplayer.cpp b/src/mixer/basetrackplayer.cpp index 7b44ced9da0d..51dfb77f7c0c 100644 --- a/src/mixer/basetrackplayer.cpp +++ b/src/mixer/basetrackplayer.cpp @@ -481,7 +481,7 @@ void BaseTrackPlayerImpl::slotTrackLoaded(TrackPointer pNewTrack, int reset = m_pConfig->getValue( ConfigKey("[Controls]", "SpeedAutoReset"), RESET_PITCH); if (reset == RESET_SPEED || reset == RESET_PITCH_AND_SPEED) { - // Avoid resetting speed if master sync is enabled and other decks with sync enabled + // Avoid resetting speed if sync lock is enabled and other decks with sync enabled // are playing, as this would change the speed of already playing decks. if (!m_pEngineMaster->getEngineSync()->otherSyncedPlaying(getGroup())) { m_pRateRatio->set(1.0); diff --git a/src/skin/legacy/tooltips.cpp b/src/skin/legacy/tooltips.cpp index 3540c5a43fbe..420f886e2410 100644 --- a/src/skin/legacy/tooltips.cpp +++ b/src/skin/legacy/tooltips.cpp @@ -538,7 +538,7 @@ void Tooltips::addStandardTooltips() { // Ghetto-Sync (TM) add("beatsync_beatsync_tempo") << tr("Old Synchronize") - << tr("(This skin should be updated to use Master Sync!)") + << tr("(This skin should be updated to use Sync Lock!)") << QString("%1: %2").arg(leftClick, tr("Syncs the tempo (BPM) and phase to that of the other track, " "if BPM is detected on both.")) << QString("%1: %2").arg(rightClick, tr("Syncs the tempo (BPM) to that of the other track, " @@ -549,7 +549,7 @@ void Tooltips::addStandardTooltips() { // Awesome-Sync (TM) add("sync_enabled") - << tr("Enable Master Sync") + << tr("Enable Sync Lock") << tr("Tap to sync the tempo to other playing tracks or the master clock.") << tr("Hold for at least a second to enable sync lock for this deck.") << tr("Decks with sync locked will all play at the same tempo, and decks that also have " @@ -562,7 +562,7 @@ void Tooltips::addStandardTooltips() { "from the other track. Requires a detected key on both involved decks.")) << QString("%1: %2").arg(rightClick, tr("Resets the key to the original track key.")); - add("sync_master") + add("sync_leader") << tr("Enable Sync Clock Master") << tr("When enabled, this device will serve as the master clock for all other decks."); diff --git a/src/test/enginesynctest.cpp b/src/test/enginesynctest.cpp index fc51115364a5..99e5bb7935aa 100644 --- a/src/test/enginesynctest.cpp +++ b/src/test/enginesynctest.cpp @@ -20,33 +20,33 @@ constexpr double kMaxFloatingPointErrorHighPrecision = 0.0000000000000005; constexpr double kMaxBeatDistanceEpsilon = 1e-9; } // namespace -/// Tests for Master Sync. +/// Tests for Sync Lock. /// The following manual tests should probably be performed: -/// * Quantize mode nudges tracks in sync, whether internal or deck master. +/// * Quantize mode nudges tracks in sync, whether internal or deck leader. /// * Flinging tracks with the waveform should work. /// * vinyl?? class EngineSyncTest : public MockedEngineBackendTest { public: - QString getMasterGroup() { - Syncable* pMasterSyncable = m_pEngineSync->getMasterSyncable(); - if (pMasterSyncable) { - return pMasterSyncable->getGroup(); + QString getLeaderGroup() { + Syncable* pLeaderSyncable = m_pEngineSync->getLeaderSyncable(); + if (pLeaderSyncable) { + return pLeaderSyncable->getGroup(); } return QString(); } - bool isExplicitMaster(const QString& group) { - return isMaster(group, SYNC_MASTER_EXPLICIT); + bool isExplicitLeader(const QString& group) { + return isLeader(group, SYNC_LEADER_EXPLICIT); } - bool isSoftMaster(const QString& group) { - return isMaster(group, SYNC_MASTER_SOFT); + bool isSoftLeader(const QString& group) { + return isLeader(group, SYNC_LEADER_SOFT); } bool isFollower(const QString& group) { if (group == m_sInternalClockGroup) { return !ControlObject::getControl(ConfigKey(m_sInternalClockGroup, - "sync_master")) + "sync_leader")) ->toBool(); } if (auto mode = ControlObject::getControl(ConfigKey(group, "sync_mode")) @@ -59,11 +59,11 @@ class EngineSyncTest : public MockedEngineBackendTest { qWarning() << "sync_enabled should be on, isn't"; return false; } - if (double master = ControlObject::getControl( - ConfigKey(group, "sync_master")) + if (double leader = ControlObject::getControl( + ConfigKey(group, "sync_leader")) ->get(); - master != 0.0) { - qWarning() << "sync_master should be 0.0, is" << master; + leader != 0.0) { + qWarning() << "sync_leader should be 0.0, is" << leader; return false; } return true; @@ -73,7 +73,7 @@ class EngineSyncTest : public MockedEngineBackendTest { if (group == m_sInternalClockGroup) { EXPECT_EQ(0, ControlObject::getControl( - ConfigKey(m_sInternalClockGroup, "sync_master")) + ConfigKey(m_sInternalClockGroup, "sync_leader")) ->get()); } else { EXPECT_EQ(SYNC_NONE, @@ -83,105 +83,105 @@ class EngineSyncTest : public MockedEngineBackendTest { ControlObject::getControl(ConfigKey(group, "sync_enabled")) ->get()); EXPECT_EQ(0, - ControlObject::getControl(ConfigKey(group, "sync_master")) + ControlObject::getControl(ConfigKey(group, "sync_leader")) ->get()); } } - void assertNoMaster() { - EXPECT_EQ(NULL, m_pEngineSync->getMaster()); - EXPECT_EQ(NULL, m_pEngineSync->getMasterSyncable()); + void assertNoLeader() { + EXPECT_EQ(NULL, m_pEngineSync->getLeader()); + EXPECT_EQ(NULL, m_pEngineSync->getLeaderSyncable()); } private: - bool isMaster(const QString& group, SyncMode masterType) { + bool isLeader(const QString& group, SyncMode leaderType) { if (group == m_sInternalClockGroup) { - double master = ControlObject::getControl(ConfigKey(m_sInternalClockGroup, - "sync_master")) + double leader = ControlObject::getControl(ConfigKey(m_sInternalClockGroup, + "sync_leader")) ->get(); - if (masterType == SYNC_MASTER_SOFT && master != 1.0) { - qWarning() << "internal clock sync_master should be 1.0, is" << master; + if (leaderType == SYNC_LEADER_SOFT && leader != 1.0) { + qWarning() << "internal clock sync_leader should be 1.0, is" << leader; return false; - } else if (masterType == SYNC_MASTER_EXPLICIT && master != 2.0) { - qWarning() << "internal clock sync_master should be 2.0, is" << master; + } else if (leaderType == SYNC_LEADER_EXPLICIT && leader != 2.0) { + qWarning() << "internal clock sync_leader should be 2.0, is" << leader; return false; } - if (m_pEngineSync->getMaster()) { - qWarning() << "no current master"; + if (m_pEngineSync->getLeader()) { + qWarning() << "no current leader"; return false; } - if (m_sInternalClockGroup != getMasterGroup()) { - qWarning() << "internal clock is not master, it's" << getMasterGroup(); + if (m_sInternalClockGroup != getLeaderGroup()) { + qWarning() << "internal clock is not leader, it's" << getLeaderGroup(); return false; } return true; } if (group == m_sGroup1) { - if (m_pEngineSync->getMaster() != m_pChannel1) { - qWarning() << "master pointer should be channel 1, is " - << (m_pEngineSync->getMaster() - ? m_pEngineSync->getMaster() + if (m_pEngineSync->getLeader() != m_pChannel1) { + qWarning() << "leader pointer should be channel 1, is " + << (m_pEngineSync->getLeader() + ? m_pEngineSync->getLeader() ->getGroup() : "null"); return false; } } else if (group == m_sGroup2) { - if (m_pEngineSync->getMaster() != m_pChannel2) { - qWarning() << "master pointer should be channel 2, is " - << (m_pEngineSync->getMaster() - ? m_pEngineSync->getMaster() + if (m_pEngineSync->getLeader() != m_pChannel2) { + qWarning() << "leader pointer should be channel 2, is " + << (m_pEngineSync->getLeader() + ? m_pEngineSync->getLeader() ->getGroup() : "null"); return false; } } else if (group == m_sGroup3) { - if (m_pEngineSync->getMaster() != m_pChannel3) { - qWarning() << "master pointer should be channel 3, is " - << (m_pEngineSync->getMaster() - ? m_pEngineSync->getMaster() + if (m_pEngineSync->getLeader() != m_pChannel3) { + qWarning() << "leader pointer should be channel 3, is " + << (m_pEngineSync->getLeader() + ? m_pEngineSync->getLeader() ->getGroup() : "null"); return false; } } - if (getMasterGroup() != group) { - qWarning() << "master group should be" << group << ", is" << getMasterGroup(); + if (getLeaderGroup() != group) { + qWarning() << "leader group should be" << group << ", is" << getLeaderGroup(); return false; } if (auto mode = ControlObject::getControl(ConfigKey(group, "sync_mode")) ->get(); - mode != masterType) { - qWarning() << "mode should be" << masterType << ", is" << mode; + mode != leaderType) { + qWarning() << "mode should be" << leaderType << ", is" << mode; return false; } if (!ControlObject::getControl(ConfigKey(group, "sync_enabled"))->toBool()) { qWarning() << "sync_enabled should be true, isn't"; return false; } - switch (masterType) { - case SYNC_MASTER_SOFT: { - if (double master = ControlObject::getControl( - ConfigKey(group, "sync_master")) + switch (leaderType) { + case SYNC_LEADER_SOFT: { + if (double leader = ControlObject::getControl( + ConfigKey(group, "sync_leader")) ->get(); - master != 1.0) { - qWarning() << "master should be 1.0, is" << master; + leader != 1.0) { + qWarning() << "leader should be 1.0, is" << leader; return false; } break; } - case SYNC_MASTER_EXPLICIT: { - if (double master = ControlObject::getControl( - ConfigKey(group, "sync_master")) + case SYNC_LEADER_EXPLICIT: { + if (double leader = ControlObject::getControl( + ConfigKey(group, "sync_leader")) ->get(); - master != 2.0) { - qWarning() << "master should be 2.0, is" << master; + leader != 2.0) { + qWarning() << "leader should be 2.0, is" << leader; return false; } break; } default: - qWarning() << "bad master type specified"; + qWarning() << "bad leader type specified"; return false; } return true; @@ -194,46 +194,46 @@ TEST_F(EngineSyncTest, ControlObjectsExist) { NULL); } -TEST_F(EngineSyncTest, SetMasterSuccess) { - // If we set the first channel to master, EngineSync should get that message. +TEST_F(EngineSyncTest, SetLeaderSuccess) { + // If we set the first channel to leader, EngineSync should get that message. - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->slotSet(SYNC_MASTER_EXPLICIT); + pButtonLeaderSync1->slotSet(SYNC_LEADER_EXPLICIT); ProcessBuffer(); - // No tracks are playing and we have no beats, SYNC_MASTER_EXPLICIT state is in stand-by + // No tracks are playing and we have no beats, SYNC_leader_EXPLICIT state is in stand-by EXPECT_DOUBLE_EQ( 0.0, ControlObject::getControl(ConfigKey(m_sGroup1, "bpm"))->get()); - // The master sync should now be internal clock, with group 1 waiting for play. + // The sync lock should now be internal clock, with group 1 waiting for play. EXPECT_TRUE(isFollower(m_sInternalClockGroup)); EXPECT_TRUE(isFollower(m_sGroup1)); - auto pButtonMasterSync2 = + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->set(SYNC_FOLLOWER); + pButtonLeaderSync2->set(SYNC_FOLLOWER); ProcessBuffer(); EXPECT_TRUE(isFollower(m_sGroup2)); - // Now set channel 2 to be master. - pButtonMasterSync2->set(SYNC_MASTER_EXPLICIT); + // Now set channel 2 to be leader. + pButtonLeaderSync2->set(SYNC_LEADER_EXPLICIT); ProcessBuffer(); - // Now channel 2 should be waiting master, and channel 1 should be a follower. + // Now channel 2 should be waiting leader, and channel 1 should be a follower. EXPECT_TRUE(isFollower(m_sGroup2)); EXPECT_TRUE(isFollower(m_sGroup1)); // Now back again. - pButtonMasterSync1->set(SYNC_MASTER_EXPLICIT); + pButtonLeaderSync1->set(SYNC_LEADER_EXPLICIT); ProcessBuffer(); - // Now channel 1 should be waiting master, and channel 2 should be a follower. + // Now channel 1 should be waiting leader, and channel 2 should be a follower. EXPECT_TRUE(isFollower(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); // Now set channel 1 to follower, now all are followers, waiting for a tempo to adopt. - pButtonMasterSync1->slotSet(SYNC_FOLLOWER); + pButtonLeaderSync1->slotSet(SYNC_FOLLOWER); ProcessBuffer(); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); @@ -241,28 +241,28 @@ TEST_F(EngineSyncTest, SetMasterSuccess) { EXPECT_TRUE(isFollower(m_sGroup2)); } -TEST_F(EngineSyncTest, ExplicitMasterPersists) { - // If we set an explicit master, enabling sync or pressing play on other decks - // doesn't cause the master to move around. +TEST_F(EngineSyncTest, ExplicitLeaderPersists) { + // If we set an explicit leader, enabling sync or pressing play on other decks + // doesn't cause the leader to move around. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 120, 0.0); m_pTrack1->trySetBeats(pBeats1); mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 124, 0.0); m_pTrack2->trySetBeats(pBeats2); - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); - pButtonMasterSync1->slotSet(SYNC_MASTER_EXPLICIT); + pButtonLeaderSync1->slotSet(SYNC_LEADER_EXPLICIT); ProcessBuffer(); - // The master sync should now be channel 1. - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + // The sync lock should now be channel 1. + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); - auto pButtonMasterSync2 = + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_enabled"); ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); - pButtonMasterSync2->set(1.0); + pButtonLeaderSync2->set(1.0); ProcessBuffer(); - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); // Stop deck 2, and restart it, no change. @@ -270,12 +270,12 @@ TEST_F(EngineSyncTest, ExplicitMasterPersists) { ProcessBuffer(); ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); ProcessBuffer(); - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); } -TEST_F(EngineSyncTest, SetMasterWhilePlaying) { - // Make sure we don't get two master lights if we change masters while playing. +TEST_F(EngineSyncTest, SetLeaderWhilePlaying) { + // Make sure we don't get two leader lights if we change leaders while playing. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 120, 0.0); m_pTrack1->trySetBeats(pBeats1); mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 124, 0.0); @@ -283,15 +283,15 @@ TEST_F(EngineSyncTest, SetMasterWhilePlaying) { mixxx::BeatsPointer pBeats3 = BeatFactory::makeBeatGrid(m_pTrack3->getSampleRate(), 128, 0.0); m_pTrack3->trySetBeats(pBeats3); - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->set(SYNC_MASTER_EXPLICIT); - auto pButtonMasterSync2 = + pButtonLeaderSync1->set(SYNC_LEADER_EXPLICIT); + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->slotSet(SYNC_FOLLOWER); - auto pButtonMasterSync3 = + pButtonLeaderSync2->slotSet(SYNC_FOLLOWER); + auto pButtonLeaderSync3 = std::make_unique(m_sGroup3, "sync_mode"); - pButtonMasterSync3->slotSet(SYNC_FOLLOWER); + pButtonLeaderSync3->slotSet(SYNC_FOLLOWER); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); @@ -299,32 +299,32 @@ TEST_F(EngineSyncTest, SetMasterWhilePlaying) { ProcessBuffer(); - pButtonMasterSync3->slotSet(SYNC_MASTER_EXPLICIT); + pButtonLeaderSync3->slotSet(SYNC_LEADER_EXPLICIT); ProcessBuffer(); EXPECT_TRUE(isFollower(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); - EXPECT_TRUE(isExplicitMaster(m_sGroup3)); + EXPECT_TRUE(isExplicitLeader(m_sGroup3)); } -TEST_F(EngineSyncTest, SetEnabledBecomesMaster) { - // If we set the first channel with a valid tempo to follower, it should be master. +TEST_F(EngineSyncTest, SetEnabledBecomesLeader) { + // If we set the first channel with a valid tempo to follower, it should be leader. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 80, 0.0); m_pTrack1->trySetBeats(pBeats1); - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->slotSet(SYNC_FOLLOWER); + pButtonLeaderSync1->slotSet(SYNC_FOLLOWER); ProcessBuffer(); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); } -TEST_F(EngineSyncTest, DisableInternalMasterWhilePlaying) { - auto pButtonMasterSync = std::make_unique( - m_sInternalClockGroup, "sync_master"); - pButtonMasterSync->slotSet(1.0); +TEST_F(EngineSyncTest, DisableInternalLeaderWhilePlaying) { + auto pButtonLeaderSync = std::make_unique( + m_sInternalClockGroup, "sync_leader"); + pButtonLeaderSync->slotSet(1.0); auto pButtonSyncMode1 = std::make_unique(m_sGroup1, "sync_mode"); pButtonSyncMode1->slotSet(SYNC_FOLLOWER); @@ -332,8 +332,8 @@ TEST_F(EngineSyncTest, DisableInternalMasterWhilePlaying) { std::make_unique(m_sGroup2, "sync_mode"); pButtonSyncMode2->slotSet(SYNC_FOLLOWER); ProcessBuffer(); - // The master sync should now be Internal. - EXPECT_TRUE(isExplicitMaster(m_sInternalClockGroup)); + // The sync lock should now be Internal. + EXPECT_TRUE(isExplicitLeader(m_sInternalClockGroup)); // Make sure both decks are playing. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 80, 0.0); @@ -344,17 +344,17 @@ TEST_F(EngineSyncTest, DisableInternalMasterWhilePlaying) { ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); ProcessBuffer(); - // Now unset Internal master. - pButtonMasterSync->slotSet(0.0); + // Now unset Internal leader. + pButtonLeaderSync->slotSet(0.0); ProcessBuffer(); - // This is not allowed, Internal should still be master. + // This is not allowed, Internal should still be leader. EXPECT_TRUE(isFollower(m_sInternalClockGroup)); - EXPECT_EQ(0, pButtonMasterSync->get()); + EXPECT_EQ(0, pButtonLeaderSync->get()); } -TEST_F(EngineSyncTest, DisableSyncOnMaster) { - // Channel 1 follower, channel 2 master. +TEST_F(EngineSyncTest, DisableSyncOnLeader) { + // Channel 1 follower, channel 2 leader. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 130, 0.0); m_pTrack1->trySetBeats(pBeats1); auto pButtonSyncMode1 = @@ -363,48 +363,48 @@ TEST_F(EngineSyncTest, DisableSyncOnMaster) { mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 130, 0.0); m_pTrack2->trySetBeats(pBeats2); - // Set deck two to explicit master. - auto pButtonSyncMaster2 = - std::make_unique(m_sGroup2, "sync_master"); - pButtonSyncMaster2->slotSet(1.0); + // Set deck two to explicit leader. + auto pButtonSyncLeader2 = + std::make_unique(m_sGroup2, "sync_leader"); + pButtonSyncLeader2->slotSet(1.0); ProcessBuffer(); EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isExplicitMaster(m_sGroup2)); + EXPECT_TRUE(isExplicitLeader(m_sGroup2)); - // Set deck 2 to playing, now it becomes explicit master. + // Set deck 2 to playing, now it becomes explicit leader. ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); - // The request to become master is queued, so we have to process a buffer. + // The request to become leader is queued, so we have to process a buffer. ProcessBuffer(); EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isExplicitMaster(m_sGroup2)); + EXPECT_TRUE(isExplicitLeader(m_sGroup2)); // Unset enabled on channel2, it should work. auto pButtonSyncEnabled2 = std::make_unique(m_sGroup2, "sync_enabled"); pButtonSyncEnabled2->slotSet(0.0); ProcessBuffer(); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_EQ(0, ControlObject::getControl(ConfigKey(m_sGroup2, "sync_enabled"))->get()); - EXPECT_EQ(0, ControlObject::getControl(ConfigKey(m_sGroup2, "sync_master"))->get()); + EXPECT_EQ(0, ControlObject::getControl(ConfigKey(m_sGroup2, "sync_leader"))->get()); } -TEST_F(EngineSyncTest, InternalMasterSetFollowerSliderMoves) { - // If internal is master, and we turn on a follower, the slider should move. - auto pButtonMasterSyncInternal = std::make_unique( - m_sInternalClockGroup, "sync_master"); - auto pMasterSyncSlider = +TEST_F(EngineSyncTest, InternalLeaderSetFollowerSliderMoves) { + // If internal is leader, and we turn on a follower, the slider should move. + auto pButtonLeaderSyncInternal = std::make_unique( + m_sInternalClockGroup, "sync_leader"); + auto pLeaderSyncSlider = std::make_unique(m_sInternalClockGroup, "bpm"); - pMasterSyncSlider->set(100.0); - pButtonMasterSyncInternal->slotSet(1); + pLeaderSyncSlider->set(100.0); + pButtonLeaderSyncInternal->slotSet(1); // Set the file bpm of channel 1 to 80 bpm. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 80, 0.0); m_pTrack1->trySetBeats(pBeats1); - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->slotSet(SYNC_FOLLOWER); + pButtonLeaderSync1->slotSet(SYNC_FOLLOWER); ProcessBuffer(); EXPECT_DOUBLE_EQ(getRateSliderValue(1.25), @@ -415,7 +415,7 @@ TEST_F(EngineSyncTest, InternalMasterSetFollowerSliderMoves) { TEST_F(EngineSyncTest, AnySyncDeckSliderStays) { // If there exists a sync deck, even if it's not playing, don't change the - // master BPM if a new deck enables sync. + // leader BPM if a new deck enables sync. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 80, 0.0); m_pTrack1->trySetBeats(pBeats1); @@ -442,9 +442,9 @@ TEST_F(EngineSyncTest, AnySyncDeckSliderStays) { TEST_F(EngineSyncTest, InternalClockFollowsFirstPlayingDeck) { // Same as above, except we use the midi lights to change state. - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - auto pButtonMasterSync2 = + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); auto pButtonSyncEnabled1 = std::make_unique(m_sGroup1, "sync_enabled"); @@ -466,8 +466,8 @@ TEST_F(EngineSyncTest, InternalClockFollowsFirstPlayingDeck) { pButtonSyncEnabled1->set(1.0); ProcessBuffer(); - // The master sync should now be deck 1. - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + // The sync lock should now be deck 1. + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_DOUBLE_EQ(130.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); @@ -475,8 +475,8 @@ TEST_F(EngineSyncTest, InternalClockFollowsFirstPlayingDeck) { pButtonSyncEnabled2->set(1); ProcessBuffer(); - // channel 1 still master while 2 is not playing - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + // channel 1 still leader while 2 is not playing + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); EXPECT_TRUE(isFollower(m_sGroup2)); @@ -488,17 +488,17 @@ TEST_F(EngineSyncTest, InternalClockFollowsFirstPlayingDeck) { ControlObject::set(ConfigKey(m_sGroup2, "rate"), getRateSliderValue(1.0)); ControlObject::set(ConfigKey(m_sGroup2, "play"), 1.0); ProcessBuffer(); - // Deck 1 still master + // Deck 1 still leader EXPECT_TRUE(isFollower(m_sInternalClockGroup)); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); // Now disable sync on channel 1. pButtonSyncEnabled1->set(0); ProcessBuffer(); - // Master flips to deck 2 - EXPECT_TRUE(isSoftMaster(m_sGroup2)); + // Leader flips to deck 2 + EXPECT_TRUE(isSoftLeader(m_sGroup2)); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); // Rate should now match channel 2. @@ -506,20 +506,20 @@ TEST_F(EngineSyncTest, InternalClockFollowsFirstPlayingDeck) { 130.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); } -TEST_F(EngineSyncTest, SetExplicitMasterByLights) { +TEST_F(EngineSyncTest, SetExplicitLeaderByLights) { // Same as above, except we use the midi lights to change state. - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - auto pButtonMasterSync2 = + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); auto pButtonSyncEnabled1 = std::make_unique(m_sGroup1, "sync_enabled"); auto pButtonSyncEnabled2 = std::make_unique(m_sGroup2, "sync_enabled"); - auto pButtonSyncMaster1 = - std::make_unique(m_sGroup1, "sync_master"); - auto pButtonSyncMaster2 = - std::make_unique(m_sGroup2, "sync_master"); + auto pButtonSyncLeader1 = + std::make_unique(m_sGroup1, "sync_leader"); + auto pButtonSyncLeader2 = + std::make_unique(m_sGroup2, "sync_leader"); // Set the file bpm of channel 1 to 160bpm. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 160, 0.0); @@ -531,12 +531,12 @@ TEST_F(EngineSyncTest, SetExplicitMasterByLights) { ControlObject::set(ConfigKey(m_sGroup1, "play"), 1.0); ControlObject::set(ConfigKey(m_sGroup2, "play"), 1.0); - // Set channel 1 to be explicit master. - pButtonSyncMaster1->slotSet(1.0); + // Set channel 1 to be explicit leader. + pButtonSyncLeader1->slotSet(1.0); ProcessBuffer(); - // The master sync should now be channel 1. - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + // The sync lock should now be channel 1. + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); // Set channel 2 to be follower. pButtonSyncEnabled2->slotSet(1); @@ -544,49 +544,49 @@ TEST_F(EngineSyncTest, SetExplicitMasterByLights) { EXPECT_TRUE(isFollower(m_sGroup2)); - // Now set channel 2 to be master. - pButtonSyncMaster2->slotSet(1); + // Now set channel 2 to be leader. + pButtonSyncLeader2->slotSet(1); ProcessBuffer(); - // Now channel 2 should be master, and channel 1 should be a follower. + // Now channel 2 should be leader, and channel 1 should be a follower. EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isExplicitMaster(m_sGroup2)); + EXPECT_TRUE(isExplicitLeader(m_sGroup2)); // Now back again. - pButtonSyncMaster1->slotSet(1); + pButtonSyncLeader1->slotSet(1); ProcessBuffer(); - // Now channel 1 should be master, and channel 2 should be a follower. - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + // Now channel 1 should be leader, and channel 2 should be a follower. + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); - // Now set channel 1 to not-master. The system will choose deck 2 as the next best - // option for soft master - pButtonSyncMaster1->slotSet(0); + // Now set channel 1 to not-leader. The system will choose deck 2 as the next best + // option for soft leader + pButtonSyncLeader1->slotSet(0); ProcessBuffer(); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); } -TEST_F(EngineSyncTest, SetExplicitMasterByLightsNoTracks) { +TEST_F(EngineSyncTest, SetExplicitLeaderByLightsNoTracks) { // Same as above, except we use the midi lights to change state. auto pButtonSyncEnabled2 = std::make_unique(m_sGroup2, "sync_enabled"); - auto pButtonSyncMaster1 = - std::make_unique(m_sGroup1, "sync_master"); + auto pButtonSyncLeader1 = + std::make_unique(m_sGroup1, "sync_leader"); - pButtonSyncMaster1->slotSet(1); + pButtonSyncLeader1->slotSet(1); // Set channel 2 to be follower. pButtonSyncEnabled2->slotSet(1); - // Without a track loaded, deck 1 can't be an explicit master. + // Without a track loaded, deck 1 can't be an explicit leader. EXPECT_TRUE(isFollower(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); - pButtonSyncMaster1->slotSet(0); + pButtonSyncLeader1->slotSet(0); EXPECT_TRUE(isFollower(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); @@ -594,12 +594,12 @@ TEST_F(EngineSyncTest, SetExplicitMasterByLightsNoTracks) { } TEST_F(EngineSyncTest, RateChangeTest) { - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->set(SYNC_MASTER_EXPLICIT); - auto pButtonMasterSync2 = + pButtonLeaderSync1->set(SYNC_LEADER_EXPLICIT); + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->set(SYNC_FOLLOWER); + pButtonLeaderSync2->set(SYNC_FOLLOWER); ProcessBuffer(); // Set the file bpm of channel 1 to 160bpm. @@ -617,7 +617,7 @@ TEST_F(EngineSyncTest, RateChangeTest) { ControlObject::get(ConfigKey(m_sGroup1, "rate"))); EXPECT_DOUBLE_EQ(192.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); - // Internal master should also be 192. + // Internal leader should also be 192. EXPECT_DOUBLE_EQ( 192.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); @@ -635,12 +635,12 @@ TEST_F(EngineSyncTest, RateChangeTest) { TEST_F(EngineSyncTest, RateChangeTestWeirdOrder) { // This is like the test above, but the user loads the track after the slider has been tweaked. - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->slotSet(SYNC_MASTER_EXPLICIT); - auto pButtonMasterSync2 = + pButtonLeaderSync1->slotSet(SYNC_LEADER_EXPLICIT); + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->slotSet(SYNC_FOLLOWER); + pButtonLeaderSync2->slotSet(SYNC_FOLLOWER); ProcessBuffer(); // Set the file bpm of channel 1 to 160bpm. @@ -661,7 +661,7 @@ TEST_F(EngineSyncTest, RateChangeTestWeirdOrder) { ControlObject::get(ConfigKey(m_sGroup2, "rate"))); EXPECT_DOUBLE_EQ(192.0, ControlObject::get(ConfigKey(m_sGroup2, "bpm"))); - // Internal Master BPM should read the same. + // Internal Leader BPM should read the same. EXPECT_DOUBLE_EQ( 192.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); } @@ -679,19 +679,19 @@ TEST_F(EngineSyncTest, RateChangeTestOrder3) { EXPECT_DOUBLE_EQ( 120.0, ControlObject::get(ConfigKey(m_sGroup2, "file_bpm"))); - // Turn on Master. Setting explicit master causes this track's rate to be adopted instead + // Turn on Leader. Setting explicit leader causes this track's rate to be adopted instead // of matching against the other deck. - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->set(SYNC_MASTER_EXPLICIT); + pButtonLeaderSync1->set(SYNC_LEADER_EXPLICIT); ProcessBuffer(); - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); EXPECT_DOUBLE_EQ(160.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); // Turn on follower. - auto pButtonMasterSync2 = + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->set(SYNC_FOLLOWER); + pButtonLeaderSync2->set(SYNC_FOLLOWER); ProcessBuffer(); // Follower should immediately set its slider. @@ -704,13 +704,13 @@ TEST_F(EngineSyncTest, RateChangeTestOrder3) { } TEST_F(EngineSyncTest, FollowerRateChange) { - // Confirm that followers can change master sync rate as well. - auto pButtonMasterSync1 = + // Confirm that followers can change sync lock rate as well. + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->set(SYNC_MASTER_EXPLICIT); - auto pButtonMasterSync2 = + pButtonLeaderSync1->set(SYNC_LEADER_EXPLICIT); + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->set(SYNC_FOLLOWER); + pButtonLeaderSync2->set(SYNC_FOLLOWER); ProcessBuffer(); // Set the file bpm of channel 1 to 160bpm. @@ -744,18 +744,18 @@ TEST_F(EngineSyncTest, FollowerRateChange) { } TEST_F(EngineSyncTest, InternalRateChangeTest) { - auto pButtonMasterSyncInternal = std::make_unique( - m_sInternalClockGroup, "sync_master"); - pButtonMasterSyncInternal->set(1.0); - auto pButtonMasterSync1 = + auto pButtonLeaderSyncInternal = std::make_unique( + m_sInternalClockGroup, "sync_leader"); + pButtonLeaderSyncInternal->set(1.0); + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->set(SYNC_FOLLOWER); - auto pButtonMasterSync2 = + pButtonLeaderSync1->set(SYNC_FOLLOWER); + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->set(SYNC_FOLLOWER); + pButtonLeaderSync2->set(SYNC_FOLLOWER); ProcessBuffer(); - EXPECT_TRUE(isExplicitMaster(m_sInternalClockGroup)); + EXPECT_TRUE(isExplicitLeader(m_sInternalClockGroup)); EXPECT_TRUE(isFollower(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); @@ -772,9 +772,9 @@ TEST_F(EngineSyncTest, InternalRateChangeTest) { ControlObject::getControl(ConfigKey(m_sGroup2, "file_bpm"))->get()); // Set the internal rate to 150. - auto pMasterSyncSlider = + auto pLeaderSyncSlider = std::make_unique(m_sInternalClockGroup, "bpm"); - pMasterSyncSlider->set(150.0); + pLeaderSyncSlider->set(150.0); EXPECT_DOUBLE_EQ(150.0, ControlObject::getControl(ConfigKey(m_sInternalClockGroup, "bpm")) ->get()); @@ -793,7 +793,7 @@ TEST_F(EngineSyncTest, InternalRateChangeTest) { ControlObject::getControl(ConfigKey(m_sGroup2, "bpm"))->get()); // Set the internal rate to 140. - pMasterSyncSlider->set(140.0); + pLeaderSyncSlider->set(140.0); // Update COs again. ProcessBuffer(); @@ -810,22 +810,22 @@ TEST_F(EngineSyncTest, InternalRateChangeTest) { ControlObject::getControl(ConfigKey(m_sGroup2, "bpm"))->get()); } -TEST_F(EngineSyncTest, MasterStopSliderCheck) { - // If the master is playing, and stop is pushed, the sliders should stay the same. +TEST_F(EngineSyncTest, LeaderStopSliderCheck) { + // If the leader is playing, and stop is pushed, the sliders should stay the same. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 120, 0.0); m_pTrack1->trySetBeats(pBeats1); mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 128, 0.0); m_pTrack2->trySetBeats(pBeats2); - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->slotSet(SYNC_MASTER_EXPLICIT); - auto pButtonMasterSync2 = + pButtonLeaderSync1->slotSet(SYNC_LEADER_EXPLICIT); + auto pButtonLeaderSync2 = std::make_unique(m_sGroup2, "sync_mode"); - pButtonMasterSync2->slotSet(SYNC_FOLLOWER); + pButtonLeaderSync2->slotSet(SYNC_FOLLOWER); ProcessBuffer(); - //EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + //EXPECT_TRUE(isExplicitLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); auto pChannel1Play = std::make_unique(m_sGroup1, "play"); @@ -848,9 +848,9 @@ TEST_F(EngineSyncTest, MasterStopSliderCheck) { ControlObject::get(ConfigKey(m_sGroup2, "rate"))); } -TEST_F(EngineSyncTest, EnableOneDeckInitsMaster) { - // If Internal is master, and we turn sync on a playing deck, the playing deck sets the - // internal master and the beat distances are now aligned. +TEST_F(EngineSyncTest, EnableOneDeckInitsLeader) { + // If Internal is leader, and we turn sync on a playing deck, the playing deck sets the + // internal leader and the beat distances are now aligned. ControlObject::set(ConfigKey(m_sInternalClockGroup, "bpm"), 124.0); ControlObject::set(ConfigKey(m_sInternalClockGroup, "beat_distance"), 0.5); ProcessBuffer(); @@ -868,8 +868,8 @@ TEST_F(EngineSyncTest, EnableOneDeckInitsMaster) { m_pEngineSync->requestSyncMode( m_pEngineSync->getSyncableForGroup(m_sGroup1), SYNC_FOLLOWER); - // Internal is no longer master because there is exactly one playing deck. - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + // Internal is no longer leader because there is exactly one playing deck. + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); // Internal clock rate and beat distance should match that deck. @@ -892,9 +892,9 @@ TEST_F(EngineSyncTest, EnableOneDeckInitsMaster) { m_pEngineSync->requestSyncMode( m_pEngineSync->getSyncableForGroup(m_sGroup2), SYNC_FOLLOWER); - // Deck 1 is still soft master. + // Deck 1 is still soft leader. EXPECT_TRUE(isFollower(m_sInternalClockGroup)); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); EXPECT_DOUBLE_EQ( @@ -928,8 +928,8 @@ TEST_F(EngineSyncTest, MomentarySyncAlgorithmTwo) { EXPECT_DOUBLE_EQ(128.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); } -TEST_F(EngineSyncTest, EnableOneDeckInitializesMaster) { - // Enabling sync on a deck causes it to be master, and sets bpm and clock. +TEST_F(EngineSyncTest, EnableOneDeckInitializesLeader) { + // Enabling sync on a deck causes it to be leader, and sets bpm and clock. // Set the deck to play. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 130, 0.0); m_pTrack1->trySetBeats(pBeats1); @@ -943,8 +943,8 @@ TEST_F(EngineSyncTest, EnableOneDeckInitializesMaster) { m_pEngineSync->requestSyncMode( m_pEngineSync->getSyncableForGroup(m_sGroup1), SYNC_FOLLOWER); - // That first deck is now master - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + // That first deck is now leader + EXPECT_TRUE(isSoftLeader(m_sGroup1)); // Internal clock rate should be set and beat distances reset. EXPECT_DOUBLE_EQ(130.0, @@ -961,7 +961,7 @@ TEST_F(EngineSyncTest, EnableOneDeckInitializesMaster) { ->get()); } -TEST_F(EngineSyncTest, LoadTrackInitializesMaster) { +TEST_F(EngineSyncTest, LoadTrackInitializesLeader) { // First eject the fake tracks that come with the testing framework. m_pChannel1->getEngineBuffer()->slotEjectTrack(1.0); m_pChannel2->getEngineBuffer()->slotEjectTrack(1.0); @@ -971,24 +971,24 @@ TEST_F(EngineSyncTest, LoadTrackInitializesMaster) { std::make_unique(m_sGroup1, "sync_enabled"); pButtonSyncEnabled1->slotSet(1.0); - // No master because this deck has no track. - EXPECT_EQ(NULL, m_pEngineSync->getMaster()); + // No leader because this deck has no track. + EXPECT_EQ(NULL, m_pEngineSync->getLeader()); EXPECT_DOUBLE_EQ( 0.0, ControlObject::getControl(ConfigKey(m_sGroup1, "bpm"))->get()); - // The track load trigger a master change. + // The track load trigger a leader change. m_pMixerDeck1->loadFakeTrack(false, 140.0); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_DOUBLE_EQ(140.0, ControlObject::getControl(ConfigKey(m_sGroup1, "bpm"))->get()); - // But as soon as we play, deck 1 is master + // But as soon as we play, deck 1 is leader ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(0.0); // If sync is on two decks and we load a track in only one of them, it will be - // master. + // leader. m_pChannel1->getEngineBuffer()->slotEjectTrack(1.0); EXPECT_TRUE(isFollower(m_sGroup1)); // no relevant tempo available so internal clock is following @@ -1000,13 +1000,13 @@ TEST_F(EngineSyncTest, LoadTrackInitializesMaster) { m_pMixerDeck1->loadFakeTrack(false, 128.0); - // Deck 2 is still empty so Deck 1 becomes master again - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + // Deck 2 is still empty so Deck 1 becomes leader again + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_DOUBLE_EQ(128.0, ControlObject::getControl(ConfigKey(m_sGroup1, "bpm"))->get()); // If sync is on two decks and one deck is loaded but not playing, we should - // initialize to that deck with internal clock master. + // initialize to that deck with internal clock leader. m_pMixerDeck2->loadFakeTrack(false, 110.0); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); @@ -1020,9 +1020,9 @@ TEST_F(EngineSyncTest, LoadTrackInitializesMaster) { } TEST_F(EngineSyncTest, LoadTrackResetTempoOption) { - // Make sure playing decks with master sync enabled do not change tempo when + // Make sure playing decks with sync lock enabled do not change tempo when // the "Reset Speed/Tempo" preference is set and a track is loaded to another - // deck with master sync enabled. + // deck with sync lock enabled. m_pConfig->set(ConfigKey("[Controls]", "SpeedAutoReset"), ConfigValue(BaseTrackPlayer::RESET_SPEED)); @@ -1035,13 +1035,13 @@ TEST_F(EngineSyncTest, LoadTrackResetTempoOption) { std::make_unique(m_sGroup2, "sync_enabled"); pButtonSyncEnabled2->set(1.0); - // If sync is on and we load a track, that should initialize master. + // If sync is on and we load a track, that should initialize leader. TrackPointer track1 = m_pMixerDeck1->loadFakeTrack(false, 140.0); EXPECT_DOUBLE_EQ( 140.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); EXPECT_DOUBLE_EQ(140.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); // If sync is on two decks and we load a track while one is playing, // that should not change the playing deck. @@ -1117,7 +1117,7 @@ TEST_F(EngineSyncTest, LoadTrackResetTempoOption) { } TEST_F(EngineSyncTest, EnableOneDeckSliderUpdates) { - // If we enable a deck to be master, the internal slider should immediately update. + // If we enable a deck to be leader, the internal slider should immediately update. auto pButtonSyncEnabled1 = std::make_unique(m_sGroup1, "sync_enabled"); @@ -1130,8 +1130,8 @@ TEST_F(EngineSyncTest, EnableOneDeckSliderUpdates) { pButtonSyncEnabled1->slotSet(1.0); ProcessBuffer(); - // Group 1 should now be master (only one sync deck). - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + // Group 1 should now be leader (only one sync deck). + EXPECT_TRUE(isSoftLeader(m_sGroup1)); // Internal clock rate should be set. EXPECT_DOUBLE_EQ(130.0, @@ -1165,9 +1165,9 @@ TEST_F(EngineSyncTest, SyncToNonSyncDeck) { pButtonSyncEnabled2->set(0.0); ProcessBuffer(); - // There should be no master, and deck2 should match rate of deck1. Sync slider should be + // There should be no leader, and deck2 should match rate of deck1. Sync slider should be // updated with the value, however. - assertNoMaster(); + assertNoLeader(); EXPECT_DOUBLE_EQ( 130.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); assertSyncOff(m_sGroup2); @@ -1182,17 +1182,17 @@ TEST_F(EngineSyncTest, SyncToNonSyncDeck) { pButtonSyncEnabled1->set(0.0); ProcessBuffer(); - // There should be no master, and deck2 should match rate of deck1. + // There should be no leader, and deck2 should match rate of deck1. EXPECT_EQ(0, ControlObject::get( - ConfigKey(m_sInternalClockGroup, "sync_master"))); + ConfigKey(m_sInternalClockGroup, "sync_leader"))); EXPECT_DOUBLE_EQ( 100.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); - EXPECT_EQ(NULL, m_pEngineSync->getMaster()); - EXPECT_EQ(NULL, m_pEngineSync->getMasterSyncable()); + EXPECT_EQ(NULL, m_pEngineSync->getLeader()); + EXPECT_EQ(NULL, m_pEngineSync->getLeaderSyncable()); EXPECT_EQ(SYNC_NONE, ControlObject::get(ConfigKey(m_sGroup1, "sync_mode"))); EXPECT_EQ(0, ControlObject::get(ConfigKey(m_sGroup1, "sync_enabled"))); - EXPECT_EQ(0, ControlObject::get(ConfigKey(m_sGroup1, "sync_master"))); + EXPECT_EQ(0, ControlObject::get(ConfigKey(m_sGroup1, "sync_leader"))); EXPECT_DOUBLE_EQ(getRateSliderValue(100.0 / 130.0), ControlObject::get(ConfigKey(m_sGroup1, "rate"))); @@ -1207,17 +1207,17 @@ TEST_F(EngineSyncTest, SyncToNonSyncDeck) { pButtonSyncEnabled1->set(0.0); ProcessBuffer(); - // There should be no master, and deck2 should match rate of deck1. + // There should be no leader, and deck2 should match rate of deck1. EXPECT_EQ(0, ControlObject::get( - ConfigKey(m_sInternalClockGroup, "sync_master"))); + ConfigKey(m_sInternalClockGroup, "sync_leader"))); EXPECT_DOUBLE_EQ( 100.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); - EXPECT_EQ(NULL, m_pEngineSync->getMaster()); - EXPECT_EQ(NULL, m_pEngineSync->getMasterSyncable()); + EXPECT_EQ(NULL, m_pEngineSync->getLeader()); + EXPECT_EQ(NULL, m_pEngineSync->getLeaderSyncable()); EXPECT_EQ(SYNC_NONE, ControlObject::get(ConfigKey(m_sGroup2, "sync_mode"))); EXPECT_EQ(0, ControlObject::get(ConfigKey(m_sGroup2, "sync_enabled"))); - EXPECT_EQ(0, ControlObject::get(ConfigKey(m_sGroup2, "sync_master"))); + EXPECT_EQ(0, ControlObject::get(ConfigKey(m_sGroup2, "sync_leader"))); EXPECT_DOUBLE_EQ(getRateSliderValue(1.0), ControlObject::get(ConfigKey(m_sGroup2, "rate"))); } @@ -1248,8 +1248,8 @@ TEST_F(EngineSyncTest, MomentarySyncDependsOnPlayingStates) { pButtonSyncEnabled1->set(0.0); ProcessBuffer(); - // The master sync should still be off and the speed should match deck 2. - assertNoMaster(); + // The sync lock should still be off and the speed should match deck 2. + assertNoLeader(); assertSyncOff(m_sGroup1); assertSyncOff(m_sGroup2); EXPECT_DOUBLE_EQ( @@ -1263,7 +1263,7 @@ TEST_F(EngineSyncTest, MomentarySyncDependsOnPlayingStates) { pButtonSyncEnabled1->set(1.0); pButtonSyncEnabled1->set(0.0); ProcessBuffer(); - assertNoMaster(); + assertNoLeader(); assertSyncOff(m_sGroup1); assertSyncOff(m_sGroup2); EXPECT_DOUBLE_EQ( @@ -1277,7 +1277,7 @@ TEST_F(EngineSyncTest, MomentarySyncDependsOnPlayingStates) { pButtonSyncEnabled1->set(1.0); pButtonSyncEnabled1->set(0.0); ProcessBuffer(); - assertNoMaster(); + assertNoLeader(); assertSyncOff(m_sGroup1); assertSyncOff(m_sGroup2); EXPECT_DOUBLE_EQ( @@ -1292,7 +1292,7 @@ TEST_F(EngineSyncTest, MomentarySyncDependsOnPlayingStates) { pButtonSyncEnabled1->set(1.0); pButtonSyncEnabled1->set(0.0); ProcessBuffer(); - assertNoMaster(); + assertNoLeader(); assertSyncOff(m_sGroup1); assertSyncOff(m_sGroup2); EXPECT_DOUBLE_EQ( @@ -1313,7 +1313,7 @@ TEST_F(EngineSyncTest, EjectTrackSyncRemains) { // m_sGroup1 takes over EXPECT_TRUE(isFollower(m_sInternalClockGroup)); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); assertSyncOff(m_sGroup2); pButtonEject1->set(1.0); @@ -1337,7 +1337,7 @@ TEST_F(EngineSyncTest, EjectTrackSyncRemains) { ProcessBuffer(); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); pButtonEject1->set(1.0); @@ -1346,11 +1346,11 @@ TEST_F(EngineSyncTest, EjectTrackSyncRemains) { EXPECT_TRUE(isFollower(m_sInternalClockGroup)); EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isSoftMaster(m_sGroup2)); + EXPECT_TRUE(isSoftLeader(m_sGroup2)); } -TEST_F(EngineSyncTest, FileBpmChangesDontAffectMaster) { - // If filebpm changes, don't treat it like a rate change unless it's the master. +TEST_F(EngineSyncTest, FileBpmChangesDontAffectLeader) { + // If filebpm changes, don't treat it like a rate change unless it's the leader. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 100, 0.0); m_pTrack1->trySetBeats(pBeats1); auto pButtonSyncEnabled1 = @@ -1365,16 +1365,16 @@ TEST_F(EngineSyncTest, FileBpmChangesDontAffectMaster) { pButtonSyncEnabled2->set(1.0); ProcessBuffer(); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); - // Update the master's beats -- update the internal clock + // Update the leader's beats -- update the internal clock pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 160, 0.0); m_pTrack1->trySetBeats(pBeats1); EXPECT_DOUBLE_EQ( 160.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); // Update follower beats -- don't update internal clock. pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 140, 0.0); @@ -1383,12 +1383,12 @@ TEST_F(EngineSyncTest, FileBpmChangesDontAffectMaster) { 160.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); } -TEST_F(EngineSyncTest, ExplicitMasterPostProcessed) { - // Regression test thanks to a bug. Make sure that an explicit master +TEST_F(EngineSyncTest, ExplicitLeaderPostProcessed) { + // Regression test thanks to a bug. Make sure that an explicit leader // channel gets post-processed. - auto pButtonMasterSync1 = + auto pButtonLeaderSync1 = std::make_unique(m_sGroup1, "sync_mode"); - pButtonMasterSync1->slotSet(SYNC_MASTER_EXPLICIT); + pButtonLeaderSync1->slotSet(SYNC_LEADER_EXPLICIT); mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 160, 0.0); m_pTrack1->trySetBeats(pBeats1); ProcessBuffer(); @@ -1425,10 +1425,10 @@ TEST_F(EngineSyncTest, ZeroBPMRateAdjustIgnored) { EXPECT_DOUBLE_EQ(getRateSliderValue(1.0), ControlObject::getControl(ConfigKey(m_sGroup2, "rate"))->get()); - // Also try with explicit master/follower setting + // Also try with explicit leader/follower setting pButtonSyncEnabled1->set(0.0); ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) - ->set(SYNC_MASTER_EXPLICIT); + ->set(SYNC_LEADER_EXPLICIT); ControlObject::getControl(ConfigKey(m_sGroup1, "rate")) ->set(getRateSliderValue(1.4)); @@ -1454,7 +1454,7 @@ TEST_F(EngineSyncTest, DISABLED_BeatDistanceBeforeStart) { m_pTrack1->trySetBeats(pBeats1); ControlObject::set(ConfigKey(m_sGroup1, "playposition"), -.05); ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) - ->set(SYNC_MASTER_SOFT); + ->set(SYNC_LEADER_SOFT); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); ProcessBuffer(); EXPECT_NEAR( @@ -1464,14 +1464,14 @@ TEST_F(EngineSyncTest, DISABLED_BeatDistanceBeforeStart) { } TEST_F(EngineSyncTest, ZeroLatencyRateChangeNoQuant) { - // Confirm that a rate change in an explicit master is instantly communicated + // Confirm that a rate change in an explicit leader is instantly communicated // to followers. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 128, 0.0); m_pTrack1->trySetBeats(pBeats1); mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 160, 0.0); m_pTrack2->trySetBeats(pBeats2); - // Make Channel2 master to weed out any channel ordering issues. + // Make Channel2 leader to weed out any channel ordering issues. ControlObject::getControl(ConfigKey(m_sGroup2, "sync_mode")) ->set(SYNC_FOLLOWER); ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) @@ -1512,7 +1512,7 @@ TEST_F(EngineSyncTest, ZeroLatencyRateChangeNoQuant) { } TEST_F(EngineSyncTest, ZeroLatencyRateChangeQuant) { - // Confirm that a rate change in an explicit master is instantly communicated + // Confirm that a rate change in an explicit leader is instantly communicated // to followers. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 128, 0.0); m_pTrack1->trySetBeats(pBeats1); @@ -1522,7 +1522,7 @@ TEST_F(EngineSyncTest, ZeroLatencyRateChangeQuant) { ControlObject::getControl(ConfigKey(m_sGroup1, "quantize"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0); - // Make Channel2 master to weed out any channel ordering issues. + // Make Channel2 leader to weed out any channel ordering issues. ControlObject::getControl(ConfigKey(m_sGroup2, "sync_mode")) ->set(SYNC_FOLLOWER); ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) @@ -1565,7 +1565,7 @@ TEST_F(EngineSyncTest, ZeroLatencyRateChangeQuant) { } TEST_F(EngineSyncTest, ZeroLatencyRateDiffQuant) { - // Confirm that a rate change in an explicit master is instantly communicated + // Confirm that a rate change in an explicit leader is instantly communicated // to followers. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 128, 0.0); m_pTrack1->trySetBeats(pBeats1); @@ -1574,7 +1574,7 @@ TEST_F(EngineSyncTest, ZeroLatencyRateDiffQuant) { ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0); - // Make Channel2 master to weed out any channel ordering issues. + // Make Channel2 leader to weed out any channel ordering issues. ControlObject::getControl(ConfigKey(m_sGroup2, "sync_mode")) ->set(SYNC_FOLLOWER); ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) @@ -1616,7 +1616,7 @@ TEST_F(EngineSyncTest, ZeroLatencyRateDiffQuant) { kMaxBeatDistanceEpsilon); } -// In this test, we set play *first* and then turn on master sync. +// In this test, we set play *first* and then turn on sync lock. // This exercises a slightly different ordering of signals that we // need to check. The Sync feature is unfortunately brittle. // This test exercises https://bugs.launchpad.net/mixxx/+bug/1884324 @@ -1640,11 +1640,11 @@ TEST_F(EngineSyncTest, ActivatingSyncDoesNotCauseDrifting) { ControlObject::getControl(ConfigKey(m_sGroup1, "beat_distance")) ->get()); - // engage first sync-master + // engage first sync-leader ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) ->set(SYNC_FOLLOWER); - // engage second Sync-master + // engage second Sync-leader ControlObject::getControl(ConfigKey(m_sGroup2, "sync_mode")) ->set(SYNC_FOLLOWER); @@ -1670,7 +1670,7 @@ TEST_F(EngineSyncTest, HalfDoubleBpmTest) { mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 140, 0.0); m_pTrack2->trySetBeats(pBeats2); - // Mixxx will choose the first playing deck to be master. Let's start deck 2 first. + // Mixxx will choose the first playing deck to be leader. Let's start deck 2 first. ControlObject::getControl(ConfigKey(m_sGroup1, "volume"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "volume"))->set(1.0); ProcessBuffer(); @@ -1683,15 +1683,15 @@ TEST_F(EngineSyncTest, HalfDoubleBpmTest) { ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); ProcessBuffer(); - ASSERT_TRUE(isSoftMaster(m_sGroup2)); + ASSERT_TRUE(isSoftLeader(m_sGroup2)); ASSERT_TRUE(isFollower(m_sGroup1)); EXPECT_EQ(0.5, m_pChannel1->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); EXPECT_EQ(1.0, m_pChannel2->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); EXPECT_DOUBLE_EQ( m_pChannel1->getEngineBuffer()->m_pSyncControl->getBeatDistance(), m_pChannel2->getEngineBuffer()->m_pSyncControl->getBeatDistance()); @@ -1721,10 +1721,10 @@ TEST_F(EngineSyncTest, HalfDoubleBpmTest) { EXPECT_EQ(1.0, m_pChannel1->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); EXPECT_EQ(1.0, m_pChannel2->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode")) ->set(SYNC_FOLLOWER); @@ -1741,10 +1741,10 @@ TEST_F(EngineSyncTest, HalfDoubleBpmTest) { EXPECT_EQ(1.0, m_pChannel1->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); EXPECT_EQ(2.0, m_pChannel2->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); // Exaggerate the effect with a high rate. ControlObject::getControl(ConfigKey(m_sGroup2, "rate")) @@ -1780,16 +1780,16 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) { ControlObject::getControl(ConfigKey(m_sGroup1, "quantize"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0); - // We expect that m_sGroup1 has adjusted its own bpm to the second deck and becomes a single master. + // We expect that m_sGroup1 has adjusted its own bpm to the second deck and becomes a single leader. // The internal clock is initialized right away. - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); EXPECT_DOUBLE_EQ(1.0, m_pChannel1->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); EXPECT_DOUBLE_EQ(2.0, m_pChannel2->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); EXPECT_DOUBLE_EQ(87.5, ControlObject::getControl(ConfigKey(m_sInternalClockGroup, "bpm")) ->get()); @@ -1839,12 +1839,12 @@ TEST_F(EngineSyncTest, HalfDoubleThenPlay) { ProcessBuffer(); pButtonSyncEnabled2->slotSet(1.0); pButtonSyncEnabled1->slotSet(1.0); - EXPECT_DOUBLE_EQ(1.0, + EXPECT_DOUBLE_EQ(0.5, m_pChannel1->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); EXPECT_DOUBLE_EQ(1.0, m_pChannel2->getEngineBuffer() - ->m_pSyncControl->m_masterBpmAdjustFactor); + ->m_pSyncControl->m_leaderBpmAdjustFactor); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); @@ -1892,7 +1892,7 @@ TEST_F(EngineSyncTest, HalfDoubleInternalClockTest) { ControlObject::getControl(ConfigKey(m_sGroup1, "quantize"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "quantize"))->set(1.0); - // Make Channel2 master to weed out any channel ordering issues. + // Make Channel2 leader to weed out any channel ordering issues. ControlObject::getControl(ConfigKey(m_sGroup1, "sync_enabled"))->set(1); ControlObject::getControl(ConfigKey(m_sGroup2, "sync_enabled"))->set(1); @@ -2029,7 +2029,7 @@ TEST_F(EngineSyncTest, SyncPhaseToPlayingNonSyncDeck) { m_pTrack2->trySetBeats(pBeats2); // Set the sync deck playing with nothing else active. - // Next Deck becomes master and the Master clock is set to 100 BPM + // Next Deck becomes leader and the Leader clock is set to 100 BPM // The 130 BPM Track should be played at 100 BPM, rate = 0.769230769 pButtonSyncEnabled1->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); @@ -2058,7 +2058,7 @@ TEST_F(EngineSyncTest, SyncPhaseToPlayingNonSyncDeck) { // we expect that Deck 1 distance has not changed but the internal clock keeps going, because // the internal clock should continue playing even if the leader is stopped. - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_NEAR(0.019349962, ControlObject::getControl(ConfigKey(m_sGroup1, "beat_distance"))->get(), kMaxFloatingPointErrorLowPrecision); @@ -2077,7 +2077,7 @@ TEST_F(EngineSyncTest, SyncPhaseToPlayingNonSyncDeck) { // The first deck is still the only one with sync active. // TODO: It does sounds odd to start the track 1 at a random position and adjust the // phase later. Seeking into phase is the best option even with quantize off. - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_DOUBLE_EQ(100.0, ControlObject::getControl(ConfigKey(m_sGroup1, "bpm"))->get()); // The adjustment is calculated here: BpmControl::calcSyncAdjustment @@ -2112,7 +2112,7 @@ TEST_F(EngineSyncTest, SyncPhaseToPlayingNonSyncDeck) { m_pTrack3->trySetBeats(pBeats3); // This will sync to the first deck here and not the second (lp1784185) pButtonSyncEnabled3->set(1.0); - EXPECT_TRUE(isSoftMaster(m_sGroup3)); + EXPECT_TRUE(isSoftLeader(m_sGroup3)); ProcessBuffer(); EXPECT_DOUBLE_EQ(130.0, ControlObject::get(ConfigKey(m_sGroup3, "bpm"))); // revert that @@ -2123,9 +2123,9 @@ TEST_F(EngineSyncTest, SyncPhaseToPlayingNonSyncDeck) { pButtonSyncEnabled1->set(1.0); ProcessBuffer(); - // Soft master is now deck one because that was the last one we enabled and none of them + // Soft leader is now deck one because that was the last one we enabled and none of them // are playing. - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); ControlObject::getControl(ConfigKey(m_sGroup3, "play"))->set(1.0); ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(1.0); @@ -2151,7 +2151,7 @@ TEST_F(EngineSyncTest, SyncPhaseToPlayingNonSyncDeck) { TEST_F(EngineSyncTest, UserTweakBeatDistance) { // If a deck has a user tweak, and another deck stops such that the first - // is used to reseed the master beat distance, make sure the user offset + // is used to reseed the leader beat distance, make sure the user offset // is reset. mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 128, 0.0); m_pTrack1->trySetBeats(pBeats1); @@ -2182,7 +2182,7 @@ TEST_F(EngineSyncTest, UserTweakBeatDistance) { ProcessBuffer(); } - // Stop the second deck. This causes the master beat distance to get + // Stop the second deck. This causes the leader beat distance to get // seeded with the beat distance from deck 1. ControlObject::getControl(ConfigKey(m_sGroup2, "play"))->set(0.0); @@ -2202,7 +2202,7 @@ TEST_F(EngineSyncTest, UserTweakBeatDistance) { } TEST_F(EngineSyncTest, UserTweakPreservedInSeek) { - // Ensure that when we do a seek during master sync, the user offset is maintained. + // Ensure that when we do a seek during sync lock, the user offset is maintained. // This is about 128 bpm, but results in nice round numbers of samples. const double kDivisibleBpm = 44100.0 / 344.0; @@ -2280,9 +2280,9 @@ TEST_F(EngineSyncTest, UserTweakPreservedInSeek) { kMaxFloatingPointErrorLowPrecision); } -TEST_F(EngineSyncTest, FollowerUserTweakPreservedInMasterChange) { - // Ensure that when the master deck changes, the user offset is accounted for when - // reinitializing the master parameters.. +TEST_F(EngineSyncTest, FollowerUserTweakPreservedInLeaderChange) { + // Ensure that when the leader deck changes, the user offset is accounted for when + // reinitializing the leader parameters.. // This is about 128 bpm, but results in nice round numbers of samples. const double kDivisibleBpm = 44100.0 / 344.0; @@ -2292,7 +2292,7 @@ TEST_F(EngineSyncTest, FollowerUserTweakPreservedInMasterChange) { mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 130, 0.0); m_pTrack2->trySetBeats(pBeats2); - ControlObject::getControl(ConfigKey(m_sGroup1, "sync_master"))->set(1); + ControlObject::getControl(ConfigKey(m_sGroup1, "sync_leader"))->set(1); ControlObject::getControl(ConfigKey(m_sGroup2, "sync_enabled"))->set(1); ControlObject::set(ConfigKey(m_sGroup1, "quantize"), 1.0); ControlObject::set(ConfigKey(m_sGroup2, "quantize"), 1.0); @@ -2302,7 +2302,7 @@ TEST_F(EngineSyncTest, FollowerUserTweakPreservedInMasterChange) { ControlObject::set(ConfigKey(m_sGroup1, "play"), 1.0); ControlObject::set(ConfigKey(m_sGroup2, "play"), 1.0); - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); ProcessBuffer(); @@ -2318,11 +2318,11 @@ TEST_F(EngineSyncTest, FollowerUserTweakPreservedInMasterChange) { kMaxFloatingPointErrorLowPrecision); } - // Switch master - ControlObject::getControl(ConfigKey(m_sGroup2, "sync_master"))->set(1); + // Switch leader + ControlObject::getControl(ConfigKey(m_sGroup2, "sync_leader"))->set(1); ProcessBuffer(); EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isExplicitMaster(m_sGroup2)); + EXPECT_TRUE(isExplicitLeader(m_sGroup2)); for (int i = 0; i < 10; ++i) { ProcessBuffer(); @@ -2332,9 +2332,9 @@ TEST_F(EngineSyncTest, FollowerUserTweakPreservedInMasterChange) { } } -TEST_F(EngineSyncTest, MasterUserTweakPreservedInMasterChange) { - // Ensure that when the master deck changes, the user offset is accounted for when - // reinitializing the master parameters.. +TEST_F(EngineSyncTest, LeaderUserTweakPreservedInLeaderChange) { + // Ensure that when the leader deck changes, the user offset is accounted for when + // reinitializing the leader parameters.. // This is about 128 bpm, but results in nice round numbers of samples. const double kDivisibleBpm = 44100.0 / 344.0; @@ -2344,14 +2344,14 @@ TEST_F(EngineSyncTest, MasterUserTweakPreservedInMasterChange) { mixxx::BeatsPointer pBeats2 = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 130, 0.0); m_pTrack2->trySetBeats(pBeats2); - ControlObject::getControl(ConfigKey(m_sGroup1, "sync_master"))->set(1); + ControlObject::getControl(ConfigKey(m_sGroup1, "sync_leader"))->set(1); ControlObject::getControl(ConfigKey(m_sGroup2, "sync_enabled"))->set(1); ControlObject::set(ConfigKey(m_sGroup1, "quantize"), 1.0); ControlObject::set(ConfigKey(m_sGroup2, "quantize"), 1.0); ControlObject::set(ConfigKey(m_sGroup1, "play"), 1.0); ControlObject::set(ConfigKey(m_sGroup2, "play"), 1.0); - EXPECT_TRUE(isExplicitMaster(m_sGroup1)); + EXPECT_TRUE(isExplicitLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); ProcessBuffer(); @@ -2360,7 +2360,7 @@ TEST_F(EngineSyncTest, MasterUserTweakPreservedInMasterChange) { EXPECT_DOUBLE_EQ(kDivisibleBpm, ControlObject::getControl(ConfigKey(m_sGroup2, "bpm"))->get()); - // Apply user tweak offset to master -- to test the bug we found, we need + // Apply user tweak offset to leader -- to test the bug we found, we need // to apply it indirectly. ControlObject::set(ConfigKey(m_sGroup1, "rate_temp_up"), 1); for (int i = 0; i < 5; ++i) { @@ -2371,11 +2371,11 @@ TEST_F(EngineSyncTest, MasterUserTweakPreservedInMasterChange) { } ControlObject::set(ConfigKey(m_sGroup1, "rate_temp_up"), 0); - // Switch master - ControlObject::getControl(ConfigKey(m_sGroup2, "sync_master"))->set(1); + // Switch leader + ControlObject::getControl(ConfigKey(m_sGroup2, "sync_leader"))->set(1); ProcessBuffer(); EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isExplicitMaster(m_sGroup2)); + EXPECT_TRUE(isExplicitLeader(m_sGroup2)); for (int i = 0; i < 10; ++i) { ProcessBuffer(); @@ -2385,7 +2385,7 @@ TEST_F(EngineSyncTest, MasterUserTweakPreservedInMasterChange) { } } -TEST_F(EngineSyncTest, MasterBpmNeverZero) { +TEST_F(EngineSyncTest, LeaderBpmNeverZero) { mixxx::BeatsPointer pBeats1 = BeatFactory::makeBeatGrid(m_pTrack1->getSampleRate(), 128, 0.0); m_pTrack1->trySetBeats(pBeats1); @@ -2650,7 +2650,7 @@ TEST_F(EngineSyncTest, ChangeBeatGrid) { ProcessBuffer(); - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_DOUBLE_EQ(130.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); EXPECT_DOUBLE_EQ(130.0, ControlObject::get(ConfigKey(m_sInternalClockGroup, "bpm"))); @@ -2661,7 +2661,7 @@ TEST_F(EngineSyncTest, ChangeBeatGrid) { ProcessBuffer(); // expect no change in Deck 1 - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); EXPECT_DOUBLE_EQ(130.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); EXPECT_DOUBLE_EQ(0, ControlObject::get(ConfigKey(m_sGroup2, "bpm"))); @@ -2671,8 +2671,8 @@ TEST_F(EngineSyncTest, ChangeBeatGrid) { ControlObject::set(ConfigKey(m_sGroup1, "play"), 0.0); ProcessBuffer(); - // Group1 remains master because it is the only one with a tempo. - EXPECT_TRUE(isSoftMaster(m_sGroup1)); + // Group1 remains leader because it is the only one with a tempo. + EXPECT_TRUE(isSoftLeader(m_sGroup1)); EXPECT_TRUE(isFollower(m_sGroup2)); // Load a new beatgrid during playing, this happens when the analyser is finished. @@ -2682,9 +2682,9 @@ TEST_F(EngineSyncTest, ChangeBeatGrid) { ProcessBuffer(); // Since deck 1 is not playing, deck 2 doesn't change its speed to match theirs. Deck 2 - // should be master now, and playing at our own rate. The other deck should have + // should be leader now, and playing at our own rate. The other deck should have // changed rate to match us. - EXPECT_TRUE(isSoftMaster(m_sGroup2)); + EXPECT_TRUE(isSoftLeader(m_sGroup2)); EXPECT_TRUE(isFollower(m_sGroup1)); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); EXPECT_DOUBLE_EQ(140.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); @@ -2697,7 +2697,7 @@ TEST_F(EngineSyncTest, ChangeBeatGrid) { EXPECT_TRUE(isFollower(m_sInternalClockGroup)); EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isSoftMaster(m_sGroup2)); + EXPECT_TRUE(isSoftLeader(m_sGroup2)); // Load a new beatgrid again, this happens when the user adjusts the beatgrid mixxx::BeatsPointer pBeats2n = BeatFactory::makeBeatGrid(m_pTrack2->getSampleRate(), 75, 0.0); @@ -2705,7 +2705,7 @@ TEST_F(EngineSyncTest, ChangeBeatGrid) { ProcessBuffer(); - // We expect that the second deck is still playing at unity -- it was the master + // We expect that the second deck is still playing at unity -- it was the leader // and it should not change speed just because it reloaded and the bpm changed. EXPECT_DOUBLE_EQ(75.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); // Expect to sync on half beats @@ -2730,7 +2730,7 @@ TEST_F(EngineSyncTest, BeatMapQuantizePlay) { ControlObject::set(ConfigKey(m_sGroup1, "quantize"), 1.0); ControlObject::set(ConfigKey(m_sGroup2, "quantize"), 1.0); - ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode"))->set(SYNC_MASTER_EXPLICIT); + ControlObject::getControl(ConfigKey(m_sGroup1, "sync_mode"))->set(SYNC_LEADER_EXPLICIT); ControlObject::getControl(ConfigKey(m_sGroup2, "sync_mode"))->set(SYNC_FOLLOWER); ControlObject::getControl(ConfigKey(m_sGroup1, "play"))->set(1.0); @@ -2765,17 +2765,17 @@ TEST_F(EngineSyncTest, BpmAdjustFactor) { ControlObject::set(ConfigKey(m_sGroup2, "sync_enabled"), 1.0); ProcessBuffer(); - // group 2 should be synced to the first playing deck and becomes master + // group 2 should be synced to the first playing deck and becomes leader EXPECT_DOUBLE_EQ(40.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); EXPECT_DOUBLE_EQ(80.0, ControlObject::get(ConfigKey(m_sGroup2, "bpm"))); - EXPECT_TRUE(isSoftMaster(m_sGroup2)); + EXPECT_TRUE(isSoftLeader(m_sGroup2)); assertSyncOff(m_sGroup1); ControlObject::set(ConfigKey(m_sGroup2, "play"), 1.0); ProcessBuffer(); - EXPECT_TRUE(isSoftMaster(m_sGroup2)); + EXPECT_TRUE(isSoftLeader(m_sGroup2)); // Pretend a changing beatgrid - static_cast(m_pEngineSync->getMasterSyncable())->setLocalBpm(152); + static_cast(m_pEngineSync->getLeaderSyncable())->setLocalBpm(152); ProcessBuffer(); ControlObject::set(ConfigKey(m_sGroup1, "sync_enabled"), 1.0); @@ -2786,11 +2786,11 @@ TEST_F(EngineSyncTest, BpmAdjustFactor) { EXPECT_DOUBLE_EQ(40.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); EXPECT_DOUBLE_EQ(80.0, ControlObject::get(ConfigKey(m_sGroup2, "bpm"))); EXPECT_TRUE(isFollower(m_sGroup1)); - EXPECT_TRUE(isSoftMaster(m_sGroup2)); + EXPECT_TRUE(isSoftLeader(m_sGroup2)); EXPECT_TRUE(isFollower(m_sInternalClockGroup)); } -TEST_F(EngineSyncTest, ImplicitMasterToInternalClock) { +TEST_F(EngineSyncTest, ImplicitLeaderToInternalClock) { m_pMixerDeck1->loadFakeTrack(false, 100.0); m_pMixerDeck2->loadFakeTrack(false, 125.0); ProcessBuffer(); @@ -2808,26 +2808,26 @@ TEST_F(EngineSyncTest, ImplicitMasterToInternalClock) { ControlObject::set(ConfigKey(m_sGroup2, "sync_enabled"), 1.0); ProcessBuffer(); - // group 2 should be synced to the first playing deck and becomes master + // group 2 should be synced to the first playing deck and becomes leader EXPECT_DOUBLE_EQ(125.0, ControlObject::get(ConfigKey(m_sGroup1, "bpm"))); EXPECT_DOUBLE_EQ(125.0, ControlObject::get(ConfigKey(m_sGroup2, "bpm"))); - ASSERT_FALSE(isSoftMaster(m_sGroup1)); - ASSERT_TRUE(isSoftMaster(m_sGroup2)); - ASSERT_FALSE(isSoftMaster(m_sInternalClockGroup)); + ASSERT_FALSE(isSoftLeader(m_sGroup1)); + ASSERT_TRUE(isSoftLeader(m_sGroup2)); + ASSERT_FALSE(isSoftLeader(m_sInternalClockGroup)); ProcessBuffer(); // Drop Track, no change ControlObject::set(ConfigKey(m_sGroup1, "volume"), 1.0); - ASSERT_FALSE(isSoftMaster(m_sGroup1)); - ASSERT_TRUE(isSoftMaster(m_sGroup2)); - ASSERT_FALSE(isSoftMaster(m_sInternalClockGroup)); + ASSERT_FALSE(isSoftLeader(m_sGroup1)); + ASSERT_TRUE(isSoftLeader(m_sGroup2)); + ASSERT_FALSE(isSoftLeader(m_sInternalClockGroup)); - // Other track stops, master switches to deck 1 + // Other track stops, leader switches to deck 1 ControlObject::set(ConfigKey(m_sGroup2, "volume"), 0.0); ProcessBuffer(); ProcessBuffer(); - ASSERT_TRUE(isSoftMaster(m_sGroup1)); - ASSERT_FALSE(isSoftMaster(m_sGroup2)); - ASSERT_FALSE(isSoftMaster(m_sInternalClockGroup)); + ASSERT_TRUE(isSoftLeader(m_sGroup1)); + ASSERT_FALSE(isSoftLeader(m_sGroup2)); + ASSERT_FALSE(isSoftLeader(m_sInternalClockGroup)); } diff --git a/src/test/synccontroltest.cpp b/src/test/synccontroltest.cpp index 9e9e8a159bf5..6e647e57d147 100644 --- a/src/test/synccontroltest.cpp +++ b/src/test/synccontroltest.cpp @@ -1,4 +1,4 @@ -// Tests for Master Sync. +// Tests for Sync Lock. // There are no tests for actual deck playback, since I don't know how to mock that out yet. // The following manual tests should probably be performed: // * Quantize mode nudges tracks in sync, whether internal or deck master.