- fixed a possible div by 0

- don't let the volume knob move if the mixer isn't there.
- "don't beep" option
- other option: which gain to act on (mixer or phys output)
- now has a settings file


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5218 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2003-10-31 18:49:08 +00:00
parent dd9cf102be
commit 5622c96e08
3 changed files with 149 additions and 29 deletions

View File

@ -11,6 +11,7 @@
// Description: VolumeControl and link items in Deskbar
// Created : October 20, 2003
// Modified by: Jérome Duval
// Modified by: François Revol, 10/31/2003
//
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@ -29,7 +30,7 @@
#define VOLUME_CHANGED 'vlcg'
#define VOLUME_UPDATED 'vlud'
VolumeSlider::VolumeSlider(BRect frame)
VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
: BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0),
aOutNode(NULL),
paramWeb(NULL),
@ -50,6 +51,7 @@ VolumeSlider::VolumeSlider(BRect frame)
float value = 0.0;
bool retrying = false;
this->dontBeep = dontBeep;
aOutNode = new media_node();
@ -75,16 +77,51 @@ VolumeSlider::VolumeSlider(BRect frame)
}
if (roster && (err==B_OK)) {
//if((err = roster->GetAudioOutput(aOutNode)) == B_OK) {
if((err = roster->GetAudioMixer(aOutNode)) == B_OK) {
switch (volumeWhich) {
case VOLUME_USE_MIXER:
err = roster->GetAudioMixer(aOutNode);
break;
case VOLUME_USE_PHYS_OUTPUT:
err = roster->GetAudioOutput(aOutNode);
break;
}
if(err == B_OK) {
if((err = roster->GetParameterWebFor(*aOutNode, &paramWeb)) == B_OK) {
//Finding the Mixer slider in the audio output ParameterWeb
int32 numParams = paramWeb->CountParameters();
BParameter* p = NULL;
bool foundMixerLabel = false;
for (int i = 0; i < numParams; i++) {
p = paramWeb->ParameterAt(i);
PRINT(("BParameter[%i]: %s\n", i, p->Name()));
if (volumeWhich == VOLUME_USE_MIXER) {
if (!strcmp(p->Kind(), B_MASTER_GAIN))
break;
} else if (volumeWhich == VOLUME_USE_PHYS_OUTPUT) {
/* not all cards use the same name, and
* they don't seem to use Kind() == B_MASTER_GAIN
*/
if (!strcmp(p->Kind(), B_MASTER_GAIN))
break;
PRINT(("not MASTER_GAIN \n"));
/* some audio card
*/
if (!strcmp(p->Name(), "Master"))
break;
PRINT(("not 'Master' \n"));
/* some Ensonic card have all controls names 'Volume', so
* need to fint the one that has the 'Mixer' text label
*/
if (foundMixerLabel && !strcmp(p->Name(), "Volume"))
break;
if (!strcmp(p->Name(), "Mixer"))
foundMixerLabel = true;
PRINT(("not 'Mixer' \n"));
}
#if 0
//if (!strcmp(p->Name(), "Master")) {
if (!strcmp(p->Kind(), B_MASTER_GAIN)) {
for (; i < numParams; i++) {
@ -94,6 +131,8 @@ VolumeSlider::VolumeSlider(BRect frame)
}
break;
} else p = NULL;
#endif
p = NULL;
}
if (p==NULL) {
errString = "Could not find the mixer";
@ -112,7 +151,7 @@ VolumeSlider::VolumeSlider(BRect frame)
mixerParam->GetValue( &chanData, &size, &lastChange );
value = (chanData[0]-min)*100/(max-min);
value = (chanData[0]-min)*100/((max-min)?(max-min):1);
}
} else {
errString = "No parameter web";
@ -143,6 +182,8 @@ VolumeSlider::VolumeSlider(BRect frame)
AddChild(box);
hasChanged = false; /* make sure we don't beep if we don't change anything */
if (mixerParam == NULL)
value = -1;
slider = new SliderView(box->Bounds().InsetByCopy(1, 1), new BMessage(VOLUME_CHANGED),
(errString==NULL) ? "Volume" : errString, B_FOLLOW_LEFT | B_FOLLOW_TOP, value);
box->AddChild(slider);
@ -181,7 +222,8 @@ VolumeSlider::MessageReceived(BMessage *msg)
if (hasChanged) {
PRINT(("VOLUME_CHANGED\n"));
UpdateVolume(mixerParam);
beep();
if (!dontBeep)
beep();
}
Quit();
break;
@ -267,7 +309,7 @@ SliderView::Draw(BRect updateRect)
DrawBitmapAsync(&leftBitmap, BPoint(5,1));
DrawBitmapAsync(&rightBitmap, BPoint(193,1));
float position = 11 + (192-11) * Value() / 100;
float position = 11 + (192-11) * ((Value()==-1)?0:Value()) / 100;
float right = (position < REDZONESTART) ? position : REDZONESTART;
SetHighColor(99,151,99);
FillRect(BRect(11,3,right,4));
@ -312,7 +354,7 @@ SliderView::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
SetTracking(false);
}
if (!Bounds().InsetBySelf(2,2).Contains(point))
if ((Value() == -1) || !Bounds().InsetBySelf(2,2).Contains(point))
return;
float v = MIN(MAX(point.x, 11), 192);
@ -331,7 +373,7 @@ SliderView::MouseUp(BPoint point)
{
if (!IsTracking())
return;
if (Bounds().InsetBySelf(2,2).Contains(point)) {
if ((Value() != -1) && Bounds().InsetBySelf(2,2).Contains(point)) {
float v = MIN(MAX(point.x, 11), 192);
v = (v - 11) / (192-11) * 100;
v = MAX(MIN(v,100), 0);

View File

@ -11,6 +11,7 @@
// Description: VolumeControl and link items in Deskbar
// Created : October 20, 2003
// Modified by: Jérome Duval
// Modified by: François Revol, 10/31/2003
//
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
#ifndef VOLUMESLIDER_H
@ -21,6 +22,9 @@
#include <Bitmap.h>
#include <ParameterWeb.h>
#define VOLUME_USE_MIXER 0 /* default */
#define VOLUME_USE_PHYS_OUTPUT 1
class SliderView : public BControl
{
public:
@ -38,7 +42,7 @@ private:
class VolumeSlider : public BWindow
{
public:
VolumeSlider(BRect frame);
VolumeSlider(BRect frame, bool dontBeep=false, int32 volumeWhich=0);
~VolumeSlider();
void MessageReceived(BMessage*);
@ -50,6 +54,7 @@ private:
BContinuousParameter* mixerParam;
float min, max, step;
bool hasChanged;
bool dontBeep;
SliderView *slider;
};

View File

@ -11,6 +11,7 @@
// Description: VolumeControl and link items in Deskbar
// Created : October 20, 2003
// Modified by: Jérome Duval
// Modified by: François Revol, 10/31/2003
//
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
@ -28,6 +29,9 @@
#include <strings.h>
#include <List.h>
#include <String.h>
#include <Debug.h>
#include <FindDirectory.h>
#include <Path.h>
#include "VolumeSlider.h"
#include "DeskButton.h"
#include "iconfile.h"
@ -35,6 +39,10 @@
#define MEDIA_SETTINGS 'mese'
#define SOUND_SETTINGS 'sose'
#define OPEN_MEDIA_PLAYER 'omep'
#define TOGGLE_DONT_BEEP 'tdbp'
#define SET_VOLUME_WHICH 'svwh'
#define SETTINGS_FILE "x-vnd.OBOS.DeskbarVolumeControlSettings"
const char *app_signature = "application/x-vnd.be.desklink";
// the application signature used by the replicant to find the supporting
@ -66,8 +74,12 @@ public:
virtual void MessageReceived(BMessage *);
private:
void LoadSettings();
void SaveSettings();
BBitmap * segments;
VolumeSlider *volumeSlider;
bool confDontBeep; /* don't beep on volume change */
int32 confVolumeWhich; /* which volume parameter to act on (Mixer/Phys.Output) */
};
//
@ -100,6 +112,7 @@ VCButton::VCButton(BRect frame, const char *name,
BDragger *dragger = new BDragger(rect, this, B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
AddChild(dragger);
dragger->SetViewColor(B_TRANSPARENT_32_BIT);
LoadSettings();
}
@ -110,12 +123,14 @@ VCButton::VCButton(BMessage *message)
// Background Bitmap
segments = new BBitmap(BRect(0, 0, 16 - 1, 16 - 1), B_COLOR_8_BIT);
segments->SetBits(kSpeakerBits, 16*16, 0, B_COLOR_8_BIT);
LoadSettings();
}
VCButton::~VCButton()
{
delete segments;
SaveSettings();
}
@ -143,26 +158,32 @@ void
VCButton::MessageReceived(BMessage *message)
{
switch (message->what) {
case B_ABOUT_REQUESTED:
(new BAlert("About Volume Control", "Volume Control (Replicant)\n"
" Brought to you by Jérôme DUVAL.\n\n"
"OpenBeOS, 2003","OK"))->Go();
case B_ABOUT_REQUESTED:
(new BAlert("About Volume Control", "Volume Control (Replicant)\n"
" Brought to you by Jérôme DUVAL.\n\n"
"OpenBeOS, 2003","OK"))->Go();
break;
case OPEN_MEDIA_PLAYER:
// launch the media player app
be_roster->Launch("application/x-vnd.Be.MediaPlayer");
break;
case OPEN_MEDIA_PLAYER:
// launch the media player app
be_roster->Launch("application/x-vnd.Be.MediaPlayer");
break;
case MEDIA_SETTINGS:
// launch the media prefs app
be_roster->Launch("application/x-vnd.Be.MediaPrefs");
break;
case SOUND_SETTINGS:
// launch the sounds prefs app
be_roster->Launch("application/x-vnd.Be.SoundsPrefs");
break;
default:
BView::MessageReceived(message);
break;
case MEDIA_SETTINGS:
// launch the media prefs app
be_roster->Launch("application/x-vnd.Be.MediaPrefs");
break;
case SOUND_SETTINGS:
// launch the sounds prefs app
be_roster->Launch("application/x-vnd.Be.SoundsPrefs");
break;
case TOGGLE_DONT_BEEP:
confDontBeep = !confDontBeep;
break;
case SET_VOLUME_WHICH:
message->FindInt32("volwhich", &confVolumeWhich);
break;
default:
BView::MessageReceived(message);
break;
}
}
@ -193,13 +214,32 @@ VCButton::MouseDown(BPoint point)
menu->AddItem(new BMenuItem("Sound Settings...", new BMessage(SOUND_SETTINGS)));
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem("Open MediaPlayer", new BMessage(OPEN_MEDIA_PLAYER)));
menu->AddSeparatorItem();
BMenuItem *tmpItem = new BMenuItem("Dont beep", new BMessage(TOGGLE_DONT_BEEP));
menu->AddItem(tmpItem);
tmpItem->SetMarked(confDontBeep);
BMenu *volMenu = new BMenu("Act On");
volMenu->SetFont(be_plain_font);
BMessage *msg;
msg = new BMessage(SET_VOLUME_WHICH);
msg->AddInt32("volwhich", VOLUME_USE_MIXER);
tmpItem = new BMenuItem("System Mixer", msg);
tmpItem->SetMarked(confVolumeWhich == VOLUME_USE_MIXER);
volMenu->AddItem(tmpItem);
msg = new BMessage(SET_VOLUME_WHICH);
msg->AddInt32("volwhich", VOLUME_USE_PHYS_OUTPUT);
tmpItem = new BMenuItem("Physical Output", msg);
volMenu->AddItem(tmpItem);
tmpItem->SetMarked(confVolumeWhich == VOLUME_USE_PHYS_OUTPUT);
menu->AddItem(volMenu);
menu->SetTargetForItems(this);
volMenu->SetTargetForItems(this);
menu->Go(where, true, true, BRect(where - BPoint(4, 4),
where + BPoint(4, 4)));
} else if (mouseButtons & B_PRIMARY_MOUSE_BUTTON) {
// Show VolumeSlider
volumeSlider = new VolumeSlider(BRect(where.x,where.y,where.x+207,where.y+19));
volumeSlider = new VolumeSlider(BRect(where.x,where.y,where.x+207,where.y+19), confDontBeep, confVolumeWhich);
volumeSlider->Show();
}
}
@ -211,7 +251,40 @@ VCButton::MouseUp(BPoint point)
/* don't Quit() ! thanks for FFM users */
}
void VCButton::LoadSettings()
{
confDontBeep = false;
confVolumeWhich = VOLUME_USE_MIXER;
BPath p;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &p, false) < B_OK)
return;
p.SetTo(p.Path(), SETTINGS_FILE);
BFile settings(p.Path(), B_READ_ONLY);
if (settings.InitCheck() < B_OK)
return;
BMessage msg;
if (msg.Unflatten(&settings) < B_OK)
return;
msg.FindInt32("volwhich", &confVolumeWhich);
msg.FindBool("dontbeep", &confDontBeep);
}
void VCButton::SaveSettings()
{
BPath p;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &p, false) < B_OK)
return;
p.SetTo(p.Path(), SETTINGS_FILE);
BFile settings(p.Path(), B_WRITE_ONLY|B_CREATE_FILE|B_ERASE_FILE);
if (settings.InitCheck() < B_OK)
return;
BMessage msg('CNFG');
msg.AddInt32("volwhich", confVolumeWhich);
msg.AddBool("dontbeep", confDontBeep);
ssize_t len=0;
if (msg.Flatten(&settings, &len) < B_OK)
return;
}
int