patch by Fredrik Modéen with changes by myself

* toggle the "marked" state of the settings menu items correctly
* implement muting/unmuting the volume
* implement volume up/down triggered by keyboard events
* forward the skip next/previous events to the controller
  (various kinds of keyboard navigation or mouse wheel)
* establish the notification link for volume and muted changes


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22594 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2007-10-17 10:29:16 +00:00
parent c9518b6240
commit 540fe7aef9
11 changed files with 161 additions and 69 deletions
+60 -2
View File
@@ -76,6 +76,7 @@ void Controller::Listener::AudioStatsChanged() {}
void Controller::Listener::PlaybackStateChanged(uint32) {} void Controller::Listener::PlaybackStateChanged(uint32) {}
void Controller::Listener::PositionChanged(float) {} void Controller::Listener::PositionChanged(float) {}
void Controller::Listener::VolumeChanged(float) {} void Controller::Listener::VolumeChanged(float) {}
void Controller::Listener::MutedChanged(bool) {}
// #pragma mark - // #pragma mark -
@@ -86,6 +87,7 @@ Controller::Controller()
, fPaused(false) , fPaused(false)
, fStopped(true) , fStopped(true)
, fVolume(1.0) , fVolume(1.0)
, fMuted(false)
, fRef() , fRef()
, fMediaFile(0) , fMediaFile(0)
@@ -494,12 +496,57 @@ void
Controller::SetVolume(float value) Controller::SetVolume(float value)
{ {
printf("Controller::SetVolume %.4f\n", value); printf("Controller::SetVolume %.4f\n", value);
if (Lock()) { if (!Lock())
return;
value = max_c(0.0, min_c(2.0, value));
if (fVolume != value) {
if (fMuted)
ToggleMute();
fVolume = value; fVolume = value;
if (fSoundOutput) if (fSoundOutput)
fSoundOutput->SetVolume(fVolume); fSoundOutput->SetVolume(fVolume);
Unlock();
_NotifyVolumeChanged(fVolume);
} }
Unlock();
}
void
Controller::VolumeUp()
{
// TODO: linear <-> exponential
SetVolume(Volume() + 0.05);
}
void
Controller::VolumeDown()
{
// TODO: linear <-> exponential
SetVolume(Volume() - 0.05);
}
void
Controller::ToggleMute()
{
if (!Lock())
return;
fMuted = !fMuted;
if (fSoundOutput) {
if (fMuted)
fSoundOutput->SetVolume(0.0);
else
fSoundOutput->SetVolume(fVolume);
}
_NotifyMutedChanged(fMuted);
Unlock();
} }
@@ -1330,3 +1377,14 @@ Controller::_NotifyVolumeChanged(float volume)
} }
} }
void
Controller::_NotifyMutedChanged(bool muted)
{
BList listeners(fListeners);
int32 count = listeners.CountItems();
for (int32 i = 0; i < count; i++) {
Listener* listener = (Listener*)listeners.ItemAtFast(i);
listener->MutedChanged(muted);
}
}
+6
View File
@@ -57,6 +57,7 @@ public:
virtual void PlaybackStateChanged(uint32 state); virtual void PlaybackStateChanged(uint32 state);
virtual void PositionChanged(float position); virtual void PositionChanged(float position);
virtual void VolumeChanged(float volume); virtual void VolumeChanged(float volume);
virtual void MutedChanged(bool muted);
}; };
Controller(); Controller();
@@ -89,6 +90,9 @@ public:
void SetVolume(float value); void SetVolume(float value);
float Volume() const; float Volume() const;
void VolumeUp();
void VolumeDown();
void ToggleMute();
void SetPosition(float value); void SetPosition(float value);
bool HasFile(); bool HasFile();
@@ -146,6 +150,7 @@ private:
void _NotifyPlaybackStateChanged(); void _NotifyPlaybackStateChanged();
void _NotifyPositionChanged(float position); void _NotifyPositionChanged(float position);
void _NotifyVolumeChanged(float volume); void _NotifyVolumeChanged(float volume);
void _NotifyMutedChanged(bool muted);
friend class InfoWin; friend class InfoWin;
@@ -169,6 +174,7 @@ private:
volatile bool fPaused; volatile bool fPaused;
volatile bool fStopped; volatile bool fStopped;
float fVolume; float fVolume;
bool fMuted;
entry_ref fRef; entry_ref fRef;
BMediaFile * fMediaFile; BMediaFile * fMediaFile;
@@ -137,3 +137,16 @@ ControllerObserver::VolumeChanged(float volume)
} }
void
ControllerObserver::MutedChanged(bool muted)
{
if (!(fObserveFlags & OBSERVE_VOLUME_CHANGES))
return;
BMessage message(MSG_CONTROLLER_MUTED_CHANGED);
message.AddBool("muted", muted);
DeliverMessage(message);
}
+3 -1
View File
@@ -23,7 +23,8 @@ enum {
MSG_CONTROLLER_PLAYBACK_STATE_CHANGED = 'cnps', MSG_CONTROLLER_PLAYBACK_STATE_CHANGED = 'cnps',
MSG_CONTROLLER_POSITION_CHANGED = 'cnpc', MSG_CONTROLLER_POSITION_CHANGED = 'cnpc',
MSG_CONTROLLER_VOLUME_CHANGED = 'cnvc' MSG_CONTROLLER_VOLUME_CHANGED = 'cnvc',
MSG_CONTROLLER_MUTED_CHANGED = 'cnmc'
}; };
enum { enum {
@@ -57,6 +58,7 @@ class ControllerObserver : public Controller::Listener,
virtual void PlaybackStateChanged(uint32 state); virtual void PlaybackStateChanged(uint32 state);
virtual void PositionChanged(float position); virtual void PositionChanged(float position);
virtual void VolumeChanged(float volume); virtual void VolumeChanged(float volume);
virtual void MutedChanged(bool muted);
private: private:
uint32 fObserveFlags; uint32 fObserveFlags;
+1 -1
View File
@@ -145,7 +145,7 @@ ControllerView::VolumeChanged(float value)
void void
ControllerView::ToggleMute() ControllerView::ToggleMute()
{ {
printf("ControllerView::ToggleMute()\n"); fController->ToggleMute();
} }
+5 -5
View File
@@ -36,11 +36,6 @@ public:
Playlist* playlist); Playlist* playlist);
~ControllerView(); ~ControllerView();
private:
void AttachedToWindow();
void MessageReceived(BMessage *msg);
void Draw(BRect updateRect);
// TransportControlGroup interface // TransportControlGroup interface
virtual uint32 EnabledButtons(); virtual uint32 EnabledButtons();
virtual void TogglePlaying(); virtual void TogglePlaying();
@@ -53,6 +48,11 @@ private:
virtual void ToggleMute(); virtual void ToggleMute();
virtual void PositionChanged(float value); virtual void PositionChanged(float value);
private:
void AttachedToWindow();
void MessageReceived(BMessage* message);
void Draw(BRect updateRect);
// ControllerView // ControllerView
void CheckSkippable(); void CheckSkippable();
+56 -54
View File
@@ -72,8 +72,8 @@ enum {
M_PREFERENCES, M_PREFERENCES,
M_VOLUME_UP, M_VOLUME_UP,
M_VOLUME_DOWN, M_VOLUME_DOWN,
M_CHANNEL_NEXT, M_SKIP_NEXT,
M_CHANNEL_PREV, M_SKIP_PREV,
M_ASPECT_100000_1, M_ASPECT_100000_1,
M_ASPECT_106666_1, M_ASPECT_106666_1,
M_ASPECT_109091_1, M_ASPECT_109091_1,
@@ -105,7 +105,8 @@ MainWin::MainWin()
, fController(new Controller) , fController(new Controller)
, fControllerObserver(new ControllerObserver(this, , fControllerObserver(new ControllerObserver(this,
OBSERVE_FILE_CHANGES | OBSERVE_TRACK_CHANGES OBSERVE_FILE_CHANGES | OBSERVE_TRACK_CHANGES
| OBSERVE_PLAYBACK_STATE_CHANGES | OBSERVE_POSITION_CHANGES)) | OBSERVE_PLAYBACK_STATE_CHANGES | OBSERVE_POSITION_CHANGES
| OBSERVE_VOLUME_CHANGES))
, fIsFullscreen(false) , fIsFullscreen(false)
, fKeepAspectRatio(true) , fKeepAspectRatio(true)
, fAlwaysOnTop(false) , fAlwaysOnTop(false)
@@ -168,8 +169,7 @@ MainWin::MainWin()
// setup the playlist window now, we need to have it // setup the playlist window now, we need to have it
// running for the undo/redo playlist editing // running for the undo/redo playlist editing
fPlaylistWindow = new PlaylistWindow(BRect(150, 150, 400, 500), fPlaylistWindow = new PlaylistWindow(BRect(150, 150, 400, 500), fPlaylist, fController);
fPlaylist, fController);
fPlaylistWindow->Hide(); fPlaylistWindow->Hide();
fPlaylistWindow->Show(); fPlaylistWindow->Show();
// this makes sure the window thread is running without // this makes sure the window thread is running without
@@ -315,6 +315,7 @@ MainWin::DispatchMessage(BMessage *msg, BHandler *handler)
void void
MainWin::MessageReceived(BMessage *msg) MainWin::MessageReceived(BMessage *msg)
{ {
// msg->PrintToStream();
switch (msg->what) { switch (msg->what) {
case B_REFS_RECEIVED: case B_REFS_RECEIVED:
printf("MainWin::MessageReceived: B_REFS_RECEIVED\n"); printf("MainWin::MessageReceived: B_REFS_RECEIVED\n");
@@ -397,6 +398,18 @@ MainWin::MessageReceived(BMessage *msg)
fControls->SetPosition(position); fControls->SetPosition(position);
break; break;
} }
case MSG_CONTROLLER_VOLUME_CHANGED: {
float volume;
if (msg->FindFloat("volume", &volume) == B_OK)
fControls->SetVolume(volume);
break;
}
case MSG_CONTROLLER_MUTED_CHANGED: {
bool muted;
if (msg->FindBool("muted", &muted) == B_OK)
fControls->SetMuted(muted);
break;
}
// menu item messages // menu item messages
case M_FILE_NEWPLAYER: case M_FILE_NEWPLAYER:
@@ -437,32 +450,26 @@ MainWin::MessageReceived(BMessage *msg)
case M_TOGGLE_FULLSCREEN: case M_TOGGLE_FULLSCREEN:
_ToggleFullscreen(); _ToggleFullscreen();
// fSettingsMenu->ItemAt(1)->SetMarked(fIsFullscreen);
break; break;
case M_TOGGLE_NO_MENU: case M_TOGGLE_NO_MENU:
_ToggleNoMenu(); _ToggleNoMenu();
// fSettingsMenu->ItemAt(3)->SetMarked(fNoMenu);
break; break;
case M_TOGGLE_NO_CONTROLS: case M_TOGGLE_NO_CONTROLS:
_ToggleNoControls(); _ToggleNoControls();
// fSettingsMenu->ItemAt(3)->SetMarked(fNoControls);
break; break;
case M_TOGGLE_NO_BORDER: case M_TOGGLE_NO_BORDER:
_ToggleNoBorder(); _ToggleNoBorder();
// fSettingsMenu->ItemAt(4)->SetMarked(fNoBorder);
break; break;
case M_TOGGLE_ALWAYS_ON_TOP: case M_TOGGLE_ALWAYS_ON_TOP:
_ToggleAlwaysOnTop(); _ToggleAlwaysOnTop();
// fSettingsMenu->ItemAt(5)->SetMarked(fAlwaysOnTop);
break; break;
case M_TOGGLE_KEEP_ASPECT_RATIO: case M_TOGGLE_KEEP_ASPECT_RATIO:
_ToggleKeepAspectRatio(); _ToggleKeepAspectRatio();
// fSettingsMenu->ItemAt(6)->SetMarked(fKeepAspectRatio);
break; break;
case M_TOGGLE_NO_BORDER_NO_MENU_NO_CONTROLS: case M_TOGGLE_NO_BORDER_NO_MENU_NO_CONTROLS:
@@ -527,47 +534,28 @@ MainWin::MessageReceived(BMessage *msg)
float dx = msg->FindFloat("be:wheel_delta_x"); float dx = msg->FindFloat("be:wheel_delta_x");
float dy = msg->FindFloat("be:wheel_delta_y"); float dy = msg->FindFloat("be:wheel_delta_y");
bool inv = modifiers() & B_COMMAND_KEY; bool inv = modifiers() & B_COMMAND_KEY;
if (dx > 0.1) PostMessage(inv ? M_VOLUME_DOWN : M_CHANNEL_PREV); if (dx > 0.1) PostMessage(inv ? M_VOLUME_DOWN : M_SKIP_PREV);
if (dx < -0.1) PostMessage(inv ? M_VOLUME_UP : M_CHANNEL_NEXT); if (dx < -0.1) PostMessage(inv ? M_VOLUME_UP : M_SKIP_NEXT);
if (dy > 0.1) PostMessage(inv ? M_CHANNEL_PREV : M_VOLUME_DOWN); if (dy > 0.1) PostMessage(inv ? M_SKIP_PREV : M_VOLUME_DOWN);
if (dy < -0.1) PostMessage(inv ? M_CHANNEL_NEXT : M_VOLUME_UP); if (dy < -0.1) PostMessage(inv ? M_SKIP_NEXT : M_VOLUME_UP);
break; break;
} }
*/
case M_SKIP_NEXT:
fControls->SkipForward();
break;
case M_CHANNEL_NEXT: case M_SKIP_PREV:
{ fControls->SkipBackward();
printf("M_CHANNEL_NEXT\n");
int chan = fController->CurrentChannel();
if (chan != -1) {
chan++;
if (chan < fController->ChannelCount())
SelectChannel(chan);
}
break; break;
}
case M_CHANNEL_PREV:
{
printf("M_CHANNEL_PREV\n");
int chan = fController->CurrentChannel();
if (chan != -1) {
chan--;
if (chan >= 0)
SelectChannel(chan);
}
break;
}
case M_VOLUME_UP: case M_VOLUME_UP:
printf("M_VOLUME_UP\n");
fController->VolumeUp(); fController->VolumeUp();
break; break;
case M_VOLUME_DOWN: case M_VOLUME_DOWN:
printf("M_VOLUME_DOWN\n");
fController->VolumeDown(); fController->VolumeDown();
break; break;
*/
case M_ASPECT_100000_1: case M_ASPECT_100000_1:
VideoFormatChange(fSourceWidth, fSourceHeight, 1.0, 1.0); VideoFormatChange(fSourceWidth, fSourceHeight, 1.0, 1.0);
@@ -1145,7 +1133,7 @@ MainWin::_KeyDown(BMessage *msg)
case B_UP_ARROW: case B_UP_ARROW:
if (modifiers & B_COMMAND_KEY) { if (modifiers & B_COMMAND_KEY) {
PostMessage(M_CHANNEL_NEXT); PostMessage(M_SKIP_NEXT);
} else { } else {
PostMessage(M_VOLUME_UP); PostMessage(M_VOLUME_UP);
} }
@@ -1153,7 +1141,7 @@ MainWin::_KeyDown(BMessage *msg)
case B_DOWN_ARROW: case B_DOWN_ARROW:
if (modifiers & B_COMMAND_KEY) { if (modifiers & B_COMMAND_KEY) {
PostMessage(M_CHANNEL_PREV); PostMessage(M_SKIP_PREV);
} else { } else {
PostMessage(M_VOLUME_DOWN); PostMessage(M_VOLUME_DOWN);
} }
@@ -1163,7 +1151,7 @@ MainWin::_KeyDown(BMessage *msg)
if (modifiers & B_COMMAND_KEY) { if (modifiers & B_COMMAND_KEY) {
PostMessage(M_VOLUME_UP); PostMessage(M_VOLUME_UP);
} else { } else {
PostMessage(M_CHANNEL_NEXT); PostMessage(M_SKIP_NEXT);
} }
return B_OK; return B_OK;
@@ -1171,16 +1159,16 @@ MainWin::_KeyDown(BMessage *msg)
if (modifiers & B_COMMAND_KEY) { if (modifiers & B_COMMAND_KEY) {
PostMessage(M_VOLUME_DOWN); PostMessage(M_VOLUME_DOWN);
} else { } else {
PostMessage(M_CHANNEL_PREV); PostMessage(M_SKIP_PREV);
} }
return B_OK; return B_OK;
case B_PAGE_UP: case B_PAGE_UP:
PostMessage(M_CHANNEL_NEXT); PostMessage(M_SKIP_NEXT);
return B_OK; return B_OK;
case B_PAGE_DOWN: case B_PAGE_DOWN:
PostMessage(M_CHANNEL_PREV); PostMessage(M_SKIP_PREV);
return B_OK; return B_OK;
} }
@@ -1213,12 +1201,12 @@ MainWin::_KeyDown(BMessage *msg)
case 0x39: // numeric keypad page up case 0x39: // numeric keypad page up
case 0x4a: // numeric keypad right arrow case 0x4a: // numeric keypad right arrow
PostMessage(M_CHANNEL_NEXT); PostMessage(M_SKIP_NEXT);
return B_OK; return B_OK;
case 0x5a: // numeric keypad page down case 0x5a: // numeric keypad page down
case 0x48: // numeric keypad left arrow case 0x48: // numeric keypad left arrow
PostMessage(M_CHANNEL_PREV); PostMessage(M_SKIP_PREV);
return B_OK; return B_OK;
} }
@@ -1281,6 +1269,8 @@ MainWin::_ToggleFullscreen()
Show(); Show();
} }
_MarkSettingsItem(M_TOGGLE_FULLSCREEN, fIsFullscreen);
printf("_ToggleFullscreen leave\n"); printf("_ToggleFullscreen leave\n");
} }
@@ -1304,6 +1294,8 @@ MainWin::_ToggleNoControls()
ResizeBy(0, fControlsHeight); ResizeBy(0, fControlsHeight);
} }
_MarkSettingsItem(M_TOGGLE_NO_CONTROLS, fNoControls);
printf("_ToggleNoControls leave\n"); printf("_ToggleNoControls leave\n");
} }
@@ -1329,6 +1321,8 @@ MainWin::_ToggleNoMenu()
ResizeBy(0, fMenuBarHeight); ResizeBy(0, fMenuBarHeight);
} }
_MarkSettingsItem(M_TOGGLE_NO_MENU, fNoMenu);
printf("_ToggleNoMenu leave\n"); printf("_ToggleNoMenu leave\n");
} }
@@ -1336,30 +1330,30 @@ MainWin::_ToggleNoMenu()
void void
MainWin::_ToggleNoBorder() MainWin::_ToggleNoBorder()
{ {
printf("_ToggleNoBorder enter\n");
fNoBorder = !fNoBorder; fNoBorder = !fNoBorder;
SetLook(fNoBorder ? B_BORDERED_WINDOW_LOOK : B_TITLED_WINDOW_LOOK); SetLook(fNoBorder ? B_BORDERED_WINDOW_LOOK : B_TITLED_WINDOW_LOOK);
printf("_ToggleNoBorder leave\n");
_MarkSettingsItem(M_TOGGLE_NO_BORDER, fNoBorder);
} }
void void
MainWin::_ToggleAlwaysOnTop() MainWin::_ToggleAlwaysOnTop()
{ {
printf("_ToggleAlwaysOnTop enter\n");
fAlwaysOnTop = !fAlwaysOnTop; fAlwaysOnTop = !fAlwaysOnTop;
SetFeel(fAlwaysOnTop ? B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL); SetFeel(fAlwaysOnTop ? B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL);
printf("_ToggleAlwaysOnTop leave\n");
_MarkSettingsItem(M_TOGGLE_ALWAYS_ON_TOP, fAlwaysOnTop);
} }
void void
MainWin::_ToggleKeepAspectRatio() MainWin::_ToggleKeepAspectRatio()
{ {
printf("_ToggleKeepAspectRatio enter\n");
fKeepAspectRatio = !fKeepAspectRatio; fKeepAspectRatio = !fKeepAspectRatio;
FrameResized(Bounds().Width(), Bounds().Height()); FrameResized(Bounds().Width(), Bounds().Height());
printf("_ToggleKeepAspectRatio leave\n");
_MarkSettingsItem(M_TOGGLE_KEEP_ASPECT_RATIO, fKeepAspectRatio);
} }
@@ -1442,3 +1436,11 @@ MainWin::_MarkPlaylistItem(int32 index)
} }
void
MainWin::_MarkSettingsItem(uint32 command, bool mark)
{
if (BMenuItem* item = fSettingsMenu->FindItem(command))
item->SetMarked(mark);
}
+1
View File
@@ -91,6 +91,7 @@ private:
int32 index); int32 index);
void _RemovePlaylistItem(int32 index); void _RemovePlaylistItem(int32 index);
void _MarkPlaylistItem(int32 index); void _MarkPlaylistItem(int32 index);
void _MarkSettingsItem(uint32 command, bool mark);
BMenuBar* fMenuBar; BMenuBar* fMenuBar;
BView* fBackground; BView* fBackground;
@@ -429,13 +429,12 @@ TransportControlGroup::SetMuted(bool mute)
void void
TransportControlGroup::SetVolume(float value) TransportControlGroup::SetVolume(float value)
{ {
if (B_OK != LockLooperWithTimeout(50000)) float db = _GainToDb(value);
return; float exponential = _LinearToExponential(db);
float gain = _DbToGain(exponential);
int32 pos = (int32)(floorf(gain * kVolumeFactor + 0.5));
fVolumeSlider->SetValue(_DbToGain(_ExponentialToLinear( fVolumeSlider->SetValueNoInvoke(pos);
_GainToDb(value))) * kVolumeFactor);
UnlockLooper();
} }
+10
View File
@@ -90,6 +90,16 @@ VolumeSlider::SetValue(int32 value)
Invoke(); Invoke();
} }
// SetValueNoInvoke
void
VolumeSlider::SetValueNoInvoke(int32 value)
{
if (value == Value())
return;
BControl::SetValue(value);
}
// SetEnabled // SetEnabled
void void
VolumeSlider::SetEnabled(bool enable) VolumeSlider::SetEnabled(bool enable)
+1
View File
@@ -25,6 +25,7 @@ class VolumeSlider : public BControl {
// BControl // BControl
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void SetValue(int32 value); virtual void SetValue(int32 value);
void SetValueNoInvoke(int32 value);
virtual void SetEnabled(bool enable); virtual void SetEnabled(bool enable);
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);