diff --git a/src/bin/desklink/MediaReplicant.cpp b/src/bin/desklink/MediaReplicant.cpp index e408e25b85..2b8d18e9ce 100644 --- a/src/bin/desklink/MediaReplicant.cpp +++ b/src/bin/desklink/MediaReplicant.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010, Haiku. All rights reserved. + * Copyright 2003-2013, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -9,6 +9,7 @@ * Jonas Sundström * Axel Dörfler, axeld@pinc-software.de. * Stephan Aßmus + * Puck Meerburg, puck@puckipedia.nl */ @@ -90,19 +91,29 @@ public: if (!Lock()) return; - MixerControl control; - control.Connect(fWhich); + if (fMuteMessage.Length() != 0) + fView->SetText(fMuteMessage.String()); + else { + MixerControl control; + control.Connect(fWhich); - BString text; - text.SetToFormat(B_TRANSLATE("%g dB"), control.Volume()); - fView->SetText(text.String()); + BString text; + text.SetToFormat(B_TRANSLATE("%g dB"), control.Volume()); + fView->SetText(text.String()); + } Unlock(); } + void SetMuteMessage(const char* message) + { + fMuteMessage = message == NULL ? "" : message; + } + private: BStringView* fView; int32 fWhich; + BString fMuteMessage; }; @@ -110,7 +121,8 @@ class MediaReplicant : public BView { public: MediaReplicant(BRect frame, const char* name, uint32 resizeMask = B_FOLLOW_ALL, - uint32 flags = B_WILL_DRAW | B_NAVIGABLE); + uint32 flags = B_WILL_DRAW | B_NAVIGABLE + | B_PULSE_NEEDED); MediaReplicant(BMessage* archive); virtual ~MediaReplicant(); @@ -124,6 +136,7 @@ public: virtual void MouseDown(BPoint point); virtual void Draw(BRect updateRect); virtual void MessageReceived(BMessage* message); + virtual void Pulse(); private: status_t _LaunchByPath(const char* path); @@ -136,11 +149,13 @@ private: void _Init(); BBitmap* fIcon; + BBitmap* fMutedIcon; VolumeWindow* fVolumeSlider; bool fDontBeep; // don't beep on volume change int32 fVolumeWhich; // which volume parameter to act on (Mixer/Phys.Output) + bool fMuted; }; @@ -148,7 +163,8 @@ MediaReplicant::MediaReplicant(BRect frame, const char* name, uint32 resizeMask, uint32 flags) : BView(frame, name, resizeMask, flags), - fVolumeSlider(NULL) + fVolumeSlider(NULL), + fMuted(false) { _Init(); } @@ -157,7 +173,8 @@ MediaReplicant::MediaReplicant(BRect frame, const char* name, MediaReplicant::MediaReplicant(BMessage* message) : BView(message), - fVolumeSlider(NULL) + fVolumeSlider(NULL), + fMuted(false) { _Init(); } @@ -206,7 +223,7 @@ void MediaReplicant::Draw(BRect rect) { SetDrawingMode(B_OP_OVER); - DrawBitmap(fIcon); + DrawBitmap(fMuted ? fMutedIcon : fIcon); } @@ -255,6 +272,20 @@ MediaReplicant::MouseDown(BPoint point) menu->Go(where, true, true, BRect(where - BPoint(4, 4), where + BPoint(4, 4))); + + } else if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0) { + MixerControl mixerControl; + if (mixerControl.Connect(fVolumeWhich)) { + mixerControl.SetMute(!fMuted); + fMuted = mixerControl.Mute(); + VolumeToolTip* tip = dynamic_cast(ToolTip()); + if (tip != NULL) { + tip->SetMuteMessage(fMuted ? B_TRANSLATE("Muted"): NULL); + ShowToolTip(tip); + } + Invalidate(); + } + } else { // Show VolumeWindow fVolumeSlider = new VolumeWindow(BRect(where.x, where.y, @@ -264,6 +295,28 @@ MediaReplicant::MouseDown(BPoint point) } +void +MediaReplicant::Pulse() +{ + bool setMuted = false; + MixerControl mixerControl; + const char* errorString = NULL; + if (!mixerControl.Connect(fVolumeWhich, NULL, &errorString)) { + fMuted = true; + errorString = NULL; + } else + setMuted = mixerControl.Mute(); + + if (setMuted != fMuted) { + fMuted = setMuted; + VolumeToolTip* tip = dynamic_cast(ToolTip()); + if (tip != NULL) + tip->SetMuteMessage(errorString); + Invalidate(); + } +} + + void MediaReplicant::MessageReceived(BMessage* message) { @@ -452,6 +505,11 @@ MediaReplicant::_Init() B_RGBA32); BIconUtils::GetVectorIcon(kSpeakerIcon, sizeof(kSpeakerIcon), fIcon); + fMutedIcon = new BBitmap(BRect(0, 0, kSpeakerWidth - 1, kSpeakerHeight - 1), + B_RGBA32); + BIconUtils::GetVectorIcon(kMutedSpeakerIcon, sizeof(kMutedSpeakerIcon), + fMutedIcon); + _LoadSettings(); SetToolTip(new VolumeToolTip(fVolumeWhich)); diff --git a/src/bin/desklink/MixerControl.cpp b/src/bin/desklink/MixerControl.cpp index 4adb8403aa..ed2c5b101a 100644 --- a/src/bin/desklink/MixerControl.cpp +++ b/src/bin/desklink/MixerControl.cpp @@ -1,11 +1,12 @@ /* - * Copyright 2003-2009, Haiku, Inc. + * Copyright 2003-2013, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: * Jérôme Duval * François Revol * Axel Dörfler, axeld@pinc-software.de. + * Puck Meerburg, puck@puckipedia.nl */ @@ -23,6 +24,7 @@ MixerControl::MixerControl(int32 volumeWhich) fGainMediaNode(media_node::null), fParameterWeb(NULL), fMixerParameter(NULL), + fMuteParameter(NULL), fMin(0.0f), fMax(0.0f), fStep(0.0f) @@ -85,6 +87,11 @@ retry: bool foundMixerLabel = false; for (int i = 0; i < numParams; i++) { p = fParameterWeb->ParameterAt(i); + + // assume the mute preceeding master gain control + if (!strcmp(p->Kind(), B_MUTE)) + fMuteParameter = p; + PRINT(("BParameter[%i]: %s\n", i, p->Name())); if (volumeWhich == VOLUME_USE_MIXER) { if (!strcmp(p->Kind(), B_MASTER_GAIN)) @@ -196,6 +203,31 @@ MixerControl::VolumeWhich() const } +void +MixerControl::SetMute(bool muted) +{ + if (fMuteParameter == NULL) + return; + + int32 mute = muted ? 1 : 0; + fMuteParameter->SetValue(&mute, sizeof(int32), system_time()); +} + + +bool +MixerControl::Mute() +{ + if (fMuteParameter == NULL) + return false; + + int32 mute = 0; + bigtime_t lastChange = 0; + size_t size = sizeof(int32); + fMuteParameter->GetValue(&mute, &size, &lastChange); + return mute != 0; +} + + float MixerControl::Volume() const { diff --git a/src/bin/desklink/MixerControl.h b/src/bin/desklink/MixerControl.h index 59b27e09a9..62d2dca621 100644 --- a/src/bin/desklink/MixerControl.h +++ b/src/bin/desklink/MixerControl.h @@ -1,10 +1,11 @@ /* - * Copyright 2003-2009, Haiku, Inc. + * Copyright 2003-2013, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: * Jérôme Duval * François Revol + * Puck Meerburg, puck@puckipedia.nl */ #ifndef MIXER_CONTROL_H #define MIXER_CONTROL_H @@ -12,9 +13,9 @@ #include -class BParameterWeb; class BContinuousParameter; - +class BParameter; +class BParameterWeb; // The volume which choices #define VOLUME_USE_MIXER 0 // default @@ -36,6 +37,9 @@ public: void SetVolume(float volume); void ChangeVolumeBy(float value); + void SetMute(bool muted); + bool Mute(); + float Minimum() const { return fMin; } float Maximum() const { return fMax; } @@ -48,6 +52,7 @@ private: media_node fGainMediaNode; BParameterWeb* fParameterWeb; BContinuousParameter* fMixerParameter; + BParameter* fMuteParameter; float fMin; float fMax; float fStep; diff --git a/src/bin/desklink/VolumeWindow.cpp b/src/bin/desklink/VolumeWindow.cpp index ae99ba0771..f1c8b52c31 100644 --- a/src/bin/desklink/VolumeWindow.cpp +++ b/src/bin/desklink/VolumeWindow.cpp @@ -67,7 +67,7 @@ VolumeWindow::~VolumeWindow() { } -#include + void VolumeWindow::MessageReceived(BMessage *msg) { diff --git a/src/bin/desklink/iconfile.h b/src/bin/desklink/iconfile.h index 43583284b8..c8280f3fc6 100644 --- a/src/bin/desklink/iconfile.h +++ b/src/bin/desklink/iconfile.h @@ -55,3 +55,51 @@ const unsigned char kSpeakerIcon[] = { 0x01, 0x01, 0x06, 0x10, 0x01, 0x17, 0x82, 0x00, 0x04, 0x0a, 0x0a, 0x01, 0x06, 0x00 }; + +const unsigned char kMutedSpeakerIcon[] = { + 0x6e, 0x63, 0x69, 0x66, 0x0b, 0x04, 0x01, 0x74, 0x05, 0x00, 0x02, 0x00, + 0x16, 0x02, 0x3b, 0xec, 0x7c, 0x3d, 0x46, 0x4b, 0xbd, 0xc2, 0x11, 0x3c, + 0x40, 0x66, 0x4a, 0x53, 0xa4, 0x49, 0x21, 0x70, 0x00, 0xdd, 0xff, 0xc5, + 0x02, 0x00, 0x16, 0x02, 0x3b, 0x9e, 0x03, 0x2f, 0xed, 0x63, 0xb0, 0xf2, + 0x4f, 0x3c, 0xb6, 0xc1, 0x4a, 0x53, 0x3f, 0x3a, 0xbe, 0x84, 0x00, 0xff, + 0xff, 0xc5, 0x02, 0x00, 0x16, 0x02, 0x39, 0x5e, 0x1e, 0x32, 0xdb, 0x49, + 0xb6, 0x92, 0x1a, 0x3d, 0x07, 0xd7, 0x4a, 0x57, 0x90, 0x49, 0x08, 0xd6, + 0x00, 0x64, 0xff, 0x8c, 0x05, 0x01, 0x02, 0x03, 0x16, 0x04, 0xbe, 0xbe, + 0x2b, 0xbe, 0xe9, 0x57, 0x3e, 0xe9, 0x57, 0xbe, 0xbe, 0x2b, 0x48, 0xb7, + 0x78, 0x4a, 0x2f, 0xd3, 0x00, 0x01, 0xc2, 0x70, 0xd0, 0x73, 0xff, 0xff, + 0x02, 0x01, 0x16, 0x03, 0x3b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x20, 0x00, 0x48, 0x40, 0x00, 0x49, 0xe0, 0x00, 0x00, 0x84, + 0xbe, 0x4b, 0xff, 0x32, 0x02, 0x03, 0x16, 0x02, 0x3c, 0x4e, 0x21, 0x3d, + 0x44, 0xda, 0xbd, 0x44, 0xda, 0x3c, 0x4e, 0x21, 0x49, 0x26, 0x89, 0x4a, + 0x42, 0x8e, 0xa1, 0x43, 0xff, 0xff, 0x02, 0x03, 0x16, 0x03, 0xbc, 0x6b, + 0x27, 0xbd, 0x2f, 0x9c, 0x3d, 0x2f, 0x9c, 0xbc, 0x6b, 0x27, 0x48, 0xb0, + 0xfd, 0x4a, 0x3d, 0x7c, 0x2a, 0x01, 0xb2, 0x28, 0xff, 0xff, 0x03, 0xff, + 0x00, 0x00, 0x09, 0x0a, 0x04, 0x46, 0x60, 0x4e, 0x60, 0x60, 0x4c, 0x54, + 0x47, 0x0a, 0x04, 0x26, 0x2b, 0x26, 0x4e, 0x46, 0x5e, 0x46, 0x34, 0x0a, + 0x04, 0x46, 0x35, 0x46, 0x5e, 0x56, 0x4e, 0x56, 0x2a, 0x0a, 0x04, 0x26, + 0x2b, 0x46, 0x35, 0x56, 0x2a, 0x39, 0x22, 0x0a, 0x06, 0x26, 0x2b, 0x26, + 0x4e, 0x46, 0x5e, 0x56, 0x4e, 0x56, 0x2a, 0x39, 0x22, 0x02, 0x04, 0xb9, + 0xa4, 0xbb, 0x36, 0xbc, 0x05, 0xba, 0x54, 0xb7, 0x43, 0xbc, 0x17, 0xb7, + 0x73, 0x47, 0xb6, 0x49, 0xbf, 0x5e, 0xb8, 0x9e, 0xc5, 0xb6, 0xbd, 0xdd, + 0xc6, 0xb1, 0xbb, 0x7c, 0xc7, 0x92, 0xc0, 0x3f, 0xc5, 0xd0, 0xc0, 0x10, + 0xbf, 0x5c, 0xc1, 0x3b, 0xc2, 0x88, 0xbe, 0xe6, 0xbc, 0x31, 0x02, 0x04, + 0xc0, 0x1c, 0xc7, 0xc0, 0xc0, 0x6d, 0xc7, 0xa7, 0xbf, 0xca, 0xc7, 0xd9, + 0xbf, 0xc5, 0xc8, 0xb1, 0xbf, 0xa5, 0xc8, 0x45, 0xbf, 0xe8, 0xc9, 0x1c, + 0xc0, 0x94, 0xc9, 0x46, 0xc0, 0x43, 0xc9, 0x5f, 0xc0, 0xe6, 0xc9, 0x2d, + 0xc0, 0xeb, 0xc8, 0x55, 0xc1, 0x0b, 0xc8, 0xc1, 0xc0, 0xc8, 0xc7, 0xeb, + 0x0a, 0x02, 0x28, 0x4d, 0x43, 0x38, 0x08, 0x02, 0x29, 0x30, 0x43, 0x5a, + 0x0e, 0x0a, 0x00, 0x01, 0x00, 0x20, 0x21, 0x21, 0x0a, 0x01, 0x01, 0x04, + 0x10, 0x01, 0x17, 0x84, 0x00, 0x04, 0x0a, 0x02, 0x01, 0x01, 0x00, 0x0a, + 0x03, 0x01, 0x03, 0x00, 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0a, 0x05, 0x01, + 0x05, 0x10, 0x01, 0x17, 0x84, 0x00, 0x04, 0x0a, 0x06, 0x01, 0x05, 0x00, + 0x0a, 0x07, 0x01, 0x05, 0x02, 0x3d, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3d, 0xbb, 0xbb, 0x47, 0x44, 0x44, 0x48, 0x62, 0x22, 0x0a, + 0x08, 0x01, 0x05, 0x1a, 0x3f, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xa0, 0x00, 0x41, 0xff, 0xfb, 0x42, 0xff, 0xfd, 0x13, 0xff, + 0x01, 0x17, 0x81, 0x00, 0x04, 0x0a, 0x09, 0x01, 0x05, 0x1a, 0x3f, 0x38, + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3d, 0xfb, 0x44, 0x32, + 0x85, 0x45, 0x59, 0x5c, 0x13, 0xff, 0x01, 0x17, 0x82, 0x00, 0x04, 0x0a, + 0x01, 0x01, 0x06, 0x10, 0x01, 0x17, 0x82, 0x00, 0x04, 0x0a, 0x0a, 0x01, + 0x06, 0x00, 0x0a, 0x0a, 0x01, 0x07, 0x10, 0x01, 0x17, 0x86, 0x22, 0x04, + 0x0a, 0x0a, 0x01, 0x08, 0x10, 0x01, 0x17, 0x86, 0x20, 0x04 +};