Scrolling up/down above Volume Control in deskbar's shelf now changes volume (bug #2323).

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28575 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2008-11-09 16:13:41 +00:00
parent 019ed09bee
commit aea6792976
3 changed files with 132 additions and 62 deletions
+104 -54
View File
@@ -27,30 +27,17 @@
#define REDZONESTART 151 #define REDZONESTART 151
VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
: BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL, MixerControl::MixerControl(int32 volumeWhich, float *value, const char **error)
B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0), :
fAudioMixerNode(NULL), fAudioMixerNode(NULL),
fParamWeb(NULL), fParamWeb(NULL),
fMixerParam(NULL) fMixerParam(NULL),
{ fMin(0.0),
// Make sure it's not outside the screen. fMax(0.0),
const int32 kMargin = 3; fStep(0.0)
BRect windowRect = ConvertToScreen(Bounds()); {
BRect screenFrame(BScreen(B_MAIN_SCREEN_ID).Frame());
if (screenFrame.right < windowRect.right + kMargin)
MoveBy(- kMargin - windowRect.right + screenFrame.right, 0);
if (screenFrame.bottom < windowRect.bottom + kMargin)
MoveBy(0, - kMargin - windowRect.bottom + screenFrame.bottom);
if (screenFrame.left > windowRect.left - kMargin)
MoveBy(kMargin + screenFrame.left - windowRect.left, 0);
if (screenFrame.top > windowRect.top - kMargin)
MoveBy(0, kMargin + screenFrame.top - windowRect.top);
float value = 0.0;
bool retrying = false; bool retrying = false;
fDontBeep = dontBeep;
fAudioMixerNode = new media_node(); fAudioMixerNode = new media_node();
status_t err = B_OK; /* BMediaRoster::Roster() doesn't set it if all is ok */ status_t err = B_OK; /* BMediaRoster::Roster() doesn't set it if all is ok */
@@ -149,7 +136,8 @@ VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
fMixerParam->GetValue(&chanData, &size, &lastChange); fMixerParam->GetValue(&chanData, &size, &lastChange);
value = (chanData[0] - fMin) * 100 / ((fMax - fMin) ? (fMax - fMin) : 1); if (value)
*value = (chanData[0] - fMin) * 100 / ((fMax - fMin) ? (fMax - fMin) : 1);
} }
} else { } else {
errString = "No parameter web"; errString = "No parameter web";
@@ -173,16 +161,103 @@ VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
delete fAudioMixerNode; delete fAudioMixerNode;
fAudioMixerNode = NULL; fAudioMixerNode = NULL;
} }
if (errString) if (errString) {
fprintf(stderr, "VolumeSlider: %s.\n", errString); fprintf(stderr, "MixerControl: %s.\n", errString);
if (error)
*error = errString;
}
if (fMixerParam == NULL)
*value = -1;
}
MixerControl::~MixerControl()
{
delete fParamWeb;
BMediaRoster* roster = BMediaRoster::CurrentRoster();
if (roster && fAudioMixerNode)
roster->ReleaseNode(*fAudioMixerNode);
}
void
MixerControl::UpdateVolume(int32 value)
{
if (!fMixerParam)
return;
float chanData[2];
bigtime_t lastChange;
size_t size = sizeof(chanData);
fMixerParam->GetValue(&chanData, &size, &lastChange);
for (int i = 0; i < 2; i++) {
chanData[i] = (value * (fMax - fMin) / 100) / fStep * fStep + fMin;
}
PRINT(("Min value: %f Max Value: %f\nData: %f %f\n",
fMixerParam->MinValue(), fMixerParam->MaxValue(), chanData[0], chanData[1]));
fMixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000);
}
void
MixerControl::ChangeVolumeBy(int32 value)
{
if (!fMixerParam)
return;
float chanData[2];
bigtime_t lastChange;
size_t size = sizeof(chanData);
fMixerParam->GetValue(&chanData, &size, &lastChange);
for (int i = 0; i < 2; i++) {
chanData[i] += fStep * value;
if (chanData[i] < fMin)
chanData[i] = fMin;
else if (chanData[i] > fMax)
chanData[i] = fMax;
}
PRINT(("Min value: %f Max Value: %f\nData: %f %f\n",
fMixerParam->MinValue(), fMixerParam->MaxValue(), chanData[0], chanData[1]));
fMixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000);
}
// #pragma mark -
VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
: BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0)
{
// Make sure it's not outside the screen.
const int32 kMargin = 3;
BRect windowRect = ConvertToScreen(Bounds());
BRect screenFrame(BScreen(B_MAIN_SCREEN_ID).Frame());
if (screenFrame.right < windowRect.right + kMargin)
MoveBy(- kMargin - windowRect.right + screenFrame.right, 0);
if (screenFrame.bottom < windowRect.bottom + kMargin)
MoveBy(0, - kMargin - windowRect.bottom + screenFrame.bottom);
if (screenFrame.left > windowRect.left - kMargin)
MoveBy(kMargin + screenFrame.left - windowRect.left, 0);
if (screenFrame.top > windowRect.top - kMargin)
MoveBy(0, kMargin + screenFrame.top - windowRect.top);
float value = 0.0;
fDontBeep = dontBeep;
const char *errString;
fMixerControl = new MixerControl(volumeWhich, &value, &errString);
BBox *box = new BBox(Bounds(), "sliderbox", B_FOLLOW_LEFT | B_FOLLOW_TOP, BBox *box = new BBox(Bounds(), "sliderbox", B_FOLLOW_LEFT | B_FOLLOW_TOP,
B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER); B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER);
AddChild(box); AddChild(box);
fHasChanged = false; /* make sure we don't beep if we don't change anything */ fHasChanged = false; /* make sure we don't beep if we don't change anything */
if (fMixerParam == NULL)
value = -1;
fSlider = new SliderView(box->Bounds().InsetByCopy(1, 1), new BMessage(VOLUME_CHANGED), fSlider = new SliderView(box->Bounds().InsetByCopy(1, 1), new BMessage(VOLUME_CHANGED),
errString == NULL ? "Volume" : errString, B_FOLLOW_LEFT | B_FOLLOW_TOP, (int32)value); errString == NULL ? "Volume" : errString, B_FOLLOW_LEFT | B_FOLLOW_TOP, (int32)value);
box->AddChild(fSlider); box->AddChild(fSlider);
@@ -195,10 +270,7 @@ VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
VolumeSlider::~VolumeSlider() VolumeSlider::~VolumeSlider()
{ {
delete fParamWeb; delete fMixerControl;
BMediaRoster* roster = BMediaRoster::CurrentRoster();
if (roster && fAudioMixerNode)
roster->ReleaseNode(*fAudioMixerNode);
} }
@@ -215,14 +287,14 @@ VolumeSlider::MessageReceived(BMessage *msg)
switch (msg->what) { switch (msg->what) {
case VOLUME_UPDATED: case VOLUME_UPDATED:
PRINT(("VOLUME_UPDATED\n")); PRINT(("VOLUME_UPDATED\n"));
UpdateVolume(fMixerParam); fMixerControl->UpdateVolume(fSlider->Value());
fHasChanged = true; fHasChanged = true;
break; break;
case VOLUME_CHANGED: case VOLUME_CHANGED:
if (fHasChanged) { if (fHasChanged) {
PRINT(("VOLUME_CHANGED\n")); PRINT(("VOLUME_CHANGED\n"));
UpdateVolume(fMixerParam); fMixerControl->UpdateVolume(fSlider->Value());
if (!fDontBeep) if (!fDontBeep)
beep(); beep();
} }
@@ -235,28 +307,6 @@ VolumeSlider::MessageReceived(BMessage *msg)
} }
void
VolumeSlider::UpdateVolume(BContinuousParameter* param)
{
if (!param)
return;
float chanData[2];
bigtime_t lastChange;
size_t size = sizeof(chanData);
fMixerParam->GetValue( &chanData, &size, &lastChange );
for (int i = 0; i < 2; i++) {
chanData[i] = (fSlider->Value() * (fMax - fMin) / 100) / fStep * fStep + fMin;
}
PRINT(("Min value: %f Max Value: %f\nData: %f %f\n",
fMixerParam->MinValue(), fMixerParam->MaxValue(), chanData[0], chanData[1]));
fMixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000);
}
// #pragma mark - // #pragma mark -
+16 -6
View File
@@ -18,6 +18,21 @@
#define VOLUME_USE_PHYS_OUTPUT 1 #define VOLUME_USE_PHYS_OUTPUT 1
class MixerControl {
public:
MixerControl(int32 volumeWhich, float *value = NULL, const char **error = NULL);
~MixerControl();
void UpdateVolume(int32 value);
void ChangeVolumeBy(int32 incr);
private:
media_node *fAudioMixerNode;
BParameterWeb* fParamWeb;
BContinuousParameter* fMixerParam;
float fMin, fMax, fStep;
};
class SliderView : public BControl { class SliderView : public BControl {
public: public:
SliderView(BRect rect, BMessage *msg, const char* title, uint32 resizeFlags, SliderView(BRect rect, BMessage *msg, const char* title, uint32 resizeFlags,
@@ -43,12 +58,7 @@ class VolumeSlider : public BWindow {
void WindowActivated(bool active); void WindowActivated(bool active);
private: private:
void UpdateVolume(BContinuousParameter* param); MixerControl *fMixerControl;
media_node *fAudioMixerNode;
BParameterWeb* fParamWeb;
BContinuousParameter* fMixerParam;
float fMin, fMax, fStep;
bool fHasChanged; bool fHasChanged;
bool fDontBeep; bool fDontBeep;
SliderView *fSlider; SliderView *fSlider;
+10
View File
@@ -234,6 +234,16 @@ MediaReplicant::MessageReceived(BMessage *message)
message->FindInt32("volwhich", &fVolumeWhich); message->FindInt32("volwhich", &fVolumeWhich);
break; break;
case B_MOUSE_WHEEL_CHANGED:
{
float dy;
if (message->FindFloat("be:wheel_delta_y", &dy) == B_OK
&& dy != 0.0) {
MixerControl mixerControl(fVolumeWhich);
mixerControl.ChangeVolumeBy(dy < 0 ? 20 : -20);
}
break;
}
default: default:
BView::MessageReceived(message); BView::MessageReceived(message);
break; break;