Big visual update: it's now almost the same as the original MediaTheme.

Some special parameter types are still missing, actually changing anything
is missing, some needed work-arounds for broken Be code, etc.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3798 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2003-07-02 02:06:21 +00:00
parent 9505110943
commit b8da958ed6

View File

@ -14,13 +14,130 @@
#include <Button.h>
#include <TextControl.h>
#include <OptionPopUp.h>
#include <ChannelSlider.h>
#include <Box.h>
#include <CheckBox.h>
#include <TabView.h>
#include <MenuField.h>
using namespace BPrivate;
namespace BPrivate {
class SeparatorView : public BView {
public:
SeparatorView(BRect frame);
virtual ~SeparatorView();
virtual void Draw(BRect updateRect);
private:
bool fVertical;
};
class TitleView : public BView {
public:
TitleView(BRect frame, const char *title);
virtual ~TitleView();
virtual void Draw(BRect updateRect);
virtual void GetPreferredSize(float *width, float *height);
private:
const char *fTitle;
};
} // namespace BPrivate
SeparatorView::SeparatorView(BRect frame)
: BView(frame, "-", B_FOLLOW_NONE, B_WILL_DRAW)
{
fVertical = frame.Width() < frame.Height();
}
SeparatorView::~SeparatorView()
{
}
void
SeparatorView::Draw(BRect updateRect)
{
rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR);
BRect rect = updateRect & Bounds();
SetHighColor(tint_color(color, B_DARKEN_1_TINT));
if (fVertical)
StrokeLine(BPoint(0, rect.top), BPoint(0, rect.bottom));
else
StrokeLine(BPoint(rect.left, 0), BPoint(rect.right, 0));
SetHighColor(tint_color(color, B_LIGHTEN_1_TINT));
if (fVertical)
StrokeLine(BPoint(1, rect.top), BPoint(1, rect.bottom));
else
StrokeLine(BPoint(rect.left, 1), BPoint(rect.right, 1));
}
// #pragma mark -
TitleView::TitleView(BRect frame, const char *title)
: BView(frame, title, B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW)
{
fTitle = strdup(title);
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
SetLowColor(ViewColor());
}
TitleView::~TitleView()
{
free((char *)fTitle);
}
void
TitleView::Draw(BRect updateRect)
{
BRect rect(Bounds());
SetDrawingMode(B_OP_COPY);
SetHighColor(240, 240, 240);
DrawString(fTitle, BPoint(rect.left + 1, rect.bottom - 9));
SetDrawingMode(B_OP_OVER);
SetHighColor(80, 20, 20);
DrawString(fTitle, BPoint(rect.left, rect.bottom - 8));
//SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT));
//StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.right, rect.bottom));
}
void
TitleView::GetPreferredSize(float *_width, float *_height)
{
if (_width)
*_width = StringWidth(fTitle) + 2;
if (_height) {
font_height fontHeight;
GetFontHeight(&fontHeight);
*_height = fontHeight.ascent + fontHeight.descent + fontHeight.leading + 8;
}
}
// #pragma mark -
DefaultMediaTheme::DefaultMediaTheme()
: BMediaTheme("BeOS Theme", "BeOS built-in theme version 0.1")
{
@ -50,10 +167,15 @@ DefaultMediaTheme::MakeViewFor(BParameterWeb *web, const BRect *hintRect)
if (hintRect)
rect = *hintRect;
else
rect.Set(0, 0, 150, 100);
rect.Set(0, 0, 80, 100);
BView *view = new BView(rect, "web", B_FOLLOW_ALL, B_WILL_DRAW);
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
// do we have more than one attached parameter group?
// if so, use a tabbed view with a tab for each group
BTabView *tabView = NULL;
if (web->CountGroups() > 1)
tabView = new BTabView(rect, "web");
rect.OffsetTo(B_ORIGIN);
@ -62,51 +184,67 @@ DefaultMediaTheme::MakeViewFor(BParameterWeb *web, const BRect *hintRect)
if (group == NULL)
continue;
BView *groupView = MakeViewFor(group, &rect);
BView *groupView = MakeViewFor(*group, rect);
if (groupView == NULL)
continue;
view->AddChild(groupView);
if (tabView == NULL) {
// if we don't need a container to put that view into,
// we're done here
return groupView;
}
rect.OffsetBy(0, groupView->Bounds().Height() + 5);
tabView->AddTab(groupView);
if (groupView->Bounds().Width() + 5 > rect.Width())
rect.right = groupView->Bounds().Width() - 1;
}
view->ResizeTo(rect.right + 10, rect.top + 5);
if (tabView != NULL) {
tabView->ResizeTo(rect.right + 10, rect.bottom + tabView->TabHeight());
return view;
rect = tabView->Bounds();
rect.InsetBySelf(1, 1);
tabView->ContainerView()->ResizeTo(rect.Width(), rect.Height());
}
return tabView;
}
BView *
DefaultMediaTheme::MakeViewFor(BParameterGroup *group, const BRect *hintRect)
DefaultMediaTheme::MakeViewFor(BParameterGroup &group, const BRect &hintRect)
{
CALLED();
BRect rect(*hintRect);
rect.InsetBySelf(5, 5);
BBox *view = new BBox(rect, group->Name());
view->SetLabel(group->Name());
BRect rect(hintRect);
BBox *view = new BBox(rect, group.Name());
view->SetBorder(B_NO_BORDER);
// Add the sub-group views
rect.OffsetTo(B_ORIGIN);
rect.InsetBySelf(5, 5);
rect.top += 10; // ToDo: font height
rect.right = rect.left + 100;
rect.right = rect.left + 50;
for (int32 i = 0; i < group->CountGroups(); i++) {
BParameterGroup *subGroup = group->GroupAt(i);
for (int32 i = 0; i < group.CountGroups(); i++) {
BParameterGroup *subGroup = group.GroupAt(i);
if (subGroup == NULL)
continue;
BView *groupView = MakeViewFor(subGroup, &rect);
BView *groupView = MakeViewFor(*subGroup, rect);
if (groupView == NULL)
continue;
if (i > 0) {
// add separator view
BRect separatorRect(rect);
separatorRect.left -= 3;
separatorRect.right = separatorRect.left + 1;
view->AddChild(new SeparatorView(separatorRect));
}
view->AddChild(groupView);
rect.OffsetBy(groupView->Bounds().Width() + 5, 0);
@ -115,33 +253,107 @@ DefaultMediaTheme::MakeViewFor(BParameterGroup *group, const BRect *hintRect)
rect.bottom = groupView->Bounds().Height() - 1;
}
view->ResizeTo(rect.left + 10, rect.bottom + 25);
view->ResizeTo(rect.left + 10, rect.bottom + 10);
rect.left = 5;
// add the parameter views part of the group
if (view->CountChildren() > 0)
rect.OffsetBy(0, rect.Height() + 5);
if (group.CountParameters() == 0)
return view;
for (int32 i = 0; i < group->CountParameters(); i++) {
BParameter *parameter = group->ParameterAt(i);
if (view->CountChildren() > 0)
rect.OffsetBy(0, rect.Height() + 10);
BList views;
bool center = false;
for (int32 i = 0; i < group.CountParameters(); i++) {
BParameter *parameter = group.ParameterAt(i);
if (parameter == NULL)
continue;
BControl *control = MakeViewFor(parameter, &rect);
if (control == NULL)
BView *parameterView = MakeSelfHostingViewFor(*parameter, rect);
if (parameterView == NULL)
continue;
view->AddChild(control);
// if there is a BChannelSlider (ToDo: or any vertical slider?)
// the views will be centered
if (dynamic_cast<BChannelSlider *>(parameterView) != NULL)
center = true;
rect.OffsetBy(0, control->Bounds().Height() + 5);
parameterView->SetViewColor(view->ViewColor());
// ToDo: dunno why this is needed, but the controls
// sometimes (!) have a white background without it
if (control->Bounds().Width() + 5 > rect.Width())
rect.right = control->Bounds().Width() - 1;
view->AddChild(parameterView);
views.AddItem(parameterView);
rect.OffsetBy(0, parameterView->Bounds().Height() + 5);
if (parameterView->Bounds().Width() + 5 > rect.Width())
rect.right = parameterView->Bounds().Width() + rect.left + 5;
}
if (group->CountParameters() > 0)
view->ResizeTo(rect.right + 10, rect.top + 5);
if (group.CountParameters() > 0)
view->ResizeTo(rect.right + 5, rect.top + 5);
// center the parameter views if needed, and tweak some views
float width = view->Bounds().Width();
for (int32 i = 0; i < views.CountItems(); i++) {
BView *subView = static_cast<BView *>(views.ItemAt(i));
BRect frame = subView->Frame();
if (center)
subView->MoveTo((width - frame.Width()) / 2, frame.top);
else {
// tweak the PopUp views to look better
if (dynamic_cast<BOptionPopUp *>(subView) != NULL) {
subView->ResizeTo(width, frame.Height());
//subView->SetDivider(10);
}
}
}
return view;
}
/** This creates a view that handles all incoming messages itself - that's
* what is meant with self-hosting.
*/
BView *
DefaultMediaTheme::MakeSelfHostingViewFor(BParameter &parameter, const BRect &hintRect)
{
BView *view = MakeViewFor(&parameter, &hintRect);
if (view == NULL) {
// The MakeViewFor() method above returns a BControl - which we
// don't need for a null parameter; that's why it returns NULL.
// But we want to see something anyway, so we add a string view
// here.
if (parameter.Type() == BParameter::B_NULL_PARAMETER) {
if (parameter.Group()->ParameterAt(0) == &parameter) {
// this is the first parameter in this group, so
// let's use a nice title view
TitleView *titleView = new TitleView(hintRect, parameter.Name());
titleView->ResizeToPreferred();
return titleView;
}
BStringView *stringView = new BStringView(hintRect, parameter.Name(), parameter.Name());
stringView->SetAlignment(B_ALIGN_CENTER);
stringView->ResizeToPreferred();
return stringView;
}
return NULL;
}
// ToDo: create message filters for this view!
return view;
}
@ -154,7 +366,7 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
if (hintRect)
rect = *hintRect;
else
rect.Set(0, 0, 150, 100);
rect.Set(0, 0, 50, 100);
switch (parameter->Type()) {
case BParameter::B_NULL_PARAMETER:
@ -165,7 +377,16 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
{
BDiscreteParameter &discrete = static_cast<BDiscreteParameter &>(*parameter);
if (discrete.CountItems() > 0) {
if (!strcmp(discrete.Kind(), B_ENABLE)
|| !strcmp(discrete.Kind(), B_MUTE)
|| discrete.CountItems() == 0) {
// create a checkbox item
BCheckBox *checkBox = new BCheckBox(rect, discrete.Name(), discrete.Name(), NULL);
checkBox->ResizeToPreferred();
return checkBox;
} else {
// create a pop up menu field
BOptionPopUp *popUp = new BOptionPopUp(rect, discrete.Name(), discrete.Name(), NULL);
@ -177,21 +398,50 @@ DefaultMediaTheme::MakeViewFor(BParameter *parameter, const BRect *hintRect)
popUp->ResizeToPreferred();
return popUp;
} else {
// create a checkbox item
BCheckBox *checkBox = new BCheckBox(rect, discrete.Name(), discrete.Name(), NULL);
checkBox->ResizeToPreferred();
return checkBox;
}
}
case BParameter::B_CONTINUOUS_PARAMETER:
{
BContinuousParameter &continuous = static_cast<BContinuousParameter &>(*parameter);
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());
char minLabel[64], maxLabel[64];
const char *unit = continuous.Unit();
if (unit[0]) {
// if we have a unit, print it next to the limit values
sprintf(minLabel, "%g %s", continuous.MinValue(), continuous.Unit());
sprintf(maxLabel, "%g %s", continuous.MaxValue(), continuous.Unit());
} else {
sprintf(minLabel, "%g", continuous.MinValue());
sprintf(maxLabel, "%g", continuous.MaxValue());
}
slider->SetLimitLabels(minLabel, maxLabel);
float width, height;
slider->GetPreferredSize(&width, &height);
slider->ResizeTo(width, 190);
// ToDo: take BContinuousParameter::GetResponse() & ValueStep() into account!
for (int32 i = 0; i < continuous.CountChannels(); i++)
slider->SetLimitsFor(i, continuous.MinValue(), continuous.MaxValue());
return slider;
}
BSlider *slider = new BSlider(rect, parameter->Name(), parameter->Name(),
NULL, 0, 100);
slider->ResizeToPreferred();
float width, height;
slider->GetPreferredSize(&width, &height);
slider->ResizeTo(100, height);
return slider;
}