From 9cfc4c2ff8117e74b8965d407edb24252dae1aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 9 Apr 2009 17:19:38 +0000 Subject: [PATCH] * The slider now snaps to 0 dB when crossing that to ease finding the maximum volume without distortion. * Added about window. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30073 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/bin/desklink/VolumeControl.cpp | 95 +++++++++++++++++++++++++++++- src/bin/desklink/VolumeControl.h | 10 ++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/src/bin/desklink/VolumeControl.cpp b/src/bin/desklink/VolumeControl.cpp index 07daf06fc4..7be5cd9dc7 100644 --- a/src/bin/desklink/VolumeControl.cpp +++ b/src/bin/desklink/VolumeControl.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,8 @@ VolumeControl::VolumeControl(int32 volumeWhich, bool beep, BMessage* message) : BSlider("VolumeControl", "Volume", message, 0, 1, B_HORIZONTAL), - fBeep(beep) + fBeep(beep), + fSnapping(false) { font_height fontHeight; GetFontHeight(&fontHeight); @@ -123,6 +125,13 @@ VolumeControl::DetachedFromWindow() } +/*! Since we have set a mouse event mask, we don't want to forward all + mouse downs to the slider - instead, we only invoke it, which causes a + message to our target. Within the VolumeWindow, this will actually + cause the window to close. + Also, we need to mask out the dragger in this case, or else dragging + us will also cause a volume update. +*/ void VolumeControl::MouseDown(BPoint where) { @@ -152,6 +161,67 @@ VolumeControl::MouseDown(BPoint where) } +void +VolumeControl::MouseUp(BPoint where) +{ + fSnapping = false; + BSlider::MouseUp(where); +} + + +/*! Override the BSlider functionality to be able to grab the knob when + it's over 0 dB for some pixels. +*/ +void +VolumeControl::MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage) +{ + if (!IsTracking()) { + BSlider::MouseMoved(where, transit, dragMessage); + return; + } + + float cursorPosition = Orientation() == B_HORIZONTAL ? where.x : where.y; + + if (fSnapping && cursorPosition >= fMinSnap && cursorPosition <= fMaxSnap) { + // Don't move the slider, keep the current value for a few + // more pixels + return; + } + + fSnapping = false; + + int32 oldValue = Value(); + int32 newValue = ValueForPoint(where); + if (oldValue == newValue) { + BSlider::MouseMoved(where, transit, dragMessage); + return; + } + + // Check if there is a 0 dB transition at all + if ((oldValue < 0 && newValue >= 0) || (oldValue > 0 && newValue <= 0)) { + SetValue(0); + if (ModificationMessage() != NULL) + Messenger().SendMessage(ModificationMessage()); + + if (oldValue > newValue) { + // movement from right to left + fMinSnap = _PointForValue(-4); + fMaxSnap = _PointForValue(1); + } else { + // movement from left to right + fMinSnap = _PointForValue(-1); + fMaxSnap = _PointForValue(4); + } + + fSnapping = true; + return; + } + + BSlider::MouseMoved(where, transit, dragMessage); +} + + void VolumeControl::MessageReceived(BMessage* msg) { @@ -188,6 +258,13 @@ VolumeControl::MessageReceived(BMessage* msg) SetValue((int32)fMixerControl->Volume()); break; + case B_ABOUT_REQUESTED: + (new BAlert("About Volume Control", "Volume Control\n" + " Written by Jérôme DUVAL, and Axel Dörfler.\n\n" + "Copyright " B_UTF8_COPYRIGHT "2003-2009, Haiku", + "OK"))->Go(NULL); + break; + default: return BView::MessageReceived(msg); } @@ -267,6 +344,22 @@ VolumeControl::_InitVolume(int32 volumeWhich) } +float +VolumeControl::_PointForValue(int32 value) const +{ + int32 min, max; + GetLimits(&min, &max); + + if (Orientation() == B_HORIZONTAL) { + return ceilf(1.0f * (value - min) / (max - min) + * (BarFrame().Width() - 2) + BarFrame().left + 1); + } else { + return ceilf(BarFrame().top - 1.0f * (value - min) / (max - min) + * BarFrame().Height()); + } +} + + bool VolumeControl::_IsReplicant() const { diff --git a/src/bin/desklink/VolumeControl.h b/src/bin/desklink/VolumeControl.h index 27c7eed074..9294917964 100644 --- a/src/bin/desklink/VolumeControl.h +++ b/src/bin/desklink/VolumeControl.h @@ -29,7 +29,12 @@ public: protected: virtual void AttachedToWindow(); virtual void DetachedFromWindow(); + virtual void MouseDown(BPoint where); + virtual void MouseUp(BPoint where); + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage); + virtual void MessageReceived(BMessage* message); virtual status_t Invoke(BMessage* message = NULL); @@ -39,11 +44,16 @@ protected: private: void _InitVolume(int32 volumeWhich); bool _IsReplicant() const; + float _PointForValue(int32 value) const; mutable char fText[64]; MixerControl* fMixerControl; int32 fOriginalValue; bool fBeep; + + bool fSnapping; + float fMinSnap; + float fMaxSnap; }; #endif // VOLUME_SLIDER_H