DefaultMediaTheme: improve watching for parameter value changes.
* Addresses TODO of sub-classing controls, registering with the media roster for parameter changes. * Also adds support for discrete parameter controls, which didn't have this functionality. * With this change, the controls no longer need to be focused or modified for the parameter changes to register.
This commit is contained in:
parent
939b40d65c
commit
9c7d2b4668
@ -105,6 +105,51 @@ class TitleView : public BView {
|
|||||||
const char *fTitle;
|
const char *fTitle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CheckBox : public BCheckBox {
|
||||||
|
public:
|
||||||
|
CheckBox(BRect area, const char* name, const char* label,
|
||||||
|
BDiscreteParameter ¶meter);
|
||||||
|
virtual ~CheckBox();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
private:
|
||||||
|
BDiscreteParameter &fParameter;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OptionPopUp : public BOptionPopUp {
|
||||||
|
public:
|
||||||
|
OptionPopUp(BRect area, const char* name, const char* label,
|
||||||
|
BDiscreteParameter ¶meter);
|
||||||
|
virtual ~OptionPopUp();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
private:
|
||||||
|
BDiscreteParameter &fParameter;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Slider : public BSlider {
|
||||||
|
public:
|
||||||
|
Slider(BRect area, const char* name, const char*label, int32 minValue,
|
||||||
|
int32 maxValue, BContinuousParameter ¶meter);
|
||||||
|
virtual ~Slider();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
private:
|
||||||
|
BContinuousParameter &fParameter;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChannelSlider : public BChannelSlider {
|
||||||
|
public:
|
||||||
|
ChannelSlider(BRect area, const char* name, const char* label,
|
||||||
|
orientation orientation, int32 channels,
|
||||||
|
BContinuousParameter ¶meter);
|
||||||
|
virtual ~ChannelSlider();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
private:
|
||||||
|
BContinuousParameter &fParameter;
|
||||||
|
};
|
||||||
|
|
||||||
class MessageFilter : public BMessageFilter {
|
class MessageFilter : public BMessageFilter {
|
||||||
public:
|
public:
|
||||||
static MessageFilter *FilterFor(BView *view, BParameter ¶meter);
|
static MessageFilter *FilterFor(BView *view, BParameter ¶meter);
|
||||||
@ -126,7 +171,6 @@ class ContinuousMessageFilter : public MessageFilter {
|
|||||||
|
|
||||||
BControl *fControl;
|
BControl *fControl;
|
||||||
BContinuousParameter &fParameter;
|
BContinuousParameter &fParameter;
|
||||||
bool fRegistered;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DiscreteMessageFilter : public MessageFilter {
|
class DiscreteMessageFilter : public MessageFilter {
|
||||||
@ -165,6 +209,25 @@ parameter_should_be_hidden(BParameter ¶meter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_watching_for_parameter_changes(BControl* control, BParameter ¶meter)
|
||||||
|
{
|
||||||
|
if (BMediaRoster* roster = BMediaRoster::CurrentRoster()) {
|
||||||
|
roster->StartWatching(control, parameter.Web()->Node(),
|
||||||
|
B_MEDIA_NEW_PARAMETER_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_watching_for_parameter_changes(BControl* control, BParameter ¶meter)
|
||||||
|
{
|
||||||
|
if (BMediaRoster* roster = BMediaRoster::CurrentRoster()) {
|
||||||
|
roster->StopWatching(control, parameter.Web()->Node(),
|
||||||
|
B_MEDIA_NEW_PARAMETER_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@ -557,6 +620,93 @@ TitleView::GetPreferredSize(float *_width, float *_height)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
CheckBox::CheckBox(BRect area, const char* name, const char* label,
|
||||||
|
BDiscreteParameter ¶meter)
|
||||||
|
: BCheckBox(area, name, label, NULL),
|
||||||
|
fParameter(parameter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CheckBox::~CheckBox()
|
||||||
|
{
|
||||||
|
stop_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CheckBox::AttachedToWindow()
|
||||||
|
{
|
||||||
|
start_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OptionPopUp::OptionPopUp(BRect area, const char* name, const char* label,
|
||||||
|
BDiscreteParameter ¶meter)
|
||||||
|
: BOptionPopUp(area, name, label, NULL),
|
||||||
|
fParameter(parameter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OptionPopUp::~OptionPopUp()
|
||||||
|
{
|
||||||
|
stop_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OptionPopUp::AttachedToWindow()
|
||||||
|
{
|
||||||
|
start_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Slider::Slider(BRect area, const char* name, const char* label, int32 minValue,
|
||||||
|
int32 maxValue, BContinuousParameter ¶meter)
|
||||||
|
: BSlider(area, name, label, NULL, minValue, maxValue),
|
||||||
|
fParameter(parameter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Slider::~Slider()
|
||||||
|
{
|
||||||
|
stop_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Slider::AttachedToWindow()
|
||||||
|
{
|
||||||
|
start_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ChannelSlider::ChannelSlider(BRect area, const char* name, const char* label,
|
||||||
|
orientation orientation, int32 channels, BContinuousParameter ¶meter)
|
||||||
|
: BChannelSlider(area, name, label, NULL, orientation, channels),
|
||||||
|
fParameter(parameter)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ChannelSlider::~ChannelSlider()
|
||||||
|
{
|
||||||
|
stop_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ChannelSlider::AttachedToWindow()
|
||||||
|
{
|
||||||
|
start_watching_for_parameter_changes(this, fParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
MessageFilter::MessageFilter()
|
MessageFilter::MessageFilter()
|
||||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
|
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
|
||||||
{
|
{
|
||||||
@ -593,8 +743,7 @@ ContinuousMessageFilter::ContinuousMessageFilter(BControl *control,
|
|||||||
BContinuousParameter ¶meter)
|
BContinuousParameter ¶meter)
|
||||||
: MessageFilter(),
|
: MessageFilter(),
|
||||||
fControl(control),
|
fControl(control),
|
||||||
fParameter(parameter),
|
fParameter(parameter)
|
||||||
fRegistered(false)
|
|
||||||
{
|
{
|
||||||
// initialize view for us
|
// initialize view for us
|
||||||
control->SetMessage(new BMessage(kMsgParameterChanged));
|
control->SetMessage(new BMessage(kMsgParameterChanged));
|
||||||
@ -622,16 +771,6 @@ ContinuousMessageFilter::Filter(BMessage *message, BHandler **target)
|
|||||||
if (*target != fControl)
|
if (*target != fControl)
|
||||||
return B_DISPATCH_MESSAGE;
|
return B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
// TODO: remove this work-around! We can solve this by subclassing the
|
|
||||||
// slider classes, and start watching in their AttachedToWindow() method
|
|
||||||
if (!fRegistered) {
|
|
||||||
if (BMediaRoster* roster = BMediaRoster::CurrentRoster()) {
|
|
||||||
roster->StartWatching(fControl, fParameter.Web()->Node(),
|
|
||||||
B_MEDIA_NEW_PARAMETER_VALUE);
|
|
||||||
}
|
|
||||||
fRegistered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message->what == kMsgParameterChanged) {
|
if (message->what == kMsgParameterChanged) {
|
||||||
// update parameter from control
|
// update parameter from control
|
||||||
// TODO: support for response!
|
// TODO: support for response!
|
||||||
@ -715,7 +854,6 @@ DiscreteMessageFilter::DiscreteMessageFilter(BControl *control,
|
|||||||
control->SetMessage(new BMessage(kMsgParameterChanged));
|
control->SetMessage(new BMessage(kMsgParameterChanged));
|
||||||
|
|
||||||
// set initial value
|
// set initial value
|
||||||
|
|
||||||
size_t size = sizeof(int32);
|
size_t size = sizeof(int32);
|
||||||
int32 value;
|
int32 value;
|
||||||
if (parameter.GetValue((void *)&value, &size, NULL) < B_OK) {
|
if (parameter.GetValue((void *)&value, &size, NULL) < B_OK) {
|
||||||
@ -744,8 +882,39 @@ DiscreteMessageFilter::Filter(BMessage *message, BHandler **target)
|
|||||||
{
|
{
|
||||||
BControl *control;
|
BControl *control;
|
||||||
|
|
||||||
if (message->what != kMsgParameterChanged
|
if ((control = dynamic_cast<BControl *>(*target)) == NULL)
|
||||||
|| (control = dynamic_cast<BControl *>(*target)) == NULL)
|
return B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
|
if (message->what == B_MEDIA_NEW_PARAMETER_VALUE) {
|
||||||
|
TRACE("DiscreteMessageFilter::Filter: Got a new parameter value\n");
|
||||||
|
const media_node* node;
|
||||||
|
int32 parameterID;
|
||||||
|
ssize_t size;
|
||||||
|
if (message->FindInt32("parameter", ¶meterID) != B_OK
|
||||||
|
|| fParameter.ID() != parameterID
|
||||||
|
|| message->FindData("node", B_RAW_TYPE, (const void**)&node,
|
||||||
|
&size) != B_OK
|
||||||
|
|| fParameter.Web()->Node() != *node)
|
||||||
|
return B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
|
int32 value = 0;
|
||||||
|
size_t valueSize = sizeof(int32);
|
||||||
|
if (fParameter.GetValue((void*)&value, &valueSize, NULL) < B_OK) {
|
||||||
|
ERROR("DiscreteMessageFilter: Could not get value for continuous "
|
||||||
|
"parameter %p (name '%s', node %d)\n", &fParameter,
|
||||||
|
fParameter.Name(), (int)fParameter.Web()->Node().node);
|
||||||
|
return B_SKIP_MESSAGE;
|
||||||
|
}
|
||||||
|
if (BCheckBox* checkBox = dynamic_cast<BCheckBox*>(control)) {
|
||||||
|
checkBox->SetValue(value);
|
||||||
|
} else if (BOptionPopUp* popUp = dynamic_cast<BOptionPopUp*>(control)) {
|
||||||
|
popUp->SetValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_SKIP_MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message->what != kMsgParameterChanged)
|
||||||
return B_DISPATCH_MESSAGE;
|
return B_DISPATCH_MESSAGE;
|
||||||
|
|
||||||
// update view
|
// update view
|
||||||
@ -1077,8 +1246,8 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
|
|||||||
|| discrete.CountItems() == 0) {
|
|| discrete.CountItems() == 0) {
|
||||||
// create a checkbox item
|
// create a checkbox item
|
||||||
|
|
||||||
BCheckBox *checkBox = new BCheckBox(rect, discrete.Name(),
|
BCheckBox *checkBox = new CheckBox(rect, discrete.Name(),
|
||||||
discrete.Name(), NULL);
|
discrete.Name(), discrete);
|
||||||
checkBox->ResizeToPreferred();
|
checkBox->ResizeToPreferred();
|
||||||
|
|
||||||
return checkBox;
|
return checkBox;
|
||||||
@ -1099,8 +1268,8 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
|
|||||||
width += font.StringWidth(discrete.Name()) + 55;
|
width += font.StringWidth(discrete.Name()) + 55;
|
||||||
rect.right = rect.left + width;
|
rect.right = rect.left + width;
|
||||||
|
|
||||||
BOptionPopUp *popUp = new BOptionPopUp(rect, discrete.Name(),
|
BOptionPopUp *popUp = new OptionPopUp(rect, discrete.Name(),
|
||||||
discrete.Name(), NULL);
|
discrete.Name(), discrete);
|
||||||
|
|
||||||
for (int32 i = 0; i < discrete.CountItems(); i++) {
|
for (int32 i = 0; i < discrete.CountItems(); i++) {
|
||||||
popUp->AddOption(discrete.ItemNameAt(i), discrete.ItemValueAt(i));
|
popUp->AddOption(discrete.ItemNameAt(i), discrete.ItemValueAt(i));
|
||||||
@ -1118,8 +1287,9 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
|
|||||||
|
|
||||||
if (!strcmp(continuous.Kind(), B_MASTER_GAIN)
|
if (!strcmp(continuous.Kind(), B_MASTER_GAIN)
|
||||||
|| !strcmp(continuous.Kind(), B_GAIN)) {
|
|| !strcmp(continuous.Kind(), B_GAIN)) {
|
||||||
BChannelSlider *slider = new BChannelSlider(rect, continuous.Name(),
|
BChannelSlider *slider = new ChannelSlider(rect,
|
||||||
continuous.Name(), NULL, B_VERTICAL, continuous.CountChannels());
|
continuous.Name(), continuous.Name(), B_VERTICAL,
|
||||||
|
continuous.CountChannels(), continuous);
|
||||||
|
|
||||||
char minLabel[64], maxLabel[64];
|
char minLabel[64], maxLabel[64];
|
||||||
|
|
||||||
@ -1148,8 +1318,8 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
|
|||||||
return slider;
|
return slider;
|
||||||
}
|
}
|
||||||
|
|
||||||
BSlider *slider = new BSlider(rect, parameter->Name(), parameter->Name(),
|
BSlider *slider = new Slider(rect, parameter->Name(),
|
||||||
NULL, 0, 100);
|
parameter->Name(), 0, 100, continuous);
|
||||||
|
|
||||||
float width, height;
|
float width, height;
|
||||||
slider->GetPreferredSize(&width, &height);
|
slider->GetPreferredSize(&width, &height);
|
||||||
|
Loading…
Reference in New Issue
Block a user