2005-01-15 04:38:32 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright 2005, Haiku Inc. All Rights Reserved.
|
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
|
*/
|
|
|
|
|
|
2005-03-10 16:03:49 +00:00
|
|
|
// TODO: Currently it works correctly only with vertical sliders.
|
2005-02-17 14:10:52 +00:00
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
#include <Bitmap.h>
|
2005-01-15 04:38:32 +00:00
|
|
|
#include <ChannelSlider.h>
|
2005-02-01 07:42:07 +00:00
|
|
|
#include <Debug.h>
|
|
|
|
|
#include <PropertyInfo.h>
|
2005-02-21 10:07:30 +00:00
|
|
|
#include <Screen.h>
|
2005-02-17 14:10:52 +00:00
|
|
|
#include <Window.h>
|
2005-02-01 07:42:07 +00:00
|
|
|
|
2005-02-04 09:43:21 +00:00
|
|
|
const static unsigned char
|
|
|
|
|
kVerticalKnobData[] = {
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
|
|
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0xcb, 0xcb, 0xcb, 0xcb, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12,
|
|
|
|
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12,
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0xff
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const static unsigned char
|
|
|
|
|
kHorizontalKnobData[] = {
|
|
|
|
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0xff, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0xff, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xcb, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xcb, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xcb, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0xcb, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12, 0xff,
|
|
|
|
|
0xff, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x12, 0xff,
|
|
|
|
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0xff,
|
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0xff, 0xff
|
|
|
|
|
};
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
|
|
|
|
|
static property_info
|
|
|
|
|
sPropertyInfo[] = {
|
|
|
|
|
{ "Orientation",
|
|
|
|
|
{ B_GET_PROPERTY, B_SET_PROPERTY, 0 },
|
|
|
|
|
{ B_DIRECT_SPECIFIER, 0 }, "" },
|
2005-03-08 14:52:43 +00:00
|
|
|
|
|
|
|
|
{ 0 }
|
2005-02-01 07:42:07 +00:00
|
|
|
};
|
|
|
|
|
|
2005-01-15 04:38:32 +00:00
|
|
|
|
|
|
|
|
BChannelSlider::BChannelSlider(BRect area, const char *name, const char *label,
|
|
|
|
|
BMessage *model, int32 channels, uint32 resizeMode, uint32 flags)
|
|
|
|
|
: BChannelControl(area, name, label, model, channels, resizeMode, flags)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
InitData();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BChannelSlider::BChannelSlider(BRect area, const char *name, const char *label,
|
|
|
|
|
BMessage *model, orientation o, int32 channels, uint32 resizeMode, uint32 flags)
|
|
|
|
|
: BChannelControl(area, name, label, model, channels, resizeMode, flags)
|
2005-02-01 07:42:07 +00:00
|
|
|
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
InitData();
|
|
|
|
|
SetOrientation(o);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BChannelSlider::BChannelSlider(BMessage *archive)
|
|
|
|
|
: BChannelControl(archive)
|
|
|
|
|
{
|
2005-02-03 15:50:41 +00:00
|
|
|
InitData();
|
|
|
|
|
|
|
|
|
|
orientation orient;
|
|
|
|
|
if (archive->FindInt32("_orient", (int32 *)&orient) == B_OK)
|
|
|
|
|
SetOrientation(orient);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BChannelSlider::~BChannelSlider()
|
|
|
|
|
{
|
2005-02-21 10:07:30 +00:00
|
|
|
delete fLeftKnob;
|
|
|
|
|
delete fMidKnob;
|
|
|
|
|
delete fRightKnob;
|
2005-03-11 13:20:01 +00:00
|
|
|
delete[] fInitialValues;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BArchivable *
|
|
|
|
|
BChannelSlider::Instantiate(BMessage *archive)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
if (validate_instantiation(archive, "BChannelSlider"))
|
|
|
|
|
return new BChannelSlider(archive);
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
|
BChannelSlider::Archive(BMessage *into, bool deep) const
|
|
|
|
|
{
|
2005-02-03 15:50:41 +00:00
|
|
|
status_t status = BChannelControl::Archive(into, deep);
|
|
|
|
|
if (status == B_OK)
|
|
|
|
|
status = into->AddInt32("_orient", (int32)Orientation());
|
|
|
|
|
|
|
|
|
|
return status;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
orientation
|
|
|
|
|
BChannelSlider::Orientation() const
|
|
|
|
|
{
|
2005-02-02 09:34:06 +00:00
|
|
|
return Vertical() ? B_VERTICAL : B_HORIZONTAL;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::SetOrientation(orientation _orientation)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
bool isVertical = _orientation == B_VERTICAL;
|
|
|
|
|
if (isVertical != Vertical()) {
|
2005-02-01 14:29:06 +00:00
|
|
|
fVertical = isVertical;
|
2005-02-01 07:42:07 +00:00
|
|
|
Invalidate(Bounds());
|
|
|
|
|
}
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int32
|
|
|
|
|
BChannelSlider::MaxChannelCount() const
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
return 32;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
BChannelSlider::SupportsIndividualLimits() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::AttachedToWindow()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
BView *parent = Parent();
|
|
|
|
|
if (parent != NULL)
|
|
|
|
|
SetViewColor(parent->ViewColor());
|
|
|
|
|
|
|
|
|
|
inherited::AttachedToWindow();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::AllAttached()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
BControl::AllAttached();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::DetachedFromWindow()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
inherited::DetachedFromWindow();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::AllDetached()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
BControl::AllDetached();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::MessageReceived(BMessage *message)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-03-10 16:03:49 +00:00
|
|
|
switch (message->what) {
|
|
|
|
|
case B_SET_PROPERTY:
|
|
|
|
|
case B_GET_PROPERTY:
|
|
|
|
|
{
|
|
|
|
|
BMessage reply(B_REPLY);
|
|
|
|
|
int32 index = 0;
|
|
|
|
|
BMessage specifier;
|
|
|
|
|
int32 what = 0;
|
|
|
|
|
const char *property = NULL;
|
|
|
|
|
bool handled = false;
|
|
|
|
|
status_t status = message->GetCurrentSpecifier(&index, &specifier, &what, &property);
|
|
|
|
|
BPropertyInfo propInfo(sPropertyInfo);
|
|
|
|
|
if (status == B_OK
|
|
|
|
|
&& propInfo.FindMatch(message, index, &specifier, what, property) >= 0) {
|
|
|
|
|
handled = true;
|
|
|
|
|
if (message->what == B_SET_PROPERTY) {
|
|
|
|
|
orientation orient;
|
|
|
|
|
if (specifier.FindInt32("data", (int32 *)&orient) == B_OK) {
|
|
|
|
|
SetOrientation(orient);
|
|
|
|
|
Invalidate(Bounds());
|
|
|
|
|
}
|
|
|
|
|
} else if (message->what == B_GET_PROPERTY)
|
2005-03-11 13:20:01 +00:00
|
|
|
reply.AddInt32("result", (int32)Orientation());
|
|
|
|
|
else
|
|
|
|
|
status = B_BAD_SCRIPT_SYNTAX;
|
2005-03-10 16:03:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (handled) {
|
|
|
|
|
reply.AddInt32("error", status);
|
|
|
|
|
message->SendReply(&reply);
|
|
|
|
|
} else
|
|
|
|
|
inherited::MessageReceived(message);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
inherited::MessageReceived(message);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::Draw(BRect updateRect)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
UpdateFontDimens();
|
|
|
|
|
DrawThumbs();
|
|
|
|
|
|
|
|
|
|
BRect bounds(Bounds());
|
|
|
|
|
float labelWidth = StringWidth(Label());
|
|
|
|
|
|
|
|
|
|
MovePenTo((bounds.Width() - labelWidth) / 2, 10);
|
|
|
|
|
DrawString(Label());
|
|
|
|
|
|
2005-02-21 10:07:30 +00:00
|
|
|
Sync();
|
2005-02-01 07:42:07 +00:00
|
|
|
// TODO: Respect label limits !!!
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::MouseDown(BPoint where)
|
|
|
|
|
{
|
2005-02-17 14:10:52 +00:00
|
|
|
if (!IsEnabled())
|
|
|
|
|
BControl::MouseDown(where);
|
|
|
|
|
else {
|
|
|
|
|
fCurrentChannel = -1;
|
|
|
|
|
fMinpoint = 0;
|
|
|
|
|
|
|
|
|
|
// Search the channel on which the mouse was over
|
|
|
|
|
int32 numChannels = CountChannels();
|
|
|
|
|
for (int32 channel = 0; channel < numChannels; channel++) {
|
|
|
|
|
BRect frame = ThumbFrameFor(channel);
|
|
|
|
|
frame.OffsetBy(fClickDelta);
|
|
|
|
|
|
|
|
|
|
float range = ThumbRangeFor(channel);
|
|
|
|
|
|
2005-03-10 16:03:49 +00:00
|
|
|
if (Vertical()) {
|
|
|
|
|
fMinpoint = frame.top + frame.Height() / 2;
|
2005-02-17 14:10:52 +00:00
|
|
|
frame.bottom += range;
|
|
|
|
|
} else {
|
|
|
|
|
fMinpoint = frame.Width();
|
2005-03-11 13:20:01 +00:00
|
|
|
frame.right += range;
|
2005-02-17 14:10:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Found. Now set the initial values
|
|
|
|
|
if (frame.Contains(where)) {
|
|
|
|
|
uint32 buttons = 0;
|
|
|
|
|
BMessage *currentMessage = Window()->CurrentMessage();
|
|
|
|
|
if (currentMessage != NULL)
|
|
|
|
|
currentMessage->FindInt32("buttons", (int32 *)&buttons);
|
|
|
|
|
|
2005-03-10 16:03:49 +00:00
|
|
|
fAllChannels = (buttons & B_SECONDARY_MOUSE_BUTTON) == 0;
|
2005-02-17 14:10:52 +00:00
|
|
|
fCurrentChannel = channel;
|
|
|
|
|
|
|
|
|
|
if (fInitialValues != NULL && fAllChannels) {
|
|
|
|
|
delete[] fInitialValues;
|
|
|
|
|
fInitialValues = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fInitialValues == NULL)
|
|
|
|
|
fInitialValues = new int32[CountChannels()];
|
|
|
|
|
|
|
|
|
|
if (fAllChannels) {
|
|
|
|
|
for (int32 i = 0; i < CountChannels(); i++)
|
|
|
|
|
fInitialValues[i] = ValueFor(i);
|
|
|
|
|
} else
|
|
|
|
|
fInitialValues[fCurrentChannel] = ValueFor(fCurrentChannel);
|
|
|
|
|
|
|
|
|
|
if (Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) {
|
|
|
|
|
if (!IsTracking()) {
|
|
|
|
|
SetTracking(true);
|
|
|
|
|
DrawThumbs();
|
|
|
|
|
Flush();
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-11 13:20:01 +00:00
|
|
|
MouseMovedCommon(where, where);
|
2005-02-17 14:10:52 +00:00
|
|
|
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
debugger("BChannelSlider::MouseDown(): SYNCHRONOUS CONTROLS NOT YET SUPPORTED");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::MouseUp(BPoint where)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-17 14:10:52 +00:00
|
|
|
if (IsEnabled() && IsTracking()) {
|
|
|
|
|
FinishChange();
|
|
|
|
|
SetTracking(false);
|
|
|
|
|
fAllChannels = false;
|
|
|
|
|
fCurrentChannel = -1;
|
|
|
|
|
fMinpoint = 0;
|
|
|
|
|
} else
|
|
|
|
|
BControl::MouseUp(where);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
if (IsEnabled() && IsTracking())
|
|
|
|
|
MouseMovedCommon(where, B_ORIGIN);
|
|
|
|
|
else
|
|
|
|
|
BControl::MouseMoved(where, code, message);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::WindowActivated(bool state)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
BControl::WindowActivated(state);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::KeyDown(const char *bytes, int32 numBytes)
|
|
|
|
|
{
|
2005-02-17 14:10:52 +00:00
|
|
|
BControl::KeyDown(bytes, numBytes);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::KeyUp(const char *bytes, int32 numBytes)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
BView::KeyUp(bytes, numBytes);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::FrameResized(float newWidth, float newHeight)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
inherited::FrameResized(newWidth, newHeight);
|
|
|
|
|
Invalidate(Bounds());
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::SetFont(const BFont *font, uint32 mask)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
inherited::SetFont(font, mask);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::MakeFocus(bool focusState)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
if (focusState && !IsFocus())
|
|
|
|
|
fFocusChannel = -1;
|
|
|
|
|
BControl::MakeFocus(focusState);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::SetEnabled(bool on)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
BControl::SetEnabled(on);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::GetPreferredSize(float *width, float *height)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
// TODO: Implement
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BHandler *
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::ResolveSpecifier(BMessage *msg, int32 index, BMessage *specifier,
|
|
|
|
|
int32 form, const char *property)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-03-07 08:45:18 +00:00
|
|
|
BHandler *target = this;
|
|
|
|
|
BPropertyInfo propertyInfo(sPropertyInfo);
|
|
|
|
|
if (propertyInfo.FindMatch(msg, index, specifier, form, property) < B_OK)
|
|
|
|
|
target = BChannelControl::ResolveSpecifier(msg, index, specifier, form, property);
|
|
|
|
|
|
|
|
|
|
return target;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
|
|
|
|
BChannelSlider::GetSupportedSuites(BMessage *data)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
if (data == NULL)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
|
|
data->AddString("suites", "suite/vnd.Be-channel-slider");
|
|
|
|
|
|
|
|
|
|
BPropertyInfo propInfo(sPropertyInfo);
|
|
|
|
|
data->AddFlat("messages", &propInfo, 1);
|
|
|
|
|
|
|
|
|
|
return inherited::GetSupportedSuites(data);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::DrawChannel(BView *into, int32 channel, BRect area, bool pressed)
|
|
|
|
|
{
|
2005-03-11 13:20:01 +00:00
|
|
|
float hCenter = area.Width() / 2;
|
|
|
|
|
float vCenter = area.Height() / 2;
|
|
|
|
|
|
|
|
|
|
BPoint leftTop;
|
|
|
|
|
BPoint bottomRight;
|
|
|
|
|
if (Vertical()) {
|
2005-04-07 15:24:29 +00:00
|
|
|
leftTop.Set(area.left + hCenter, area.top + vCenter);
|
|
|
|
|
bottomRight.Set(leftTop.x , leftTop.y + ThumbRangeFor(channel));
|
2005-03-11 13:20:01 +00:00
|
|
|
} else {
|
|
|
|
|
leftTop.Set(area.left, area.top + vCenter);
|
|
|
|
|
bottomRight.Set(area.left + ThumbRangeFor(channel), leftTop.y);
|
|
|
|
|
}
|
|
|
|
|
|
2005-02-21 10:07:30 +00:00
|
|
|
DrawGroove(into, channel, leftTop, bottomRight);
|
2005-03-10 16:03:49 +00:00
|
|
|
|
|
|
|
|
BPoint thumbLocation = leftTop;
|
2005-03-11 13:20:01 +00:00
|
|
|
if (Vertical())
|
|
|
|
|
thumbLocation.y += ThumbDeltaFor(channel);
|
2005-03-10 16:03:49 +00:00
|
|
|
|
|
|
|
|
DrawThumb(into, channel, thumbLocation, pressed);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2005-02-01 07:42:07 +00:00
|
|
|
BChannelSlider::DrawGroove(BView *into, int32 channel, BPoint topLeft, BPoint bottomRight)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-03 15:50:41 +00:00
|
|
|
// TODO: Draw the real thing
|
|
|
|
|
ASSERT(into != NULL);
|
2005-03-11 13:20:01 +00:00
|
|
|
BRect rect(topLeft, bottomRight);
|
|
|
|
|
|
|
|
|
|
if (Vertical())
|
|
|
|
|
rect.InsetBy(-1, 0);
|
|
|
|
|
else
|
|
|
|
|
rect.InsetBy(0, -1);
|
|
|
|
|
|
|
|
|
|
into->FillRect(rect, B_SOLID_HIGH);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
BChannelSlider::DrawThumb(BView *into, int32 channel, BPoint where, bool pressed)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
ASSERT(into != NULL);
|
2005-02-03 15:50:41 +00:00
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
const BBitmap *thumb = ThumbFor(channel, pressed);
|
2005-02-02 09:34:06 +00:00
|
|
|
if (thumb == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
BRect bitmapBounds = thumb->Bounds();
|
|
|
|
|
where.x -= bitmapBounds.right / 2;
|
|
|
|
|
where.y -= bitmapBounds.bottom / 2;
|
|
|
|
|
|
|
|
|
|
into->DrawBitmapAsync(thumb, where);
|
|
|
|
|
|
|
|
|
|
if (pressed) {
|
|
|
|
|
into->PushState();
|
|
|
|
|
|
|
|
|
|
into->SetDrawingMode(B_OP_ALPHA);
|
2005-02-17 14:10:52 +00:00
|
|
|
|
2005-03-10 16:03:49 +00:00
|
|
|
rgb_color color = tint_color(into->ViewColor(), B_DARKEN_4_TINT);
|
2005-02-17 14:10:52 +00:00
|
|
|
color.alpha = 128;
|
|
|
|
|
into->SetHighColor(color);
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
BRect rect(where, where);
|
|
|
|
|
rect.right += bitmapBounds.right;
|
|
|
|
|
rect.bottom += bitmapBounds.bottom;
|
2005-02-17 14:10:52 +00:00
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
into->FillRect(rect);
|
|
|
|
|
|
|
|
|
|
into->PopState();
|
|
|
|
|
}
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const BBitmap *
|
|
|
|
|
BChannelSlider::ThumbFor(int32 channel, bool pressed)
|
|
|
|
|
{
|
2005-02-04 09:43:21 +00:00
|
|
|
// TODO: Finish me
|
|
|
|
|
if (fLeftKnob == NULL) {
|
|
|
|
|
if (Vertical()) {
|
|
|
|
|
fLeftKnob = new BBitmap(BRect(0, 0, 11, 14), B_CMAP8);
|
|
|
|
|
fLeftKnob->SetBits(kVerticalKnobData, sizeof(kVerticalKnobData), 0, B_CMAP8);
|
|
|
|
|
} else {
|
|
|
|
|
fLeftKnob = new BBitmap(BRect(0, 0, 14, 10), B_CMAP8);
|
|
|
|
|
fLeftKnob->SetBits(kHorizontalKnobData, sizeof(kHorizontalKnobData), 0, B_CMAP8);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fLeftKnob;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
BRect
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::ThumbFrameFor(int32 channel)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
UpdateFontDimens();
|
|
|
|
|
|
|
|
|
|
BRect frame(0, 0, 0, 0);
|
|
|
|
|
const BBitmap *thumb = ThumbFor(channel, false);
|
|
|
|
|
if (thumb != NULL) {
|
|
|
|
|
frame = thumb->Bounds();
|
|
|
|
|
if (Vertical())
|
2005-03-10 16:03:49 +00:00
|
|
|
frame.OffsetBy(channel * frame.Width(), fLineFeed * 2);
|
2005-02-01 07:42:07 +00:00
|
|
|
else
|
2005-03-10 16:03:49 +00:00
|
|
|
frame.OffsetBy(fLineFeed, fLineFeed + channel * frame.Height());
|
2005-02-01 07:42:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return frame;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
float
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::ThumbDeltaFor(int32 channel)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
float delta = 0;
|
|
|
|
|
if (channel >= 0 && channel < MaxChannelCount()) {
|
|
|
|
|
float range = ThumbRangeFor(channel);
|
|
|
|
|
int32 limitRange = MaxLimitList()[channel] - MinLimitList()[channel];
|
|
|
|
|
delta = ValueList()[channel] * range / limitRange;
|
|
|
|
|
|
|
|
|
|
if (Vertical())
|
|
|
|
|
delta = range - delta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return delta;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
float
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::ThumbRangeFor(int32 channel)
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
UpdateFontDimens();
|
|
|
|
|
|
2005-03-10 16:03:49 +00:00
|
|
|
float range = 0;
|
2005-02-01 07:42:07 +00:00
|
|
|
BRect bounds = Bounds();
|
|
|
|
|
BRect frame = ThumbFrameFor(channel);
|
|
|
|
|
if (Vertical())
|
2005-02-01 14:29:06 +00:00
|
|
|
range = bounds.Height() - frame.Height() - fLineFeed * 4;
|
2005-02-01 07:42:07 +00:00
|
|
|
else
|
2005-02-01 14:29:06 +00:00
|
|
|
range = bounds.Width() - frame.Width() - fLineFeed * 2;
|
2005-02-01 07:42:07 +00:00
|
|
|
|
|
|
|
|
return range;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
void
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::InitData()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
UpdateFontDimens();
|
|
|
|
|
|
2005-02-01 14:29:06 +00:00
|
|
|
fLeftKnob = NULL;
|
|
|
|
|
fMidKnob = NULL;
|
|
|
|
|
fRightKnob = NULL;
|
|
|
|
|
fBacking = NULL;
|
|
|
|
|
fBackingView = NULL;
|
|
|
|
|
fVertical = Bounds().Width() / Bounds().Height() < 1;
|
|
|
|
|
fClickDelta = B_ORIGIN;
|
2005-02-01 07:42:07 +00:00
|
|
|
|
|
|
|
|
fCurrentChannel = -1;
|
|
|
|
|
fAllChannels = false;
|
|
|
|
|
fInitialValues = NULL;
|
|
|
|
|
fMinpoint = 0;
|
|
|
|
|
fFocusChannel = -1;
|
|
|
|
|
|
|
|
|
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
void
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::FinishChange()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
if (fInitialValues != NULL) {
|
|
|
|
|
if (fAllChannels) {
|
|
|
|
|
// TODO: Iterate through the list of channels, and invoke only
|
|
|
|
|
// for changed values
|
|
|
|
|
|
|
|
|
|
InvokeChannel();
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
if (ValueList()[fCurrentChannel] != fInitialValues[fCurrentChannel]) {
|
|
|
|
|
SetValueFor(fCurrentChannel, ValueList()[fCurrentChannel]);
|
|
|
|
|
Invoke();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetTracking(false);
|
|
|
|
|
Redraw();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
void
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::UpdateFontDimens()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
font_height height;
|
|
|
|
|
GetFontHeight(&height);
|
2005-02-01 14:29:06 +00:00
|
|
|
fBaseLine = height.ascent + height.leading;
|
|
|
|
|
fLineFeed = fBaseLine + height.descent;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
void
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::DrawThumbs()
|
2005-02-03 15:50:41 +00:00
|
|
|
{
|
2005-02-21 10:07:30 +00:00
|
|
|
BRect first = ThumbFrameFor(0);
|
2005-04-07 15:24:29 +00:00
|
|
|
BRect last = ThumbFrameFor(CountChannels() - 1);
|
2005-02-21 10:07:30 +00:00
|
|
|
|
|
|
|
|
if (fBacking == NULL) {
|
|
|
|
|
BRect bitmapFrame;
|
|
|
|
|
if (Vertical()) {
|
|
|
|
|
bitmapFrame.top = first.top - ThumbRangeFor(0);
|
|
|
|
|
bitmapFrame.bottom = last.bottom;
|
|
|
|
|
bitmapFrame.left = first.left;
|
|
|
|
|
bitmapFrame.right = last.right;
|
|
|
|
|
} else {
|
|
|
|
|
bitmapFrame.top = first.top;
|
|
|
|
|
bitmapFrame.bottom = last.bottom;
|
|
|
|
|
bitmapFrame.left = first.left;
|
|
|
|
|
bitmapFrame.right = last.right + ThumbRangeFor(0);
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-07 15:24:29 +00:00
|
|
|
bitmapFrame.InsetBy(-3, -3);
|
2005-02-21 10:07:30 +00:00
|
|
|
bitmapFrame.OffsetTo(B_ORIGIN);
|
2005-03-11 13:20:01 +00:00
|
|
|
|
2005-02-21 10:07:30 +00:00
|
|
|
fBacking = new BBitmap(bitmapFrame, BScreen(Window()).ColorSpace(), true, false);
|
|
|
|
|
if (fBacking->Lock()) {
|
|
|
|
|
fBackingView = new BView(bitmapFrame, "backing view", B_FOLLOW_NONE, B_WILL_DRAW);
|
|
|
|
|
fBacking->AddChild(fBackingView);
|
|
|
|
|
fBackingView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
|
|
|
fBackingView->SetLowColor(fBackingView->ViewColor());
|
|
|
|
|
fBacking->Unlock();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-07 15:24:29 +00:00
|
|
|
BPoint drawHere;
|
|
|
|
|
drawHere.x = (Bounds().Width() - fBacking->Bounds().Width()) / 2;
|
|
|
|
|
drawHere.y = (Bounds().Height() - fBacking->Bounds().Height()) / 2 ;
|
|
|
|
|
|
2005-02-21 10:07:30 +00:00
|
|
|
if (fBacking->Lock()) {
|
2005-04-07 15:24:29 +00:00
|
|
|
// Clear the view's background
|
2005-03-10 16:03:49 +00:00
|
|
|
fBackingView->FillRect(fBackingView->Bounds(), B_SOLID_LOW);
|
2005-04-07 15:24:29 +00:00
|
|
|
for (int32 channel = 0; channel < CountChannels(); channel++) {
|
|
|
|
|
BRect channelArea = ThumbFrameFor(channel);
|
|
|
|
|
// TODO: HACK!!! What am I missing ?
|
|
|
|
|
// Why do I need this to draw the channel in the correct location ?
|
|
|
|
|
channelArea.OffsetBy(3, -21);
|
|
|
|
|
DrawChannel(fBackingView, channel, channelArea, fMinpoint != 0);
|
|
|
|
|
}
|
2005-02-21 10:07:30 +00:00
|
|
|
fBackingView->Sync();
|
|
|
|
|
fBacking->Unlock();
|
|
|
|
|
}
|
2005-04-07 15:24:29 +00:00
|
|
|
|
2005-02-21 10:07:30 +00:00
|
|
|
fClickDelta = drawHere;
|
2005-03-11 13:20:01 +00:00
|
|
|
|
2005-04-07 15:24:29 +00:00
|
|
|
// TODO: Look at the above comment
|
|
|
|
|
fClickDelta.y -= 21;
|
|
|
|
|
fClickDelta.x += 3;
|
|
|
|
|
|
2005-02-21 10:07:30 +00:00
|
|
|
DrawBitmapAsync(fBacking, drawHere);
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
void
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::DrawThumbFrame(BView *where, const BRect &area)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
bool
|
2005-02-02 13:33:34 +00:00
|
|
|
BChannelSlider::Vertical() const
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-02-01 14:29:06 +00:00
|
|
|
return fVertical;
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
void
|
2005-01-15 04:38:32 +00:00
|
|
|
BChannelSlider::Redraw()
|
|
|
|
|
{
|
2005-02-01 07:42:07 +00:00
|
|
|
Invalidate(Bounds());
|
|
|
|
|
Flush();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-02-01 07:42:07 +00:00
|
|
|
void
|
2005-02-03 15:50:41 +00:00
|
|
|
BChannelSlider::MouseMovedCommon(BPoint point, BPoint point2)
|
2005-01-15 04:38:32 +00:00
|
|
|
{
|
2005-03-10 16:03:49 +00:00
|
|
|
float floatValue = 0;
|
|
|
|
|
int32 limitRange = MaxLimitList()[fCurrentChannel] - MinLimitList()[fCurrentChannel];
|
|
|
|
|
float range = ThumbRangeFor(fCurrentChannel);
|
2005-02-17 14:10:52 +00:00
|
|
|
if (Vertical())
|
2005-03-10 16:03:49 +00:00
|
|
|
floatValue = range - (point.y - fMinpoint);
|
2005-02-17 14:10:52 +00:00
|
|
|
else
|
2005-03-11 13:20:01 +00:00
|
|
|
floatValue = range + (point.x - fMinpoint);
|
2005-03-10 16:03:49 +00:00
|
|
|
|
|
|
|
|
int32 value = (int32)(floatValue / range * limitRange);
|
|
|
|
|
if (fAllChannels)
|
|
|
|
|
SetAllValue(value);
|
|
|
|
|
else
|
|
|
|
|
SetValueFor(fCurrentChannel, value);
|
|
|
|
|
|
2005-02-17 14:10:52 +00:00
|
|
|
InvokeNotifyChannel(ModificationMessage());
|
2005-03-11 13:20:01 +00:00
|
|
|
DrawThumbs();
|
2005-01-15 04:38:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_0(void *, ...) {}
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_1(void *, ...) {}
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_2(void *, ...) {}
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_3(void *, ...) {}
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_4(void *, ...) {}
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_5(void *, ...) {}
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_6(void *, ...) {}
|
|
|
|
|
void BChannelSlider::_Reserved_BChannelSlider_7(void *, ...) {}
|