diff --git a/src/kits/interface/ChannelControl.cpp b/src/kits/interface/ChannelControl.cpp index 3327257b67..b4b4278103 100644 --- a/src/kits/interface/ChannelControl.cpp +++ b/src/kits/interface/ChannelControl.cpp @@ -10,8 +10,23 @@ BChannelControl::BChannelControl(BRect frame, const char *name, const char *label, BMessage *model, int32 channel_count, uint32 resizeMode, uint32 flags) - : BControl(frame, name, label, model, resizeMode, flags) + : BControl(frame, name, label, model, resizeMode, flags), + _m_channel_count(channel_count), + _m_value_channel(0), + _m_channel_min(NULL), + _m_channel_max(NULL), + _m_channel_val(NULL), + _m_multi_labels(NULL), + fModificationMsg(NULL) { + _m_channel_min = new int32[channel_count]; + memset(_m_channel_min, 0, sizeof(int32) * channel_count); + + _m_channel_max = new int32[channel_count]; + memset(_m_channel_max, 64, sizeof(int32) * channel_count); + + _m_channel_val = new int32[channel_count]; + memset(_m_channel_val, 0, sizeof(int32) * channel_count); } @@ -23,6 +38,9 @@ BChannelControl::BChannelControl(BMessage *archive) BChannelControl::~BChannelControl() { + delete[] _m_channel_min; + delete[] _m_channel_max; + delete[] _m_channel_val; } @@ -36,36 +54,44 @@ BChannelControl::Archive(BMessage *into, bool deep) const void BChannelControl::FrameResized(float width, float height) { + BView::FrameResized(width, height); } void BChannelControl::SetFont(const BFont *font, uint32 mask) { + BView::SetFont(font, mask); } void BChannelControl::AttachedToWindow() { + BControl::AttachedToWindow(); } void BChannelControl::DetachedFromWindow() { + BControl::DetachedFromWindow(); } void BChannelControl::ResizeToPreferred() { + float width, height; + GetPreferredSize(&width, &height); + ResizeTo(width, height); } void BChannelControl::MessageReceived(BMessage *message) { + BControl::MessageReceived(message); } @@ -87,13 +113,15 @@ BChannelControl::GetSupportedSuites(BMessage *data) void BChannelControl::SetModificationMessage(BMessage *message) { + delete fModificationMsg; + fModificationMsg = message; } BMessage * BChannelControl::ModificationMessage() const { - return NULL; + return fModificationMsg; } @@ -116,48 +144,99 @@ status_t BChannelControl::InvokeNotifyChannel(BMessage *msg, uint32 kind, int32 fromChannel, int32 channelCount, const bool *inMask) { - return B_ERROR; + BeginInvokeNotify(kind); + status_t status = InvokeChannel(msg, fromChannel, channelCount, inMask); + EndInvokeNotify(); + + return status; } void BChannelControl::SetValue(int32 value) { + // Get real + if (value > _m_channel_max[_m_value_channel]) + value = _m_channel_max[_m_value_channel]; + + if (value < _m_channel_min[_m_value_channel]); + value = _m_channel_min[_m_value_channel]; + + if (value != _m_channel_val[_m_value_channel]) { + StuffValues(_m_value_channel, 1, &value); + BControl::SetValue(value); + } } status_t BChannelControl::SetCurrentChannel(int32 channel) { - return B_ERROR; + if (channel < 0 || channel >= _m_channel_count) + return B_BAD_INDEX; + + if (channel != _m_value_channel) { + _m_value_channel = channel; + BControl::SetValue(_m_channel_val[_m_value_channel]); + } + + return B_OK; } int32 BChannelControl::CurrentChannel() const { - return -1; + return _m_value_channel; } int32 BChannelControl::CountChannels() const { - return -1; + return _m_channel_count; } status_t BChannelControl::SetChannelCount(int32 channel_count) { - return B_ERROR; + if (channel_count < 0 || channel_count >= MaxChannelCount()) + return B_BAD_VALUE; + + // TODO: Currently we only grow the buffer. Test what BeOS does + if (channel_count > _m_channel_count) { + int32 *newMin = new int32[channel_count]; + int32 *newMax = new int32[channel_count]; + int32 *newVal = new int32[channel_count]; + + memcpy(newMin, _m_channel_min, _m_channel_count); + memcpy(newMax, _m_channel_max, _m_channel_count); + memcpy(newVal, _m_channel_val, _m_channel_count); + + delete[] _m_channel_min; + delete[] _m_channel_max; + delete[] _m_channel_val; + + _m_channel_min = newMin; + _m_channel_max = newMax; + _m_channel_val = newVal; + } + + _m_channel_count = channel_count; + + return B_OK; } int32 BChannelControl::ValueFor(int32 channel) const { - return -1; + int32 value = 0; + if (GetValue(&value, channel, 1) <= 0) + return -1; + + return value; } @@ -165,14 +244,18 @@ int32 BChannelControl::GetValue(int32 *outValues, int32 fromChannel, int32 channelCount) const { - return -1; + int32 i = 0; + for (i = 0; i < channelCount; i++) + outValues[i] = _m_channel_val[fromChannel + i]; + + return i; } status_t BChannelControl::SetValueFor(int32 channel, int32 value) { - return B_ERROR; + return SetValue(channel, 1, &value); } @@ -180,7 +263,7 @@ status_t BChannelControl::SetValue(int32 fromChannel, int32 channelCount, const int32 *inValues) { - return B_ERROR; + return StuffValues(fromChannel, channelCount, inValues); } @@ -304,4 +387,3 @@ void BChannelControl::_Reserverd_ChannelControl_8(void *, ...) {} void BChannelControl::_Reserverd_ChannelControl_9(void *, ...) {} void BChannelControl::_Reserverd_ChannelControl_10(void *, ...) {} void BChannelControl::_Reserverd_ChannelControl_11(void *, ...) {} - diff --git a/src/kits/interface/ChannelSlider.cpp b/src/kits/interface/ChannelSlider.cpp index c898e5992f..7b3c47d403 100644 --- a/src/kits/interface/ChannelSlider.cpp +++ b/src/kits/interface/ChannelSlider.cpp @@ -3,46 +3,75 @@ * Distributed under the terms of the MIT License. */ - +#include #include -#include +#include +#include +static property_info +sPropertyInfo[] = { + { "Orientation", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, "" }, + + { "ChannelCount", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, "" }, + + { "CurrentChannel", + { B_GET_PROPERTY, B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, "" }, + + {0} +}; + + 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) { + InitData(); } 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) + { + InitData(); + SetOrientation(o); } BChannelSlider::BChannelSlider(BMessage *archive) : BChannelControl(archive) { + // TODO: Implement } BChannelSlider::~BChannelSlider() { + delete fInitialValues; } BArchivable * BChannelSlider::Instantiate(BMessage *archive) { - return NULL; + if (validate_instantiation(archive, "BChannelSlider")) + return new BChannelSlider(archive); + else + return NULL; } status_t BChannelSlider::Archive(BMessage *into, bool deep) const { + // TODO: Implement return B_ERROR; } @@ -50,20 +79,25 @@ BChannelSlider::Archive(BMessage *into, bool deep) const orientation BChannelSlider::Orientation() const { - return B_VERTICAL; + return _m_vertical ? B_VERTICAL : B_HORIZONTAL; } void -BChannelSlider::SetOrientation(orientation o) +BChannelSlider::SetOrientation(orientation _orientation) { + bool isVertical = _orientation == B_VERTICAL; + if (isVertical != Vertical()) { + _m_vertical = isVertical; + Invalidate(Bounds()); + } } int32 BChannelSlider::MaxChannelCount() const { - return -1; + return 32; } @@ -77,108 +111,146 @@ BChannelSlider::SupportsIndividualLimits() const void BChannelSlider::AttachedToWindow() { + BView *parent = Parent(); + if (parent != NULL) + SetViewColor(parent->ViewColor()); + + inherited::AttachedToWindow(); } void BChannelSlider::AllAttached() { + BControl::AllAttached(); } void BChannelSlider::DetachedFromWindow() { + inherited::DetachedFromWindow(); } void BChannelSlider::AllDetached() { + BControl::AllDetached(); } void -BChannelSlider::MessageReceived(BMessage *msg) +BChannelSlider::MessageReceived(BMessage *message) { + inherited::MessageReceived(message); } void -BChannelSlider::Draw(BRect area) +BChannelSlider::Draw(BRect updateRect) { + UpdateFontDimens(); + DrawThumbs(); + + BRect bounds(Bounds()); + float labelWidth = StringWidth(Label()); + + MovePenTo((bounds.Width() - labelWidth) / 2, 10); + DrawString(Label()); + + // TODO: Respect label limits !!! } void BChannelSlider::MouseDown(BPoint where) { + // TODO: Implement } void -BChannelSlider::MouseUp(BPoint pt) +BChannelSlider::MouseUp(BPoint where) { + // TODO: Implement } void -BChannelSlider::MouseMoved(BPoint pt, uint32 code, const BMessage *message) +BChannelSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message) { + if (IsEnabled() && IsTracking()) + MouseMovedCommon(where, B_ORIGIN); + else + BControl::MouseMoved(where, code, message); } void BChannelSlider::WindowActivated(bool state) { + BControl::WindowActivated(state); } void BChannelSlider::KeyDown(const char *bytes, int32 numBytes) { + // TODO: Implement } void BChannelSlider::KeyUp(const char *bytes, int32 numBytes) { + BView::KeyUp(bytes, numBytes); } void -BChannelSlider::FrameResized(float width, float height) +BChannelSlider::FrameResized(float newWidth, float newHeight) { + inherited::FrameResized(newWidth, newHeight); + Invalidate(Bounds()); } void BChannelSlider::SetFont(const BFont *font, uint32 mask) { + inherited::SetFont(font, mask); } void BChannelSlider::MakeFocus(bool focusState) { + if (focusState && !IsFocus()) + fFocusChannel = -1; + BControl::MakeFocus(focusState); } void BChannelSlider::SetEnabled(bool on) { + BControl::SetEnabled(on); } void BChannelSlider::GetPreferredSize(float *width, float *height) { + // TODO: Implement } BHandler * -BChannelSlider::ResolveSpecifier(BMessage *msg, int32 index, BMessage *specifier, int32 form, const char *property) +BChannelSlider::ResolveSpecifier(BMessage *msg, int32 index, BMessage *specifier, + int32 form, const char *property) { + // TODO: Implement return NULL; } @@ -186,102 +258,211 @@ BChannelSlider::ResolveSpecifier(BMessage *msg, int32 index, BMessage *specifier status_t BChannelSlider::GetSupportedSuites(BMessage *data) { - return B_ERROR; + 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); } void BChannelSlider::DrawChannel(BView *into, int32 channel, BRect area, bool pressed) { + // TODO: Implement } + void -BChannelSlider::DrawGroove(BView *into, int32 channel, BPoint tl, BPoint br) +BChannelSlider::DrawGroove(BView *into, int32 channel, BPoint topLeft, BPoint bottomRight) { + // TODO: Implement } void BChannelSlider::DrawThumb(BView *into, int32 channel, BPoint where, bool pressed) { + ASSERT(into != NULL); + + const BBitmap *thumb = ThumbFor(channel, pressed); + + 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); + BRect rect(where, where); + rect.right += bitmapBounds.right; + rect.bottom += bitmapBounds.bottom; + into->SetHighColor(tint_color(ViewColor(), B_DARKEN_4_TINT)); + into->FillRect(rect); + + into->PopState(); + } } const BBitmap * BChannelSlider::ThumbFor(int32 channel, bool pressed) { - return NULL; + // TODO: Implement } -BRect +BRect BChannelSlider::ThumbFrameFor(int32 channel) { - return BRect(); + UpdateFontDimens(); + + BRect frame(0, 0, 0, 0); + const BBitmap *thumb = ThumbFor(channel, false); + if (thumb != NULL) { + frame = thumb->Bounds(); + if (Vertical()) + frame.OffsetBy(0, _m_linefeed * 2); + else + frame.OffsetBy(_m_linefeed, _m_linefeed); + } + + return frame; } -float +float BChannelSlider::ThumbDeltaFor(int32 channel) { - return 0.0f; + 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; } -float +float BChannelSlider::ThumbRangeFor(int32 channel) { - return 0.0f; + UpdateFontDimens(); + + float range = 0; + + BRect bounds = Bounds(); + BRect frame = ThumbFrameFor(channel); + if (Vertical()) + range = bounds.Height() - frame.Height() - _m_linefeed * 4; + else + range = bounds.Width() - frame.Width() - _m_linefeed * 2; + + return range; } -void +void BChannelSlider::InitData() { + UpdateFontDimens(); + + _m_left_knob = NULL; + _m_mid_knob = NULL; + _m_right_knob = NULL; + _m_backing = NULL; + _m_backing_view = NULL; + _m_vertical = Bounds().Width() / Bounds().Height() < 1; + _m_click_delta = B_ORIGIN; + + fCurrentChannel = -1; + fAllChannels = false; + fInitialValues = NULL; + fMinpoint = 0; + fFocusChannel = -1; + + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + // TODO: Set initial values ? } -void +void BChannelSlider::FinishChange() { + 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(); } -void +void BChannelSlider::UpdateFontDimens() { + font_height height; + GetFontHeight(&height); + _m_baseline = height.ascent + height.leading; + _m_linefeed = _m_baseline + height.descent; } -void +void BChannelSlider::DrawThumbs() -{ +{ } -void +void BChannelSlider::DrawThumbFrame(BView *where, const BRect &area) { } -bool +bool BChannelSlider::Vertical() { - return false; + return _m_vertical; } -void +void BChannelSlider::Redraw() { + Invalidate(Bounds()); + Flush(); } -void -BChannelSlider::MouseMovedCommon(BPoint, BPoint) +void +BChannelSlider::MouseMovedCommon(BPoint , BPoint ) { + // TODO: Implement } @@ -293,4 +474,3 @@ void BChannelSlider::_Reserved_BChannelSlider_4(void *, ...) {} void BChannelSlider::_Reserved_BChannelSlider_5(void *, ...) {} void BChannelSlider::_Reserved_BChannelSlider_6(void *, ...) {} void BChannelSlider::_Reserved_BChannelSlider_7(void *, ...) {} -