diff --git a/src/apps/mediaplayer/Jamfile b/src/apps/mediaplayer/Jamfile index 311d27ce0b..6d4acab783 100644 --- a/src/apps/mediaplayer/Jamfile +++ b/src/apps/mediaplayer/Jamfile @@ -25,6 +25,7 @@ for sourceDir in $(sourceDirs) { Application MediaPlayer : # interface + DurationView.cpp PeakView.cpp PlayPauseButton.cpp PositionToolTip.cpp @@ -87,6 +88,7 @@ Application MediaPlayer : ColorSpaceToString.cpp Command.cpp CommandStack.cpp + DurationToString.cpp Event.cpp EventQueue.cpp FileReadWrite.cpp diff --git a/src/apps/mediaplayer/interface/DurationView.cpp b/src/apps/mediaplayer/interface/DurationView.cpp new file mode 100644 index 0000000000..23b48edef5 --- /dev/null +++ b/src/apps/mediaplayer/interface/DurationView.cpp @@ -0,0 +1,131 @@ +/* + * Copyright 2010, Stephan Aßmus . + * Distributed under the terms of the MIT License. + */ + + +#include "DurationView.h" + +#include + +#include "DurationToString.h" + + +// constructor +DurationView::DurationView(const char* name) + : + BStringView(name, ""), + fMode(kTimeToFinish), + fPosition(0), + fDuration(0), + fDisplayDuration(0) +{ + BFont font(be_bold_font); + font.SetSize(font.Size() * 1.2); + SetFont(&font); + + SetAlignment(B_ALIGN_RIGHT); + + _Update(); +} + + +void +DurationView::AttachedToWindow() +{ + BStringView::AttachedToWindow(); + SetHighColor(tint_color(ViewColor(), B_DARKEN_4_TINT)); +} + + +void +DurationView::MouseDown(BPoint where) +{ + // Switch through the modes + uint32 mode = fMode + 1; + if (mode == kLastMode) + mode = 0; + SetMode(mode); +} + + +BSize +DurationView::MinSize() +{ +// If we wanted to have a fixed size: +// BSize size; +// size.width = StringWidth("-00:00:00"); +// font_height fontHeight; +// GetFontHeight(&fontHeight); +// size.height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); +// return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); + return BStringView::MinSize(); +} + + +BSize +DurationView::MaxSize() +{ + return BLayoutUtils::ComposeSize(ExplicitMaxSize(), MinSize()); +} + + +// #pragma mark - + + +void +DurationView::Update(bigtime_t position, bigtime_t duration) +{ + if (position == fPosition && duration == fDuration) + return; + + fPosition = position; + fDuration = duration; + _Update(); +} + + +void +DurationView::SetMode(uint32 mode) +{ + if (mode == fMode) + return; + + fMode = mode; + _Update(); +} + + +void +DurationView::_Update() +{ + switch (fMode) { + case kTimeElapsed: + _GenerateString(fPosition); + break; + default: + case kTimeToFinish: + _GenerateString(fPosition - fDuration); + break; + case kDuration: + _GenerateString(fDuration); + break; + } +} + + +void +DurationView::_GenerateString(bigtime_t duration) +{ + duration /= 1000000; + if (fDisplayDuration == duration) + return; + + fDisplayDuration = duration; + + char string[64]; + duration_to_string(duration, string, sizeof(string)); + + SetText(string); +} + diff --git a/src/apps/mediaplayer/interface/DurationView.h b/src/apps/mediaplayer/interface/DurationView.h new file mode 100644 index 0000000000..6085a89b3e --- /dev/null +++ b/src/apps/mediaplayer/interface/DurationView.h @@ -0,0 +1,50 @@ +/* + * Copyright 2010, Stephan Aßmus . + * Distributed under the terms of the MIT License. + */ +#ifndef DURATION_VIEW_H +#define DURATION_VIEW_H + + +#include +#include + + +class DurationView : public BStringView { +public: + DurationView(const char* name); + + // BStringView interface + virtual void AttachedToWindow(); + virtual void MouseDown(BPoint where); + virtual BSize MinSize(); + virtual BSize MaxSize(); + + // DurationView + void Update(bigtime_t position, bigtime_t duration); + + enum { + kTimeElapsed = 0, + kTimeToFinish, + kDuration, + + kLastMode + }; + + void SetMode(uint32 mode); + uint32 Mode() const + { return fMode; } + +private: + void _Update(); + void _GenerateString(bigtime_t duration); + +private: + uint32 fMode; + bigtime_t fPosition; + bigtime_t fDuration; + bigtime_t fDisplayDuration; +}; + + +#endif // DURATION_VIEW_H diff --git a/src/apps/mediaplayer/interface/PositionToolTip.cpp b/src/apps/mediaplayer/interface/PositionToolTip.cpp index abcb6650fa..667baae679 100644 --- a/src/apps/mediaplayer/interface/PositionToolTip.cpp +++ b/src/apps/mediaplayer/interface/PositionToolTip.cpp @@ -10,6 +10,8 @@ #include +#include "DurationToString.h" + class PositionToolTip::PositionView : public BStringView { public: @@ -48,9 +50,14 @@ public: fDuration = duration; } + char positionText[32]; + duration_to_string(fPosition, positionText, sizeof(positionText)); + + char durationText[32]; + duration_to_string(fDuration, durationText, sizeof(durationText)); + char text[64]; - snprintf(text, sizeof(text), "%02ld:%02ld / %02ld:%02ld", - fPosition / 60, fPosition % 60, fDuration / 60, fDuration % 60); + snprintf(text, sizeof(text), "%s / %s", positionText, durationText); SetText(text); UnlockLooper(); diff --git a/src/apps/mediaplayer/interface/TransportControlGroup.cpp b/src/apps/mediaplayer/interface/TransportControlGroup.cpp index c9198e12a5..f46f4b1a61 100644 --- a/src/apps/mediaplayer/interface/TransportControlGroup.cpp +++ b/src/apps/mediaplayer/interface/TransportControlGroup.cpp @@ -18,6 +18,7 @@ #include #include +#include "DurationView.h" #include "PeakView.h" #include "PlaybackState.h" #include "PlayPauseButton.h" @@ -62,14 +63,26 @@ TransportControlGroup::TransportControlGroup(BRect frame, bool useSkipButtons, { float symbolHeight = 9; - // Seek Slider + BGroupView* seekGroup = new BGroupView(B_HORIZONTAL, 0); + BGroupLayout* seekLayout = seekGroup->GroupLayout(); + GroupLayout()->AddView(seekGroup); + + // Seek slider fSeekSlider = new SeekSlider("seek slider", new BMessage(MSG_SEEK), 0, kPositionFactor); - GroupLayout()->AddView(fSeekSlider); + seekLayout->AddView(fSeekSlider); fPositionToolTip = new PositionToolTip(); fSeekSlider->SetToolTip(fPositionToolTip); + // Duration view + fDurationView = new DurationView("duration view"); + seekLayout->AddView(fDurationView); + + seekLayout->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(5)); + + // Buttons + BGroupView* controlGroup = new BGroupView(B_HORIZONTAL, 0); controlGroup->GroupLayout()->SetInsets(7, 5, 7, 5); GroupLayout()->AddView(controlGroup); @@ -82,8 +95,6 @@ TransportControlGroup::TransportControlGroup(BRect frame, bool useSkipButtons, uint32 topBottomBorder = BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER; - // Buttons - if (useSkipButtons) { // Skip Back fSkipBack = new SymbolButton(B_EMPTY_STRING, @@ -137,8 +148,7 @@ TransportControlGroup::TransportControlGroup(BRect frame, bool useSkipButtons, } else fSkipForward = NULL; - controlGroup->GroupLayout()->AddItem( - BSpaceLayoutItem::CreateHorizontalStrut(5)); + controlLayout->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(5)); // Mute BShape* speakerShape = _CreateSpeakerShape(8); @@ -461,10 +471,12 @@ void TransportControlGroup::SetPosition(float value, bigtime_t position, bigtime_t duration) { + fPositionToolTip->Update(position, duration); + fDurationView->Update(position, duration); + if (fSeekSlider->IsTracking()) return; - fPositionToolTip->Update(position, duration); fSeekSlider->SetPosition(value); } diff --git a/src/apps/mediaplayer/interface/TransportControlGroup.h b/src/apps/mediaplayer/interface/TransportControlGroup.h index d8461121c6..be91052d26 100644 --- a/src/apps/mediaplayer/interface/TransportControlGroup.h +++ b/src/apps/mediaplayer/interface/TransportControlGroup.h @@ -15,6 +15,7 @@ class BShape; +class DurationView; class PeakView; class PlayPauseButton; class PositionToolTip; @@ -104,6 +105,7 @@ private: private: SeekSlider* fSeekSlider; + DurationView* fDurationView; PositionToolTip* fPositionToolTip; PeakView* fPeakView; VolumeSlider* fVolumeSlider; diff --git a/src/apps/mediaplayer/support/DurationToString.cpp b/src/apps/mediaplayer/support/DurationToString.cpp new file mode 100644 index 0000000000..1f1d0b4316 --- /dev/null +++ b/src/apps/mediaplayer/support/DurationToString.cpp @@ -0,0 +1,31 @@ +/* + * Copyright 2010, Stephan Aßmus + * Distributed under the terms of the MIT License. + */ + + +#include "DurationToString.h" + +#include + + +void +duration_to_string(int32 seconds, char* string, size_t stringSize) +{ + bool negative = seconds < 0; + if (negative) + seconds = -seconds; + + int32 hours = seconds / 3600; + seconds -= hours * 3600; + int32 minutes = seconds / 60; + seconds = seconds % 60; + + if (hours > 0) { + snprintf(string, stringSize, "%s%ld:%02ld:%02ld", + negative ? "-" : "", hours, minutes, seconds); + } else { + snprintf(string, stringSize, "%s%ld:%02ld", + negative ? "-" : "", minutes, seconds); + } +} diff --git a/src/apps/mediaplayer/support/DurationToString.h b/src/apps/mediaplayer/support/DurationToString.h new file mode 100644 index 0000000000..990bb8d407 --- /dev/null +++ b/src/apps/mediaplayer/support/DurationToString.h @@ -0,0 +1,15 @@ +/* + * Copyright 2010, Stephan Aßmus + * Distributed under the terms of the MIT License. + */ +#ifndef DURATION_TO_STRING_H +#define DURATION_TO_STRING_H + + +#include + + +void duration_to_string(int32 seconds, char* string, size_t stringSize); + + +#endif // DURATION_TO_STRING_H