Skip to content

Implement switchable time format for decks#1652

Closed
poelzi wants to merge 5 commits intomixxxdj:masterfrom
poelzi:feature/seconds
Closed

Implement switchable time format for decks#1652
poelzi wants to merge 5 commits intomixxxdj:masterfrom
poelzi:feature/seconds

Conversation

@poelzi
Copy link
Copy Markdown
Contributor

@poelzi poelzi commented Apr 26, 2018

The display format on the decks can now be configured.
Implement first alternative display based on kiloseconds.

If you mixx tracks based on first and last downbeat, it is unnecessary complicated to use minutes. The first alternative display shows "k.sss:zzz" following roughly the idea of the kilosecond so it can be much easier calculated when the next track should be started.

The display format on the decks can now be configured.
Implement alternative display based on kiloseconds.
@daschuer
Copy link
Copy Markdown
Member

Thank you, nice Idea. Can you file a bug for this, than we can track this feature for a change log.

@poelzi
Copy link
Copy Markdown
Contributor Author

poelzi commented Apr 26, 2018

tracking bug: https://bugs.launchpad.net/mixxx/+bug/1767179

Comment thread src/preferences/dialog/dlgprefdeck.cpp Outdated
comboBoxTimeFormat->clear();
comboBoxTimeFormat->addItem(tr("hh:mm:ss.zzz"),
static_cast<int>(TrackTime::DisplayFormat::DEFAULT));
comboBoxTimeFormat->addItem(tr("k.sss:zz"),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need here access QLocale::decimalPoint() and QLocale::groupSeparator().
I wonder if the colon matches a official time format for ks. Or should we use plain seconds instead like US k,sss.zz or German k.sss,zz?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or plain ks like use k.ssszz Or "k.sss zz" with space as group separator as defined in the SI system

https://en.wikipedia.org/wiki/Decimal_separator#Digit_grouping

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the decimal point as it makes longer tracks easier to read. "k.sss zz" sounds good for me, too.
Should the separator then be localized then ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm I have just checked, currently I have the 00:00.00 format even in German. Now I can remember that we have discussed it before to use 00:00,00 for us, but this looks unusual, because all hardware devices have the dot, even though it would be correct.

When reading your PR I was stumbeling over "k.sss:zzz", just because is somehow ambiguous in this case.

7.332:84 Colon
7,332 84 Space
7,332 84 Punctuation Space
7,332 84 Thin Space
7,332 84 Hair Space

I think I prefer for now the localized thin Space version as recommended by SI-System.

Comment thread src/preferences/dialog/dlgprefdeck.cpp Outdated

// Track Display model
comboBoxTimeFormat->clear();
comboBoxTimeFormat->addItem(tr("hh:mm:ss.zzz"),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we also need to insert the QLocale::decimalPoint()

Comment thread src/preferences/dialog/dlgprefdeck.cpp Outdated
static_cast<int>(TrackTime::DisplayFormat::KILO_SECOND));
connect(comboBoxTimeFormat, SIGNAL(activated(int)),
this, SLOT(slotTimeFormatChanged(int)));
slotTimeFormatChanged((double)m_pConfig->getValue(ConfigKey("[Controls]", "TimeFormat"),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use static_cast, but I think you can omit it in this case

Comment thread src/preferences/dialog/dlgprefdeck.cpp Outdated
m_pConfig->set(ConfigKey("[Controls]","TimeFormat"), ConfigValue(v));
comboBoxTimeFormat->setCurrentIndex(
comboBoxTimeFormat->findData(i));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra new line

Comment thread src/preferences/dialog/dlgprefdeck.cpp Outdated

void DlgPrefDeck::slotTimeFormatChanged(int index) {
int mode = comboBoxTimeFormat->itemData(index).toInt();
m_timeDisplayFormat = static_cast<TrackTime::DisplayFormat>(mode);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can omit the m_timeDisplayFormat here and read the comboBoxTimeFormat directly

}

void DlgPrefDeck::slotApply() {
double timeDisplay = static_cast<double>(m_timeDisplayMode);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can get also rid of m_timeDisplayMode

Comment thread src/preferences/dialog/dlgprefdeck.cpp Outdated

}

void DlgPrefDeck::slotTimeFormatChanged(int index) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should get rid of this. It is anyway confusing to have this function twice as int and double overload.

Comment thread src/preferences/dialog/dlgprefdeck.h Outdated
ElapsedAndRemaining,
};
enum class DisplayFormat {
DEFAULT,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEFAULT is meaningless here. How about WALL_CLOCK or HOUR_MINUTES_SECONDS or TRADITIONAL

Comment thread src/util/duration.cpp Outdated

QString durationString =
(days > 0 ? (QString::number(days) %
QLatin1String("d, ")) : QString()) %
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to deal with days? Can't we just count seconds?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just took the logic of the normal formatting here. I don't think tracks over a 1 day are so common ;)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we schould remove the day part entirely. No track will have this length, and if there is what we have unlikely the screen space for this.
I personally would prefer to see
30:10:01,86 instead of 1d,6:10:01,86

Comment thread src/util/duration.cpp
QString durationString =
(days > 0 ? (QString::number(days) %
QLatin1String("d, ")) : QString()) %
QString("%1.%2").arg(kilos, 0, 10).arg(seconds, 3, 'f', 0, QLatin1Char('0'));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QLocale::toString() can already do this in the correct format.

@daschuer daschuer added this to the 2.2.0 milestone Apr 26, 2018
Fix comments regarding style.
Also add hectosecond formatting. For mixing, 100 seconds is actually a quite useful
seperator.
@poelzi
Copy link
Copy Markdown
Contributor Author

poelzi commented May 5, 2018

I tried localizing the time format and the results where terrible. In fact, we don't localize the time at all nor do I think we should. Nobody complained about the old format being not localized and I think it should be presented in the best readable way. Which it is for normal time format.

I tried different options for the kilo second and new hecto second displays. The period combined with the small space look the best. The german "," looks super strange. In fact, I found the hecto second display quite appealing. Most tracks are in the 5-10 minute range. 100 seconds are a good marker for the track end, so the first diget after the separator is the important one.

Comment thread src/util/duration.cpp Outdated
} // namespace

// static
QString DurationBase::kCentisecondSeperator = QString::fromUtf8("\u2009");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires a comment.
// Unicode for THIN SPACE

I am also a bit confused why it works. The UTF8 character is 0xe28089
"\u2009" should be already UTF-16, the internal codec of QString. Does the compiler turns it into utf8 and than fromUtf8 back at rune time?
Did you try QChar(0x2009); ?

@daschuer
Copy link
Copy Markdown
Member

daschuer commented May 5, 2018

It works nice. Should the library column also follow the settings?
I cannot really deal with the hectosecond format. The dot for 100 s is useless for me. It is no problem at all, because it is just an option, but why not replace it by, or add a plain seconds format?

@daschuer
Copy link
Copy Markdown
Member

daschuer commented May 6, 2018

A Beats time format or better bars, if we have it one day would also be a nice benefit.
I have never worked with that, but I can't count seconds if a 130 bpm beat is hammering in the same time.

@poelzi
Copy link
Copy Markdown
Contributor Author

poelzi commented May 15, 2018

Ready for review. Beats counter sounds interesting.

Copy link
Copy Markdown
Contributor

@Be-ing Be-ing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. LGTM other than a few places where the VERFIY_OR_DEBUG_ASSERT macro could be used. @daschuer any last comments?

Comment thread src/util/duration.cpp
}

