- use the Mixer volume
- update volume when sliding - FocusFollowsMouse fixes - media_server restart fix git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5217 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
#include "iconfile.h"
|
#include "iconfile.h"
|
||||||
|
|
||||||
#define VOLUME_CHANGED 'vlcg'
|
#define VOLUME_CHANGED 'vlcg'
|
||||||
|
#define VOLUME_UPDATED 'vlud'
|
||||||
|
|
||||||
VolumeSlider::VolumeSlider(BRect frame)
|
VolumeSlider::VolumeSlider(BRect frame)
|
||||||
: BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0),
|
: BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0),
|
||||||
@@ -48,14 +49,34 @@ VolumeSlider::VolumeSlider(BRect frame)
|
|||||||
MoveBy(0, kMargin + screenFrame.top - windowRect.top);
|
MoveBy(0, kMargin + screenFrame.top - windowRect.top);
|
||||||
|
|
||||||
float value = 0.0;
|
float value = 0.0;
|
||||||
|
bool retrying = false;
|
||||||
|
|
||||||
aOutNode = new media_node();
|
aOutNode = new media_node();
|
||||||
|
|
||||||
status_t err;
|
status_t err = B_OK; /* BMediaRoster::Roster() doesn't set it if all is ok */
|
||||||
|
const char *errString = NULL;
|
||||||
BMediaRoster* roster = BMediaRoster::Roster(&err);
|
BMediaRoster* roster = BMediaRoster::Roster(&err);
|
||||||
|
|
||||||
if(roster && (err==B_OK)) {
|
retry:
|
||||||
if((err = roster->GetAudioOutput(aOutNode)) == B_OK) {
|
/* here we release the BMediaRoster once if we can't access the system mixer,
|
||||||
|
* to make sure it really isn't there, and it's not BMediaRoster that is messed up.
|
||||||
|
*/
|
||||||
|
if (retrying) {
|
||||||
|
errString = NULL;
|
||||||
|
PRINT(("retrying to get a Media Roster\n"));
|
||||||
|
/* BMediaRoster looks doomed */
|
||||||
|
roster = BMediaRoster::CurrentRoster();
|
||||||
|
if (roster) {
|
||||||
|
roster->Lock();
|
||||||
|
roster->Quit();
|
||||||
|
}
|
||||||
|
snooze(10000);
|
||||||
|
roster = BMediaRoster::Roster(&err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roster && (err==B_OK)) {
|
||||||
|
//if((err = roster->GetAudioOutput(aOutNode)) == B_OK) {
|
||||||
|
if((err = roster->GetAudioMixer(aOutNode)) == B_OK) {
|
||||||
if((err = roster->GetParameterWebFor(*aOutNode, ¶mWeb)) == B_OK) {
|
if((err = roster->GetParameterWebFor(*aOutNode, ¶mWeb)) == B_OK) {
|
||||||
|
|
||||||
//Finding the Mixer slider in the audio output ParameterWeb
|
//Finding the Mixer slider in the audio output ParameterWeb
|
||||||
@@ -63,8 +84,9 @@ VolumeSlider::VolumeSlider(BRect frame)
|
|||||||
BParameter* p = NULL;
|
BParameter* p = NULL;
|
||||||
for (int i = 0; i < numParams; i++) {
|
for (int i = 0; i < numParams; i++) {
|
||||||
p = paramWeb->ParameterAt(i);
|
p = paramWeb->ParameterAt(i);
|
||||||
printf("%i %s\n", i, p->Name());
|
PRINT(("BParameter[%i]: %s\n", i, p->Name()));
|
||||||
if (!strcmp(p->Name(), "Master")) {
|
//if (!strcmp(p->Name(), "Master")) {
|
||||||
|
if (!strcmp(p->Kind(), B_MASTER_GAIN)) {
|
||||||
for (; i < numParams; i++) {
|
for (; i < numParams; i++) {
|
||||||
p = paramWeb->ParameterAt(i);
|
p = paramWeb->ParameterAt(i);
|
||||||
if (strcmp(p->Kind(), B_MASTER_GAIN)) p=NULL;
|
if (strcmp(p->Kind(), B_MASTER_GAIN)) p=NULL;
|
||||||
@@ -74,45 +96,55 @@ VolumeSlider::VolumeSlider(BRect frame)
|
|||||||
} else p = NULL;
|
} else p = NULL;
|
||||||
}
|
}
|
||||||
if (p==NULL) {
|
if (p==NULL) {
|
||||||
printf("Could not find the mixer.\n");
|
errString = "Could not find the mixer";
|
||||||
exit(1);
|
|
||||||
} else if(p->Type()!=BParameter::B_CONTINUOUS_PARAMETER) {
|
} else if(p->Type()!=BParameter::B_CONTINUOUS_PARAMETER) {
|
||||||
printf("Mixer is unknown.\n");
|
errString = "Mixer is unknown";
|
||||||
exit(2);
|
} else {
|
||||||
|
|
||||||
|
mixerParam = dynamic_cast<BContinuousParameter*>(p);
|
||||||
|
min = mixerParam->MinValue();
|
||||||
|
max = mixerParam->MaxValue();
|
||||||
|
step = mixerParam->ValueStep();
|
||||||
|
|
||||||
|
float chanData[2];
|
||||||
|
bigtime_t lastChange;
|
||||||
|
size_t size = sizeof(chanData);
|
||||||
|
|
||||||
|
mixerParam->GetValue( &chanData, &size, &lastChange );
|
||||||
|
|
||||||
|
value = (chanData[0]-min)*100/(max-min);
|
||||||
}
|
}
|
||||||
|
|
||||||
mixerParam= dynamic_cast<BContinuousParameter*>(p);
|
|
||||||
min = mixerParam->MinValue();
|
|
||||||
max = mixerParam->MaxValue();
|
|
||||||
step = mixerParam->ValueStep();
|
|
||||||
|
|
||||||
float chanData[2];
|
|
||||||
bigtime_t lastChange;
|
|
||||||
size_t size = sizeof(chanData);
|
|
||||||
|
|
||||||
mixerParam->GetValue( &chanData, &size, &lastChange );
|
|
||||||
|
|
||||||
value = (chanData[0]-min)*100/(max-min);
|
|
||||||
} else {
|
} else {
|
||||||
printf("No parameter web\n");
|
errString = "No parameter web";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("No Audio output\n");
|
if (!retrying) {
|
||||||
|
retrying = true;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
errString = "No Audio output";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("No Media Roster\n");
|
if (!retrying) {
|
||||||
|
retrying = true;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
errString = "No Media Roster";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(err!=B_OK) {
|
if(err!=B_OK) {
|
||||||
delete aOutNode;
|
delete aOutNode;
|
||||||
aOutNode = NULL;
|
aOutNode = NULL;
|
||||||
}
|
}
|
||||||
|
if (errString)
|
||||||
|
fprintf(stderr, "VolumeSlider: %s.\n", errString);
|
||||||
|
|
||||||
BBox *box = new BBox(Bounds(), "sliderbox", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER);
|
BBox *box = new BBox(Bounds(), "sliderbox", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER);
|
||||||
AddChild(box);
|
AddChild(box);
|
||||||
|
|
||||||
|
hasChanged = false; /* make sure we don't beep if we don't change anything */
|
||||||
slider = new SliderView(box->Bounds().InsetByCopy(1, 1), new BMessage(VOLUME_CHANGED),
|
slider = new SliderView(box->Bounds().InsetByCopy(1, 1), new BMessage(VOLUME_CHANGED),
|
||||||
mixerParam ? "Volume" : "No Media Server", B_FOLLOW_LEFT | B_FOLLOW_TOP, value);
|
(errString==NULL) ? "Volume" : errString, B_FOLLOW_LEFT | B_FOLLOW_TOP, value);
|
||||||
box->AddChild(slider);
|
box->AddChild(slider);
|
||||||
|
|
||||||
slider->SetTarget(this);
|
slider->SetTarget(this);
|
||||||
@@ -133,45 +165,49 @@ VolumeSlider::~VolumeSlider()
|
|||||||
void
|
void
|
||||||
VolumeSlider::WindowActivated(bool active)
|
VolumeSlider::WindowActivated(bool active)
|
||||||
{
|
{
|
||||||
if (!active) {
|
/* don't Quit() ! thanks for FFM users */
|
||||||
Lock();
|
|
||||||
Quit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VolumeSlider::MessageReceived(BMessage *msg)
|
VolumeSlider::MessageReceived(BMessage *msg)
|
||||||
{
|
{
|
||||||
switch (msg->what) {
|
switch (msg->what) {
|
||||||
case VOLUME_CHANGED:
|
case VOLUME_UPDATED:
|
||||||
{
|
PRINT(("VOLUME_UPDATED\n"));
|
||||||
printf("VOLUME_CHANGED\n");
|
UpdateVolume(mixerParam);
|
||||||
if(mixerParam) {
|
hasChanged = true;
|
||||||
float chanData[2];
|
break;
|
||||||
bigtime_t lastChange;
|
case VOLUME_CHANGED:
|
||||||
size_t size = sizeof(chanData);
|
if (hasChanged) {
|
||||||
|
PRINT(("VOLUME_CHANGED\n"));
|
||||||
mixerParam->GetValue( &chanData, &size, &lastChange );
|
UpdateVolume(mixerParam);
|
||||||
|
beep();
|
||||||
for( int i=0; i<2; i++) {
|
|
||||||
chanData[i] = (slider->Value() * (max - min) / 100) / step * step + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRINT(("Min value: %f Max Value: %f\nData: %f %f\n", mixerParam->MinValue(), mixerParam->MaxValue(), chanData[0], chanData[1]));
|
|
||||||
mixerParam->SetValue(&chanData, sizeof(chanData), 0);
|
|
||||||
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
|
|
||||||
Quit();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
Quit();
|
||||||
BWindow::MessageReceived(msg); // not a slider message, not our problem
|
break;
|
||||||
|
default:
|
||||||
|
BWindow::MessageReceived(msg); // not a slider message, not our problem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VolumeSlider::UpdateVolume(BContinuousParameter* param)
|
||||||
|
{
|
||||||
|
if (!param)
|
||||||
|
return;
|
||||||
|
float chanData[2];
|
||||||
|
bigtime_t lastChange;
|
||||||
|
size_t size = sizeof(chanData);
|
||||||
|
|
||||||
|
mixerParam->GetValue( &chanData, &size, &lastChange );
|
||||||
|
|
||||||
|
for( int i=0; i<2; i++) {
|
||||||
|
chanData[i] = (slider->Value() * (max - min) / 100) / step * step + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT(("Min value: %f Max Value: %f\nData: %f %f\n", mixerParam->MinValue(), mixerParam->MaxValue(), chanData[0], chanData[1]));
|
||||||
|
mixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000);
|
||||||
|
}
|
||||||
|
|
||||||
#define REDZONESTART 151
|
#define REDZONESTART 151
|
||||||
|
|
||||||
|
|
||||||
@@ -180,7 +216,6 @@ SliderView::SliderView(BRect rect, BMessage *msg, const char *title, uint32 resi
|
|||||||
leftBitmap(BRect(0, 0, kLeftWidth - 1, kLeftHeight - 1), B_CMAP8),
|
leftBitmap(BRect(0, 0, kLeftWidth - 1, kLeftHeight - 1), B_CMAP8),
|
||||||
rightBitmap(BRect(0, 0, kRightWidth - 1, kRightHeight - 1), B_CMAP8),
|
rightBitmap(BRect(0, 0, kRightWidth - 1, kRightHeight - 1), B_CMAP8),
|
||||||
buttonBitmap(BRect(0, 0, kButtonWidth - 1, kButtonHeight - 1), B_CMAP8),
|
buttonBitmap(BRect(0, 0, kButtonWidth - 1, kButtonHeight - 1), B_CMAP8),
|
||||||
fTrackingX(11 + (192-11) * value / 100),
|
|
||||||
fTitle(title)
|
fTitle(title)
|
||||||
{
|
{
|
||||||
leftBitmap.SetBits(kLeftBits, kLeftWidth * kLeftHeight, 0, B_CMAP8);
|
leftBitmap.SetBits(kLeftBits, kLeftWidth * kLeftHeight, 0, B_CMAP8);
|
||||||
@@ -205,11 +240,9 @@ SliderView::Pulse()
|
|||||||
uint32 mouseButtons;
|
uint32 mouseButtons;
|
||||||
BPoint where;
|
BPoint where;
|
||||||
GetMouse(&where, &mouseButtons, true);
|
GetMouse(&where, &mouseButtons, true);
|
||||||
|
|
||||||
// button not pressed, exit
|
// button not pressed, exit
|
||||||
if (! (mouseButtons & B_PRIMARY_MOUSE_BUTTON)) {
|
if (! (mouseButtons & B_PRIMARY_MOUSE_BUTTON)) {
|
||||||
SetTracking(false);
|
SetTracking(false);
|
||||||
SetValue( (fTrackingX - 11) / (192-11) * 100 );
|
|
||||||
Invoke();
|
Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,19 +267,20 @@ SliderView::Draw(BRect updateRect)
|
|||||||
DrawBitmapAsync(&leftBitmap, BPoint(5,1));
|
DrawBitmapAsync(&leftBitmap, BPoint(5,1));
|
||||||
DrawBitmapAsync(&rightBitmap, BPoint(193,1));
|
DrawBitmapAsync(&rightBitmap, BPoint(193,1));
|
||||||
|
|
||||||
float right = (fTrackingX < REDZONESTART) ? fTrackingX : REDZONESTART;
|
float position = 11 + (192-11) * Value() / 100;
|
||||||
|
float right = (position < REDZONESTART) ? position : REDZONESTART;
|
||||||
SetHighColor(99,151,99);
|
SetHighColor(99,151,99);
|
||||||
FillRect(BRect(11,3,right,4));
|
FillRect(BRect(11,3,right,4));
|
||||||
SetHighColor(156,203,156);
|
SetHighColor(156,203,156);
|
||||||
FillRect(BRect(11,5,right,13));
|
FillRect(BRect(11,5,right,13));
|
||||||
if(right == REDZONESTART) {
|
if(right == REDZONESTART) {
|
||||||
SetHighColor(156,101,99);
|
SetHighColor(156,101,99);
|
||||||
FillRect(BRect(REDZONESTART,3,fTrackingX,4));
|
FillRect(BRect(REDZONESTART,3,position,4));
|
||||||
SetHighColor(255,154,156);
|
SetHighColor(255,154,156);
|
||||||
FillRect(BRect(REDZONESTART,5,fTrackingX,13));
|
FillRect(BRect(REDZONESTART,5,position,13));
|
||||||
}
|
}
|
||||||
SetHighColor(156,154,156);
|
SetHighColor(156,154,156);
|
||||||
FillRect(BRect(fTrackingX,3,192,13));
|
FillRect(BRect(position,3,192,13));
|
||||||
|
|
||||||
BFont font;
|
BFont font;
|
||||||
float width = font.StringWidth(fTitle);
|
float width = font.StringWidth(fTitle);
|
||||||
@@ -254,7 +288,7 @@ SliderView::Draw(BRect updateRect)
|
|||||||
SetHighColor(49,154,49);
|
SetHighColor(49,154,49);
|
||||||
DrawString(fTitle, BPoint(11 + (192-11-width)/2, 12));
|
DrawString(fTitle, BPoint(11 + (192-11-width)/2, 12));
|
||||||
|
|
||||||
DrawBitmapAsync(&buttonBitmap, BPoint(fTrackingX-5,3));
|
DrawBitmapAsync(&buttonBitmap, BPoint(position-5,3));
|
||||||
|
|
||||||
Sync();
|
Sync();
|
||||||
|
|
||||||
@@ -281,14 +315,14 @@ SliderView::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
|
|||||||
if (!Bounds().InsetBySelf(2,2).Contains(point))
|
if (!Bounds().InsetBySelf(2,2).Contains(point))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fTrackingX = point.x;
|
float v = MIN(MAX(point.x, 11), 192);
|
||||||
if(fTrackingX < 11)
|
v = (v - 11) / (192-11) * 100;
|
||||||
fTrackingX = 11;
|
v = MAX(MIN(v,100), 0);
|
||||||
if(fTrackingX > 192)
|
SetValue(v);
|
||||||
fTrackingX = 192;
|
|
||||||
Draw(Bounds());
|
Draw(Bounds());
|
||||||
Flush();
|
Flush();
|
||||||
|
if (Window())
|
||||||
|
Window()->PostMessage(VOLUME_UPDATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -297,20 +331,15 @@ SliderView::MouseUp(BPoint point)
|
|||||||
{
|
{
|
||||||
if (!IsTracking())
|
if (!IsTracking())
|
||||||
return;
|
return;
|
||||||
|
if (Bounds().InsetBySelf(2,2).Contains(point)) {
|
||||||
SetValue( (point.x - 11) / (192-11) * 100 );
|
float v = MIN(MAX(point.x, 11), 192);
|
||||||
if(Value()<0)
|
v = (v - 11) / (192-11) * 100;
|
||||||
SetValue(0);
|
v = MAX(MIN(v,100), 0);
|
||||||
if(Value()>100)
|
SetValue(v);
|
||||||
SetValue(100);
|
}
|
||||||
|
|
||||||
Invoke();
|
Invoke();
|
||||||
SetTracking(false);
|
SetTracking(false);
|
||||||
fTrackingX = point.x;
|
|
||||||
if(fTrackingX < 11)
|
|
||||||
fTrackingX = 11;
|
|
||||||
if(fTrackingX > 192)
|
|
||||||
fTrackingX = 192;
|
|
||||||
Draw(Bounds());
|
Draw(Bounds());
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ public:
|
|||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
private:
|
private:
|
||||||
BBitmap leftBitmap, rightBitmap, buttonBitmap;
|
BBitmap leftBitmap, rightBitmap, buttonBitmap;
|
||||||
float fTrackingX;
|
|
||||||
const char* fTitle;
|
const char* fTitle;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,10 +44,12 @@ public:
|
|||||||
void MessageReceived(BMessage*);
|
void MessageReceived(BMessage*);
|
||||||
void WindowActivated(bool active);
|
void WindowActivated(bool active);
|
||||||
private:
|
private:
|
||||||
|
void UpdateVolume(BContinuousParameter* param);
|
||||||
media_node *aOutNode;
|
media_node *aOutNode;
|
||||||
BParameterWeb* paramWeb;
|
BParameterWeb* paramWeb;
|
||||||
BContinuousParameter* mixerParam;
|
BContinuousParameter* mixerParam;
|
||||||
float min, max, step;
|
float min, max, step;
|
||||||
|
bool hasChanged;
|
||||||
SliderView *slider;
|
SliderView *slider;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -208,12 +208,7 @@ VCButton::MouseDown(BPoint point)
|
|||||||
void
|
void
|
||||||
VCButton::MouseUp(BPoint point)
|
VCButton::MouseUp(BPoint point)
|
||||||
{
|
{
|
||||||
if(volumeSlider) {
|
/* don't Quit() ! thanks for FFM users */
|
||||||
volumeSlider->Lock();
|
|
||||||
volumeSlider->Quit();
|
|
||||||
delete volumeSlider;
|
|
||||||
volumeSlider = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user