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:
@@ -27,30 +27,17 @@
|
||||
#define REDZONESTART 151
|
||||
|
||||
|
||||
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),
|
||||
|
||||
MixerControl::MixerControl(int32 volumeWhich, float *value, const char **error)
|
||||
:
|
||||
fAudioMixerNode(NULL),
|
||||
fParamWeb(NULL),
|
||||
fMixerParam(NULL)
|
||||
{
|
||||
// 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;
|
||||
fMixerParam(NULL),
|
||||
fMin(0.0),
|
||||
fMax(0.0),
|
||||
fStep(0.0)
|
||||
{
|
||||
bool retrying = false;
|
||||
fDontBeep = dontBeep;
|
||||
|
||||
fAudioMixerNode = new media_node();
|
||||
|
||||
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);
|
||||
|
||||
value = (chanData[0] - fMin) * 100 / ((fMax - fMin) ? (fMax - fMin) : 1);
|
||||
if (value)
|
||||
*value = (chanData[0] - fMin) * 100 / ((fMax - fMin) ? (fMax - fMin) : 1);
|
||||
}
|
||||
} else {
|
||||
errString = "No parameter web";
|
||||
@@ -173,32 +161,116 @@ VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
|
||||
delete fAudioMixerNode;
|
||||
fAudioMixerNode = NULL;
|
||||
}
|
||||
if (errString)
|
||||
fprintf(stderr, "VolumeSlider: %s.\n", errString);
|
||||
if (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,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER);
|
||||
AddChild(box);
|
||||
|
||||
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),
|
||||
errString == NULL ? "Volume" : errString, B_FOLLOW_LEFT | B_FOLLOW_TOP, (int32)value);
|
||||
box->AddChild(fSlider);
|
||||
|
||||
fSlider->SetTarget(this);
|
||||
|
||||
SetPulseRate(100);
|
||||
SetPulseRate(100);
|
||||
}
|
||||
|
||||
|
||||
VolumeSlider::~VolumeSlider()
|
||||
{
|
||||
delete fParamWeb;
|
||||
BMediaRoster* roster = BMediaRoster::CurrentRoster();
|
||||
if (roster && fAudioMixerNode)
|
||||
roster->ReleaseNode(*fAudioMixerNode);
|
||||
delete fMixerControl;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,14 +287,14 @@ VolumeSlider::MessageReceived(BMessage *msg)
|
||||
switch (msg->what) {
|
||||
case VOLUME_UPDATED:
|
||||
PRINT(("VOLUME_UPDATED\n"));
|
||||
UpdateVolume(fMixerParam);
|
||||
fMixerControl->UpdateVolume(fSlider->Value());
|
||||
fHasChanged = true;
|
||||
break;
|
||||
|
||||
case VOLUME_CHANGED:
|
||||
if (fHasChanged) {
|
||||
PRINT(("VOLUME_CHANGED\n"));
|
||||
UpdateVolume(fMixerParam);
|
||||
fMixerControl->UpdateVolume(fSlider->Value());
|
||||
if (!fDontBeep)
|
||||
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 -
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,21 @@
|
||||
#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 {
|
||||
public:
|
||||
SliderView(BRect rect, BMessage *msg, const char* title, uint32 resizeFlags,
|
||||
@@ -43,12 +58,7 @@ class VolumeSlider : public BWindow {
|
||||
void WindowActivated(bool active);
|
||||
|
||||
private:
|
||||
void UpdateVolume(BContinuousParameter* param);
|
||||
|
||||
media_node *fAudioMixerNode;
|
||||
BParameterWeb* fParamWeb;
|
||||
BContinuousParameter* fMixerParam;
|
||||
float fMin, fMax, fStep;
|
||||
MixerControl *fMixerControl;
|
||||
bool fHasChanged;
|
||||
bool fDontBeep;
|
||||
SliderView *fSlider;
|
||||
|
||||
@@ -233,7 +233,17 @@ MediaReplicant::MessageReceived(BMessage *message)
|
||||
case SET_VOLUME_WHICH:
|
||||
message->FindInt32("volwhich", &fVolumeWhich);
|
||||
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:
|
||||
BView::MessageReceived(message);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user