QString DurationBase::formatSeconds(double dSeconds, Precision precision) {
if (dSeconds < 0.0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use VERIFY_OR_DEBUG_ASSERT macro

Comment thread src/util/duration.cpp

// static
QString DurationBase::formatKiloSeconds(double dSeconds, Precision precision) {
if (dSeconds < 0.0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use VERIFY_OR_DEBUG_ASSERT macro

Comment thread src/util/duration.cpp

// static
QString DurationBase::formatHectoSeconds(double dSeconds, Precision precision) {
if (dSeconds < 0.0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use VERIFY_OR_DEBUG_ASSERT macro

Comment thread src/util/duration.cpp

// static
QString DurationBase::formatTime(double dSeconds, Precision precision) {
if (dSeconds < 0.0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use VERIFY_OR_DEBUG_ASSERT macro

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Be-ing when I replace these I get Critical [Main]: DEBUG ASSERT: "dSeconds < 0.0" in function static QString mixxx::DurationBase::formatTime(double, mixxx::DurationBase::Precision) at src/util/duration.cpp:26 when I attempt to run. Any ideas?

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented Jun 27, 2018

Ping @poelzi. Could you make the small edits mentioned above? I'd like to merge this by Saturday for 2.2.

@Be-ing Be-ing modified the milestones: 2.2.0, 2.3.0 Sep 11, 2018
@benis
Copy link
Copy Markdown
Contributor

benis commented Oct 2, 2018

@poelzi would you be happy for somebody else to pick this up and finish it off?

@benis
Copy link
Copy Markdown
Contributor

benis commented Oct 7, 2018

@Be-ing I was going to pick this up and submit a new PR. The VERIFY_OR_DEBUG_ASSERT macro, is it just a case of replacing the instances of 'if' with that? Or do I need to add in a qDebug statement somewhere.

@Be-ing
Copy link
Copy Markdown
Contributor

Be-ing commented Oct 7, 2018

Printing with qDebug is redundant with the VERIFY_OR_DEBUG_ASSERT macro. That macro will print a warning to the log if the condition is false. In these cases, yes, simply replacing the if statements with VERIFY_OR_DEBUG_ASSERT is sufficient because the if statements already handle what to do in case of an error.

@benis
Copy link
Copy Markdown
Contributor

benis commented Oct 8, 2018

I can't get this to build. I get a dozen or so errors, none of which seem related (at least not directly) to the files that were changed:

src/library/analysisfeature.cpp:72:5: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:74:5: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:76:5: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:78:5: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:81:5: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:84:5: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:86:5: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:142:9: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:146:9: error: no matching member function for call to 'connect'
src/library/analysisfeature.cpp:95:54: error: cannot initialize a parameter of type 'QWidget *' with an lvalue of type 'DlgAnalysis *'
src/library/dlganalysis.h:64:18: error: field has incomplete type 'QButtonGroup' (x3)

Any idea why that would happen? I completely cleaned beforehand including running rm -R config.log .sconsign.dblite .sconf_temp .sconsign.branch

@rryan
Copy link
Copy Markdown
Member

rryan commented Oct 9, 2018

@beenisss can you post the full compiler command and output for e.g. analysisfeature.o ?

@benis
Copy link
Copy Markdown
Contributor

benis commented Oct 9, 2018

Here you go, I think:

g++ -o osx64_build/library/analysisfeature.o -c -I/usr/local/include -I/usr/local/include/opus -std=c++11 -I/usr/local/include -I/usr/local/include/opus -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -mmacosx-version-min=10.8 -stdlib=libc++ -arch x86_64 -pipe -Wall -Wextra -g -F/usr/local/Cellar/qt/5.11.1/Frameworks -Dx86_64 -DMIXXX_BUILD_DEBUG -DSETTINGS_FILE=\"mixxx.cfg\" -DSOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS -D__PORTAUDIO__ -DQT_TABLET_SUPPORT -DQT_SHARED -DQT_DISABLE_DEPRECATED_BEFORE -DQT_CORE_LIB -DQT_GUI_LIB -DQT_OPENGL_LIB -DQT_XML_LIB -DQT_SVG_LIB -DQT_SQL_LIB -DQT_SCRIPT_LIB -DQT_NETWORK_LIB -DQT_WIDGETS_LIB -D__SNDFILE__ -DSFC_SUPPORTS_SET_COMPRESSION_LEVEL -D__COREAUDIO__ -D__HID__ -D__VINYLCONTROL__ -D__BROADCAST__ -D__OPUS__ -D__VAMP__ -Dkiss_fft_scalar=double -D__BATTERY__ -I/usr/local/include -Iosx64_build -Isrc -Ilib/soundtouch-2.0.0 -Ilib/replaygain -Ilib/libebur128/ebur128 -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtCore.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtGui.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtOpenGL.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtXml.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtSvg.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtSql.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtScript.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtNetwork.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtTest.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtScriptTools.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtWidgets.framework/Headers -I/usr/local/Cellar/qt/5.11.1/Frameworks/QtConcurrent.framework/Headers -Ilib/gtest-1.7.0/include -Ilib/fidlib -I/usr/include/taglib -I/System/Library/Frameworks/Security.framework/Headers -I/System/Library/Frameworks/CoreServices.framework/Headers -I/System/Library/Frameworks/IOKit.framework/Headers -Ilib/qtscript-bytearray -Ilib/reverb -Ilib/portaudio -Ilib/apple -Ilib/hidapi-0.8.0-rc1/hidapi -Ilib/xwax -Ilib/scratchlib -Ilib/vamp src/library/analysisfeature.cpp
4 warnings generated.
scons: *** [osx64_build/library/analysisfeature.o] Error 1
In file included from src/library/autodj/autodjprocessor.cpp:1:
In file included from src/library/autodj/autodjprocessor.h:11:
In file included from src/library/playlisttablemodel.h:4:
In file included from src/library/basesqltablemodel.h:10:
In file included from src/library/trackcollection.h:13:
src/library/dao/playlistdao.h:54:10: warning: 'initialize' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
    void initialize(const QSqlDatabase& database);
         ^
src/library/dao/dao.h:10:18: note: overridden virtual function is here
    virtual void initialize(const QSqlDatabase& database) = 0;
                 ^
In file included from src/library/autodj/autodjprocessor.cpp:1:
In file included from src/library/autodj/autodjprocessor.h:11:
In file included from src/library/playlisttablemodel.h:4:
In file included from src/library/basesqltablemodel.h:10:
In file included from src/library/trackcollection.h:16:
src/library/dao/libraryhashdao.h:15:10: warning: 'initialize' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
    void initialize(const QSqlDatabase& database) {
         ^
src/library/dao/dao.h:10:18: note: overridden virtual function is here
    virtual void initialize(const QSqlDatabase& database) = 0;
                 ^
In file included from src/library/autodj/autodjprocessor.cpp:1:
In file included from src/library/autodj/autodjprocessor.h:11:
In file included from src/library/playlisttablemodel.h:4:
src/library/basesqltablemodel.h:63:27: warning: 'flags' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
    virtual Qt::ItemFlags flags(const QModelIndex &index) const;
                          ^
/usr/local/Cellar/qt/5.11.1/Frameworks/QtCore.framework/Headers/qabstractitemmodel.h:395:19: note: overridden virtual function is here
    Qt::ItemFlags flags(const QModelIndex &index) const override;
                  ^
In file included from src/library/autodj/autodjprocessor.cpp:1:
In file included from src/library/autodj/autodjprocessor.h:11:
In file included from src/library/playlisttablemodel.h:4:
src/library/basesqltablemodel.h:86:10: warning: 'select' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
    void select();
         ^
src/library/trackmodel.h:146:18: note: overridden virtual function is here
    virtual void select() {
                 ^
17 warnings and 1 error generated.

Comment thread src/util/duration.cpp
#include <QStringBuilder>
#include <QTime>

#include <math.h>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by this addition. It has no path and the syntax doesn't match the other entries. Besides which, two lines below is the statement #include "util/math.h" - is that a different file?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"util/math.h" (in mixxx's codebase) is preferable to <math.h> (the C standard library header), since it includes Mixxx-specific helpers / shims.

@rryan
Copy link
Copy Markdown
Member

rryan commented Oct 13, 2018

Here you go, I think:

Those aren't the same errors you were seeing before?

@benis
Copy link
Copy Markdown
Contributor

benis commented Oct 13, 2018

I'm not sure what you mean, I think I've probably misunderstood what you asked for or have misled you with what I originally posted.

I'm currently working on reimplimenting this step by step and building as I go. I've noticed a couple of weird things in the updated code in the process of doing so, maybe once those are ironed out it'll work. I'm happy to post up anything that's useful for troubleshooting in the meantime though.

benis added a commit to benis/mixxx that referenced this pull request Oct 14, 2018
benis added a commit to benis/mixxx that referenced this pull request Oct 14, 2018
benis added a commit to benis/mixxx that referenced this pull request Oct 14, 2018
benis added a commit to benis/mixxx that referenced this pull request Oct 15, 2018
…pp, if > VERIFY_OR_DEBUG_ASSERT for duration.cpp
@benis
Copy link
Copy Markdown
Contributor

benis commented Oct 15, 2018

Well, I've applied the updates from this PR to a new branch manually with some changes that were minor and almost entirely cosmetic, and somehow it builds without issue.

¯\_(ツ)_/¯

benis added a commit to benis/mixxx that referenced this pull request Oct 15, 2018
@ronso0
Copy link
Copy Markdown
Member

ronso0 commented Nov 21, 2018

In my personal branch I've changed mixxx::Duration::Precision::CENTISECONDS to ...::SECONDS in /src/widget/wnumberpos.cpp to get rid of the rather distracting centiseconds.

Can we add another format hh:mm:ss and maybe call it "Traditional, coarse"?

@benis
Copy link
Copy Markdown
Contributor

benis commented Nov 22, 2018

@ronso0 I couldn't get this to build so I reimplemented it and have created a new PR at #1915 where I've copied your request.

There are a couple of things still need ironing out - feel free to get other people involved.

@benis
Copy link
Copy Markdown
Contributor

benis commented Nov 22, 2018

In light of the above I think this can be closed.

@poelzi
Copy link
Copy Markdown
Contributor Author

poelzi commented Nov 22, 2018

When I developed this, I tried different characters. I think I spent an hour trying different combinations for this not really usually formats. I chose those because after giving each version a try of 10 minutes or so, I found those ok. I'm quite open to some better ideas :)

@daschuer
Copy link
Copy Markdown
Member

I can build this branch merged to master. @benis What is your issue?

Appveyor is also able to build this. However some tests fails:
[ FAILED ] DurationUtilTest.FormatKiloSeconds
[ FAILED ] DurationUtilTest.FormatHectoSeconds

Travis has timed out.

daschuer pushed a commit to daschuer/mixxx that referenced this pull request Dec 29, 2018
daschuer pushed a commit to daschuer/mixxx that referenced this pull request Dec 29, 2018
daschuer pushed a commit to daschuer/mixxx that referenced this pull request Dec 29, 2018
benis added a commit to benis/mixxx that referenced this pull request Jan 6, 2019
benis added a commit to benis/mixxx that referenced this pull request Jan 6, 2019
benis added a commit to benis/mixxx that referenced this pull request Jan 6, 2019
benis added a commit to benis/mixxx that referenced this pull request Jan 6, 2019
benis added a commit to benis/mixxx that referenced this pull request Jan 6, 2019
daschuer pushed a commit to daschuer/mixxx that referenced this pull request Jan 6, 2019
daschuer pushed a commit to daschuer/mixxx that referenced this pull request Jan 6, 2019
@daschuer
Copy link
Copy Markdown
Member

daschuer commented Jan 6, 2019

closed in favor of #1985

@daschuer daschuer closed this Jan 6, 2019
daschuer added a commit that referenced this pull request Jan 27, 2019
Reimplement #1652 - switchable time formats
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants