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;
|
||||
};
|
||||
|
||||
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 {
|
||||
public:
|
||||
static MessageFilter *FilterFor(BView *view, BParameter ¶meter);
|
||||
@ -126,7 +171,6 @@ class ContinuousMessageFilter : public MessageFilter {
|
||||
|
||||
BControl *fControl;
|
||||
BContinuousParameter &fParameter;
|
||||
bool fRegistered;
|
||||
};
|
||||
|
||||
class DiscreteMessageFilter : public MessageFilter {
|
||||
@ -146,7 +190,7 @@ class DiscreteMessageFilter : public MessageFilter {
|
||||
const uint32 kMsgParameterChanged = '_mPC';
|
||||
|
||||
|
||||
static bool
|
||||
static bool
|
||||
parameter_should_be_hidden(BParameter ¶meter)
|
||||
{
|
||||
// ToDo: note, this is probably completely stupid, but it's the only
|
||||
@ -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 -
|
||||
|
||||
|
||||
@ -203,21 +266,21 @@ DynamicScrollView::AttachedToWindow(void)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
DynamicScrollView::FrameResized(float width, float height)
|
||||
{
|
||||
UpdateBars();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
DynamicScrollView::FrameMoved(BPoint newPosition)
|
||||
{
|
||||
UpdateBars();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
DynamicScrollView::GetPreferredSize(float *_width, float *_height)
|
||||
{
|
||||
float width = 50;
|
||||
@ -233,7 +296,7 @@ DynamicScrollView::GetPreferredSize(float *_width, float *_height)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
DynamicScrollView::SetContentBounds(BRect bounds)
|
||||
{
|
||||
fContentBounds = bounds;
|
||||
@ -242,7 +305,7 @@ DynamicScrollView::SetContentBounds(BRect bounds)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
DynamicScrollView::UpdateBars()
|
||||
{
|
||||
// we need the size that the view wants to have, and the one
|
||||
@ -326,7 +389,7 @@ DynamicScrollView::UpdateBars()
|
||||
}
|
||||
if (vertical || fIsDocumentScroller)
|
||||
barWidth -= B_V_SCROLL_BAR_WIDTH + 1;
|
||||
|
||||
|
||||
fHorizontalScrollBar->MoveTo(bounds.left, bounds.bottom + 1);
|
||||
fHorizontalScrollBar->ResizeTo(barWidth, B_H_SCROLL_BAR_HEIGHT);
|
||||
}
|
||||
@ -368,7 +431,7 @@ GroupView::~GroupView()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
GroupView::AttachedToWindow()
|
||||
{
|
||||
for (int32 i = CountChildren(); i-- > 0;) {
|
||||
@ -381,13 +444,13 @@ GroupView::AttachedToWindow()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
GroupView::AllAttached()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
GroupView::GetPreferredSize(float *_width, float *_height)
|
||||
{
|
||||
if (_width)
|
||||
@ -421,7 +484,7 @@ GroupView::MaxSize()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
GroupView::SetContentBounds(BRect bounds)
|
||||
{
|
||||
fContentBounds = bounds;
|
||||
@ -445,7 +508,7 @@ TabView::TabView(BRect frame, const char *name, button_width width,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
TabView::FrameResized(float width, float height)
|
||||
{
|
||||
BRect rect = Bounds();
|
||||
@ -457,7 +520,7 @@ TabView::FrameResized(float width, float height)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
TabView::Select(int32 tab)
|
||||
{
|
||||
BTabView::Select(tab);
|
||||
@ -486,7 +549,7 @@ SeparatorView::~SeparatorView()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
SeparatorView::Draw(BRect updateRect)
|
||||
{
|
||||
rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||
@ -523,7 +586,7 @@ TitleView::~TitleView()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
TitleView::Draw(BRect updateRect)
|
||||
{
|
||||
BRect rect(Bounds());
|
||||
@ -538,7 +601,7 @@ TitleView::Draw(BRect updateRect)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
TitleView::GetPreferredSize(float *_width, float *_height)
|
||||
{
|
||||
if (_width)
|
||||
@ -557,6 +620,93 @@ TitleView::GetPreferredSize(float *_width, float *_height)
|
||||
// #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()
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE)
|
||||
{
|
||||
@ -593,8 +743,7 @@ ContinuousMessageFilter::ContinuousMessageFilter(BControl *control,
|
||||
BContinuousParameter ¶meter)
|
||||
: MessageFilter(),
|
||||
fControl(control),
|
||||
fParameter(parameter),
|
||||
fRegistered(false)
|
||||
fParameter(parameter)
|
||||
{
|
||||
// initialize view for us
|
||||
control->SetMessage(new BMessage(kMsgParameterChanged));
|
||||
@ -616,22 +765,12 @@ ContinuousMessageFilter::~ContinuousMessageFilter()
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
filter_result
|
||||
ContinuousMessageFilter::Filter(BMessage *message, BHandler **target)
|
||||
{
|
||||
if (*target != fControl)
|
||||
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) {
|
||||
// update parameter from control
|
||||
// TODO: support for response!
|
||||
@ -715,7 +854,6 @@ DiscreteMessageFilter::DiscreteMessageFilter(BControl *control,
|
||||
control->SetMessage(new BMessage(kMsgParameterChanged));
|
||||
|
||||
// set initial value
|
||||
|
||||
size_t size = sizeof(int32);
|
||||
int32 value;
|
||||
if (parameter.GetValue((void *)&value, &size, NULL) < B_OK) {
|
||||
@ -739,13 +877,44 @@ DiscreteMessageFilter::~DiscreteMessageFilter()
|
||||
}
|
||||
|
||||
|
||||
filter_result
|
||||
filter_result
|
||||
DiscreteMessageFilter::Filter(BMessage *message, BHandler **target)
|
||||
{
|
||||
BControl *control;
|
||||
|
||||
if (message->what != kMsgParameterChanged
|
||||
|| (control = dynamic_cast<BControl *>(*target)) == NULL)
|
||||
if ((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;
|
||||
|
||||
// update view
|
||||
@ -801,7 +970,7 @@ DefaultMediaTheme::MakeViewFor(BParameterWeb *web, const BRect *hintRect)
|
||||
BRect rect;
|
||||
if (hintRect)
|
||||
rect = *hintRect;
|
||||
|
||||
|
||||
BRect bestRect;
|
||||
|
||||
// do we have more than one attached parameter group?
|
||||
@ -844,20 +1013,20 @@ DefaultMediaTheme::MakeViewFor(BParameterWeb *web, const BRect *hintRect)
|
||||
|
||||
return new DynamicScrollView(groupView->Name(), groupView);
|
||||
}
|
||||
|
||||
DynamicScrollView *scrollView = new DynamicScrollView(groupView->Name(), groupView);
|
||||
|
||||
DynamicScrollView *scrollView = new DynamicScrollView(groupView->Name(), groupView);
|
||||
tabView->AddTab(scrollView);
|
||||
|
||||
if (!hintRect) {
|
||||
bestRect = bestRect | scrollView->Bounds();
|
||||
}
|
||||
|
||||
if (!hintRect) {
|
||||
bestRect = bestRect | scrollView->Bounds();
|
||||
}
|
||||
}
|
||||
|
||||
if (tabView != NULL) {
|
||||
|
||||
if (tabView != NULL) {
|
||||
// this adjustment must be kept in sync with TabView::FrameResized
|
||||
bestRect.bottom += tabView->TabHeight();
|
||||
bestRect.InsetBy(-3.0,-3.0);
|
||||
|
||||
bestRect.InsetBy(-3.0,-3.0);
|
||||
|
||||
tabView->ResizeTo(bestRect.Width(), bestRect.Height());
|
||||
tabView->FrameResized(bestRect.Width(), bestRect.Height());
|
||||
//needed since we're not attached to a window yet
|
||||
@ -1077,8 +1246,8 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
|
||||
|| discrete.CountItems() == 0) {
|
||||
// create a checkbox item
|
||||
|
||||
BCheckBox *checkBox = new BCheckBox(rect, discrete.Name(),
|
||||
discrete.Name(), NULL);
|
||||
BCheckBox *checkBox = new CheckBox(rect, discrete.Name(),
|
||||
discrete.Name(), discrete);
|
||||
checkBox->ResizeToPreferred();
|
||||
|
||||
return checkBox;
|
||||
@ -1099,8 +1268,8 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
|
||||
width += font.StringWidth(discrete.Name()) + 55;
|
||||
rect.right = rect.left + width;
|
||||
|
||||
BOptionPopUp *popUp = new BOptionPopUp(rect, discrete.Name(),
|
||||
discrete.Name(), NULL);
|
||||
BOptionPopUp *popUp = new OptionPopUp(rect, discrete.Name(),
|
||||
discrete.Name(), discrete);
|
||||
|
||||
for (int32 i = 0; i < discrete.CountItems(); 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)
|
||||
|| !strcmp(continuous.Kind(), B_GAIN)) {
|
||||
BChannelSlider *slider = new BChannelSlider(rect, continuous.Name(),
|
||||
continuous.Name(), NULL, B_VERTICAL, continuous.CountChannels());
|
||||
BChannelSlider *slider = new ChannelSlider(rect,
|
||||
continuous.Name(), continuous.Name(), B_VERTICAL,
|
||||
continuous.CountChannels(), continuous);
|
||||
|
||||
char minLabel[64], maxLabel[64];
|
||||
|
||||
@ -1148,8 +1318,8 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
|
||||
return slider;
|
||||
}
|
||||
|
||||
BSlider *slider = new BSlider(rect, parameter->Name(), parameter->Name(),
|
||||
NULL, 0, 100);
|
||||
BSlider *slider = new Slider(rect, parameter->Name(),
|
||||
parameter->Name(), 0, 100, continuous);
|
||||
|
||||
float width, height;
|
||||
slider->GetPreferredSize(&width, &height);
|
||||
|
Loading…
Reference in New Issue
Block a user