diff --git a/src/kits/interface/Button.cpp b/src/kits/interface/Button.cpp index 8519cd79f8..1cc0cf2fab 100644 --- a/src/kits/interface/Button.cpp +++ b/src/kits/interface/Button.cpp @@ -1,542 +1,558 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Button.cpp -// Author: Marc Flerackers (mflerackers@androme.be) -// Description: BButton displays and controls a button in a window. -//------------------------------------------------------------------------------ - -// Standard Includes ----------------------------------------------------------- - -// System Includes ------------------------------------------------------------- -#include -#include -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - -//------------------------------------------------------------------------------ -BButton::BButton(BRect frame, const char *name, const char *label, BMessage *message, - uint32 resizingMode, uint32 flags) - : BControl(frame, name, label, message, resizingMode, flags), - fDrawAsDefault(false) -{ - if (Bounds().Height() < 24.0f) - ResizeTo(Bounds().Width(), 24.0f); -} -//------------------------------------------------------------------------------ -BButton::~BButton() -{ -} -//------------------------------------------------------------------------------ -BButton::BButton(BMessage *archive) - : BControl (archive) -{ - if ( archive->FindBool ( "_default", &fDrawAsDefault ) != B_OK ) - fDrawAsDefault = false; -} -//------------------------------------------------------------------------------ -BArchivable *BButton::Instantiate ( BMessage *archive ) -{ - if (validate_instantiation(archive, "BButton")) - return new BButton(archive); - else - return NULL; -} -//------------------------------------------------------------------------------ -status_t BButton::Archive(BMessage* archive, bool deep) const -{ - status_t err = BControl::Archive(archive, deep); - - if (err != B_OK) - return err; - - if (fDrawAsDefault) - err = archive->AddBool("_default", fDrawAsDefault); - - return err; -} -//------------------------------------------------------------------------------ -void BButton::Draw(BRect updateRect) -{ - BRect rect = Bounds(); - - rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), - lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), - lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT), - lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), - darken2 = tint_color(no_tint, B_DARKEN_2_TINT), - darken4 = tint_color(no_tint, B_DARKEN_4_TINT), - darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); - - if (IsDefault()) - rect = DrawDefault(rect, IsEnabled()); - else - rect.InsetBy(1,1); - - if (IsEnabled()) - { - // This can be set outside draw - SetHighColor(darken4); - - // Dark border - StrokeRect(rect); - - BeginLineArray(8); - - // Corners - AddLine(rect.LeftBottom(), rect.LeftBottom(), no_tint); - AddLine(rect.LeftTop(), rect.LeftTop(), no_tint); - AddLine(rect.RightTop(), rect.RightTop(), no_tint); - AddLine(rect.RightBottom(), rect.RightBottom(), no_tint); - - rect.InsetBy(1, 1); - - // First bevel - AddLine(BPoint(rect.left + 1.0f, rect.bottom), - BPoint(rect.right, rect.bottom), darken2); - AddLine(BPoint(rect.right, rect.bottom - 1.0f), - BPoint(rect.right, rect.top + 1.0f), darken2); - - AddLine(BPoint(rect.left, rect.top), - BPoint(rect.left, rect.bottom), lighten1); - AddLine(BPoint(rect.left + 1.0f, rect.top), - BPoint(rect.right, rect.top), lighten1); - - EndLineArray(); - - rect.InsetBy(1, 1); - - // Second bevel - SetHighColor(lightenmax); - FillRect(rect); - - SetHighColor(no_tint); - StrokeLine(BPoint(rect.right, rect.top + 1.0f), - BPoint(rect.right, rect.bottom)); - StrokeLine(BPoint(rect.left + 1.0f, rect.bottom)); - - rect.InsetBy(1, 1); - - // Filling - rect.left += 1.0f; - rect.top += 1.0f; - SetHighColor(lighten1); - FillRect(rect); - - if (Value()) - { - // Invert - rect.left -= 3; - rect.top -= 3; - rect.right += 2; - rect.bottom += 2; - SetDrawingMode(B_OP_INVERT); - SetHighColor(0, 0, 0); - FillRect(rect); - SetDrawingMode(B_OP_COPY); - } - - // Label - BFont font; - GetFont(&font); - - float x = Bounds().Width() / 2 - StringWidth(Label()) / 2.0f; - float y = Bounds().Height() / 2.0f + (float)ceil(font.Size() / 2.0f); - - if (Value()) - { - SetHighColor(lightenmax); - SetLowColor(darkenmax); - } - else - { - SetHighColor(darkenmax); - SetLowColor(lighten2); - } - - DrawString(Label(), BPoint(x, y)); - - // Focus - if (IsFocus()) - { - font_height fh; - font.GetHeight(&fh); - - y += 2.0f; - SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); - StrokeLine(BPoint(x, y), BPoint(x + StringWidth(Label()), y)); - } - } - else - { - // This can be set outside draw - SetHighColor(darken2); - - // Dark border - StrokeRect(rect); - - BeginLineArray(8); - - // Corners - AddLine(rect.LeftBottom(), rect.LeftBottom(), no_tint); - AddLine(rect.LeftTop(), rect.LeftTop(), no_tint); - AddLine(rect.RightTop(), rect.RightTop(), no_tint); - AddLine(rect.RightBottom(), rect.RightBottom(), no_tint); - - rect.InsetBy(1, 1); - - // First bevel - AddLine(BPoint(rect.left + 1.0f, rect.bottom), - BPoint(rect.right, rect.bottom), no_tint); - AddLine(BPoint(rect.right, rect.bottom - 1.0f), - BPoint(rect.right, rect.top + 1.0f), no_tint); - - AddLine(BPoint(rect.left, rect.top), - BPoint(rect.left, rect.bottom), lighten1); - AddLine(BPoint(rect.left + 1.0f, rect.top), - BPoint(rect.right, rect.top), lighten1); - - EndLineArray(); - - rect.InsetBy(1, 1); - - // Second bevel - SetHighColor(lightenmax); - FillRect(rect); - - SetHighColor(no_tint); - StrokeLine(BPoint(rect.right, rect.top + 1.0f), - BPoint(rect.right, rect.bottom)); - StrokeLine(BPoint(rect.left + 1.0f, rect.bottom)); - - rect.InsetBy(1, 1); - - // Filling - rect.left += 1.0f; - rect.top += 1.0f; - SetHighColor(lighten1); - FillRect(rect); - - // Label - BFont font; - GetFont(&font); - - float x = Bounds().Width() / 2 - StringWidth(Label()) / 2.0f; - float y = Bounds().Height() / 2.0f + (float)ceil(font.Size() / 2.0f); - - SetHighColor(tint_color(no_tint, B_DISABLED_LABEL_TINT)); - SetLowColor(lighten2); - DrawString(Label(), BPoint(x, y)); - } -} -//------------------------------------------------------------------------------ -void BButton::MouseDown(BPoint point) -{ - if (!IsEnabled()) - { - BControl::MouseDown(point); - return; - } - - SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS); - - SetValue(B_CONTROL_ON); - SetTracking(true); -} -//------------------------------------------------------------------------------ -void BButton::AttachedToWindow() -{ - BControl::AttachedToWindow(); - - if (IsDefault()) - Window()->SetDefaultButton(this); -} -//------------------------------------------------------------------------------ -void BButton::KeyDown ( const char *bytes, int32 numBytes ) -{ - if (numBytes == 1) - { - switch (bytes[0]) - { - case B_ENTER: - case B_SPACE: - SetValue(B_CONTROL_ON); - snooze(50000); - SetValue(B_CONTROL_OFF); - Invoke(); - break; - - default: - BControl::KeyDown(bytes, numBytes); - } - } - else - BControl::KeyDown(bytes, numBytes); -} -//------------------------------------------------------------------------------ -void BButton::MakeDefault(bool flag) -{ - if (flag == IsDefault()) - return; - - fDrawAsDefault = flag; - BWindow *window = Window(); - - if (flag) - { - ResizeBy(6.0f, 6.0f); - MoveBy(-3.0f, -3.0f); - - if (window) - window->SetDefaultButton((BButton*)this); - } - else - { - ResizeBy(-6.0f, -6.0f); - MoveBy(3.0f, 3.0f); - - if (window) - window->SetDefaultButton(NULL); - } -} -//------------------------------------------------------------------------------ -void BButton::SetLabel(const char *string) -{ - BControl::SetLabel(string); -} -//------------------------------------------------------------------------------ -bool BButton::IsDefault() const -{ - return fDrawAsDefault; -} -//------------------------------------------------------------------------------ -void BButton::MessageReceived(BMessage *message) -{ - BControl::MessageReceived(message); -} -//------------------------------------------------------------------------------ -void BButton::WindowActivated(bool active) -{ - BControl::WindowActivated(active); -} -//------------------------------------------------------------------------------ -void BButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - if (IsEnabled() && IsTracking()) - { - if (transit == B_EXITED_VIEW) - SetValue(B_CONTROL_OFF); - else if (transit == B_ENTERED_VIEW) - SetValue(B_CONTROL_ON); - } - else - BControl::MouseMoved(point, transit, message); -} -//------------------------------------------------------------------------------ -void BButton::MouseUp(BPoint point) -{ - if (IsEnabled() && IsTracking()) - { - if (Bounds().Contains(point)) - { - if ( Value() == B_CONTROL_ON) - { - SetValue(B_CONTROL_OFF); - BControl::Invoke(); - } - } - - SetTracking(false); - } -} -//------------------------------------------------------------------------------ -void BButton::DetachedFromWindow() -{ - BControl::DetachedFromWindow(); -} -//------------------------------------------------------------------------------ -void BButton::SetValue(int32 value) -{ - BControl::SetValue(value); -} -//------------------------------------------------------------------------------ -void BButton::GetPreferredSize (float *width, float *height) -{ - font_height fh; - - GetFontHeight(&fh); - - *height = (float)ceil(fh.ascent + fh.descent + fh.leading) + 12.0f; - *width = 20.0f + (float)ceil(StringWidth(Label())); - - if (*width < 75.0f) - *width = 75.0f; - - if (fDrawAsDefault) - { - *width += 6.0f; - *height += 6.0f; - } -} -//------------------------------------------------------------------------------ -void BButton::ResizeToPreferred() -{ - BControl::ResizeToPreferred(); -} -//------------------------------------------------------------------------------ -status_t BButton::Invoke(BMessage *message) -{ - return BControl::Invoke(message); -} -//------------------------------------------------------------------------------ -void BButton::FrameMoved(BPoint newLocation) -{ - BControl::FrameMoved(newLocation); -} -//------------------------------------------------------------------------------ -void BButton::FrameResized(float width, float height) -{ - BControl::FrameResized(width, height); -} -//------------------------------------------------------------------------------ -void BButton::MakeFocus(bool focused) -{ - BControl::MakeFocus(focused); -} -//------------------------------------------------------------------------------ -void BButton::AllAttached() -{ - BControl::AllAttached(); -} -//------------------------------------------------------------------------------ -void BButton::AllDetached() -{ - BControl::AllDetached(); -} -//------------------------------------------------------------------------------ -BHandler *BButton::ResolveSpecifier(BMessage *message, int32 index, - BMessage *specifier, int32 what, - const char *property) -{ - return BControl::ResolveSpecifier(message, index, specifier, what, property); -} -//------------------------------------------------------------------------------ -status_t BButton::GetSupportedSuites(BMessage *message) -{ - return BControl::GetSupportedSuites(message); -} -//------------------------------------------------------------------------------ -status_t BButton::Perform(perform_code d, void *arg) -{ - return B_ERROR; -} - -//------------------------------------------------------------------------------ -void BButton::_ReservedButton1() {} -void BButton::_ReservedButton2() {} -void BButton::_ReservedButton3() {} -//------------------------------------------------------------------------------ -BButton &BButton::operator=(const BButton &) -{ - return *this; -} -//------------------------------------------------------------------------------ -BRect BButton::DrawDefault(BRect bounds, bool enabled) -{ - rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), - lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), - darken1 = tint_color(no_tint, B_DARKEN_1_TINT), - darken4 = tint_color(no_tint, B_DARKEN_4_TINT); - - if (enabled) - { - // Dark border - BeginLineArray(4); - AddLine(BPoint(bounds.left, bounds.bottom - 1.0f), - BPoint(bounds.left, bounds.top + 1.0f), darken4); - AddLine(BPoint(bounds.left + 1.0f, bounds.top), - BPoint(bounds.right - 1.0f, bounds.top), darken4); - AddLine(BPoint(bounds.right, bounds.top + 1.0f), - BPoint(bounds.right, bounds.bottom - 1.0f), darken4); - AddLine(BPoint(bounds.left + 1.0f, bounds.bottom), - BPoint(bounds.right - 1.0f, bounds.bottom), darken4); - EndLineArray(); - - bounds.InsetBy(1.0f, 1.0f); - - // Bevel - SetHighColor(darken1); - StrokeRect(bounds); - - bounds.InsetBy(1.0f, 1.0f); - - // Filling - SetHighColor(lighten1); - FillRect(bounds); - - bounds.InsetBy(2.0f, 2.0f); - } - else - { - // Dark border - BeginLineArray(4); - AddLine(BPoint(bounds.left, bounds.bottom - 1.0f), - BPoint(bounds.left, bounds.top + 1.0f), darken1); - AddLine(BPoint(bounds.left + 1.0f, bounds.top), - BPoint(bounds.right - 1.0f, bounds.top), darken1); - AddLine(BPoint(bounds.right, bounds.top + 1.0f), - BPoint(bounds.right, bounds.bottom - 1.0f), darken1); - AddLine(BPoint(bounds.left + 1.0f, bounds.bottom), - BPoint(bounds.right - 1.0f, bounds.bottom), darken1); - EndLineArray(); - - bounds.InsetBy(1.0f, 1.0f); - - // Filling - SetHighColor(lighten1); - FillRect(bounds); - - bounds.InsetBy(3.0f, 3.0f); - } - - return bounds; -} -//------------------------------------------------------------------------------ -status_t Execute() -{ - // TODO: - return B_ERROR; -} -//------------------------------------------------------------------------------ - -/* - * $Log $ - * - * $Id $ - * - */ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: Button.cpp +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: BButton displays and controls a button in a window. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- +#include +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +BButton::BButton(BRect frame, const char *name, const char *label, BMessage *message, + uint32 resizingMode, uint32 flags) + : BControl(frame, name, label, message, resizingMode, flags), + fDrawAsDefault(false) +{ + // Resize to minimum height if needed + font_height fh; + GetFontHeight(&fh); + float minHeight = 12.0f + (float)ceil(fh.ascent + fh.descent); + if (Bounds().Height() < minHeight) + ResizeTo(Bounds().Width(), minHeight); +} +//------------------------------------------------------------------------------ +BButton::~BButton() +{ +} +//------------------------------------------------------------------------------ +BButton::BButton(BMessage *archive) + : BControl (archive) +{ + if (archive->FindBool("_default", &fDrawAsDefault) != B_OK) + fDrawAsDefault = false; +} +//------------------------------------------------------------------------------ +BArchivable *BButton::Instantiate(BMessage *archive) +{ + if (validate_instantiation(archive, "BButton")) + return new BButton(archive); + else + return NULL; +} +//------------------------------------------------------------------------------ +status_t BButton::Archive(BMessage* archive, bool deep) const +{ + status_t err = BControl::Archive(archive, deep); + + if (err != B_OK) + return err; + + if (fDrawAsDefault) + err = archive->AddBool("_default", fDrawAsDefault); + + return err; +} +//------------------------------------------------------------------------------ +void BButton::Draw(BRect updateRect) +{ + font_height fh; + GetFontHeight(&fh); + + BRect bounds(Bounds()); + + // If the focus is changing, just redraw the focus indicator + if (IsFocusChanging()) + { + float x = bounds.right / 2 - StringWidth(Label()) / 2.0f; + float y = bounds.bottom - fh.descent - (IsDefault() ? 6.0f : 3.0f); + + if (IsFocus()) + SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); + else + SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), + B_LIGHTEN_1_TINT)); + + StrokeLine(BPoint(x, y), BPoint(x + StringWidth(Label()), y)); + + return; + } + + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), + lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), + lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT), + lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), + darken2 = tint_color(no_tint, B_DARKEN_2_TINT), + darken4 = tint_color(no_tint, B_DARKEN_4_TINT), + darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); + + BRect rect(bounds); + + if (IsDefault()) + rect = DrawDefault(rect, IsEnabled()); + else + rect.InsetBy(1,1); + + if (IsEnabled()) + { + // This can be set outside draw + SetHighColor(darken4); + + // Dark border + StrokeRect(rect); + + BeginLineArray(8); + + // Corners + AddLine(rect.LeftBottom(), rect.LeftBottom(), no_tint); + AddLine(rect.LeftTop(), rect.LeftTop(), no_tint); + AddLine(rect.RightTop(), rect.RightTop(), no_tint); + AddLine(rect.RightBottom(), rect.RightBottom(), no_tint); + + rect.InsetBy(1, 1); + + // First bevel + AddLine(BPoint(rect.left + 1.0f, rect.bottom), + BPoint(rect.right, rect.bottom), darken2); + AddLine(BPoint(rect.right, rect.bottom - 1.0f), + BPoint(rect.right, rect.top + 1.0f), darken2); + + AddLine(BPoint(rect.left, rect.top), + BPoint(rect.left, rect.bottom), lighten1); + AddLine(BPoint(rect.left + 1.0f, rect.top), + BPoint(rect.right, rect.top), lighten1); + + EndLineArray(); + + rect.InsetBy(1, 1); + + // Second bevel + SetHighColor(lightenmax); + FillRect(rect); + + SetHighColor(no_tint); + StrokeLine(BPoint(rect.right, rect.top + 1.0f), + BPoint(rect.right, rect.bottom)); + StrokeLine(BPoint(rect.left + 1.0f, rect.bottom)); + + rect.InsetBy(1, 1); + + // Filling + rect.left += 1.0f; + rect.top += 1.0f; + SetHighColor(lighten1); + FillRect(rect); + + if (Value()) + { + // Invert + rect.left -= 3; + rect.top -= 3; + rect.right += 2; + rect.bottom += 2; + SetDrawingMode(B_OP_INVERT); + SetHighColor(0, 0, 0); + FillRect(rect); + SetDrawingMode(B_OP_COPY); + } + + // Label + float x = bounds.right / 2 - StringWidth(Label()) / 2.0f; + float y = bounds.bottom - fh.descent - (IsDefault() ? 8.0f : 5.0f); + + if (Value()) + { + SetHighColor(lightenmax); + SetLowColor(darkenmax); + } + else + { + SetHighColor(darkenmax); + SetLowColor(lighten2); + } + + DrawString(Label(), BPoint(x, y)); + + // Focus + if (IsFocus()) + { + y += 2.0f; + SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); + StrokeLine(BPoint(x, y), BPoint(x + StringWidth(Label()), y)); + } + } + else + { + // This can be set outside draw + SetHighColor(darken2); + + // Dark border + StrokeRect(rect); + + BeginLineArray(8); + + // Corners + AddLine(rect.LeftBottom(), rect.LeftBottom(), no_tint); + AddLine(rect.LeftTop(), rect.LeftTop(), no_tint); + AddLine(rect.RightTop(), rect.RightTop(), no_tint); + AddLine(rect.RightBottom(), rect.RightBottom(), no_tint); + + rect.InsetBy(1, 1); + + // First bevel + AddLine(BPoint(rect.left + 1.0f, rect.bottom), + BPoint(rect.right, rect.bottom), no_tint); + AddLine(BPoint(rect.right, rect.bottom - 1.0f), + BPoint(rect.right, rect.top + 1.0f), no_tint); + + AddLine(BPoint(rect.left, rect.top), + BPoint(rect.left, rect.bottom), lighten1); + AddLine(BPoint(rect.left + 1.0f, rect.top), + BPoint(rect.right, rect.top), lighten1); + + EndLineArray(); + + rect.InsetBy(1, 1); + + // Second bevel + SetHighColor(lightenmax); + FillRect(rect); + + SetHighColor(no_tint); + StrokeLine(BPoint(rect.right, rect.top + 1.0f), + BPoint(rect.right, rect.bottom)); + StrokeLine(BPoint(rect.left + 1.0f, rect.bottom)); + + rect.InsetBy(1, 1); + + // Filling + rect.left += 1.0f; + rect.top += 1.0f; + SetHighColor(lighten1); + FillRect(rect); + + // Label + float x = bounds.right / 2 - StringWidth(Label()) / 2.0f; + float y = bounds.bottom - fh.descent - 5.0f; + + SetHighColor(tint_color(no_tint, B_DISABLED_LABEL_TINT)); + SetLowColor(lighten2); + DrawString(Label(), BPoint(x, y)); + } +} +//------------------------------------------------------------------------------ +void BButton::MouseDown(BPoint point) +{ + if (!IsEnabled()) + { + BControl::MouseDown(point); + return; + } + + SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS); + + SetValue(B_CONTROL_ON); + SetTracking(true); +} +//------------------------------------------------------------------------------ +void BButton::AttachedToWindow() +{ + BControl::AttachedToWindow(); + + if (IsDefault()) + Window()->SetDefaultButton(this); +} +//------------------------------------------------------------------------------ +void BButton::KeyDown ( const char *bytes, int32 numBytes ) +{ + if (numBytes == 1) + { + switch (bytes[0]) + { + case B_ENTER: + case B_SPACE: + SetValue(B_CONTROL_ON); + snooze(50000); + SetValue(B_CONTROL_OFF); + Invoke(); + break; + + default: + BControl::KeyDown(bytes, numBytes); + } + } + else + BControl::KeyDown(bytes, numBytes); +} +//------------------------------------------------------------------------------ +void BButton::MakeDefault(bool flag) +{ + if (flag == IsDefault()) + return; + + fDrawAsDefault = flag; + BWindow *window = Window(); + + if (flag) + { + ResizeBy(6.0f, 6.0f); + MoveBy(-3.0f, -3.0f); + + if (window) + window->SetDefaultButton((BButton*)this); + } + else + { + ResizeBy(-6.0f, -6.0f); + MoveBy(3.0f, 3.0f); + + if (window) + window->SetDefaultButton(NULL); + } +} +//------------------------------------------------------------------------------ +void BButton::SetLabel(const char *string) +{ + BControl::SetLabel(string); +} +//------------------------------------------------------------------------------ +bool BButton::IsDefault() const +{ + return fDrawAsDefault; +} +//------------------------------------------------------------------------------ +void BButton::MessageReceived(BMessage *message) +{ + BControl::MessageReceived(message); +} +//------------------------------------------------------------------------------ +void BButton::WindowActivated(bool active) +{ + BControl::WindowActivated(active); +} +//------------------------------------------------------------------------------ +void BButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +{ + if (IsEnabled() && IsTracking()) + { + if (transit == B_EXITED_VIEW) + SetValue(B_CONTROL_OFF); + else if (transit == B_ENTERED_VIEW) + SetValue(B_CONTROL_ON); + } + else + BControl::MouseMoved(point, transit, message); +} +//------------------------------------------------------------------------------ +void BButton::MouseUp(BPoint point) +{ + if (IsEnabled() && IsTracking()) + { + if (Bounds().Contains(point)) + { + if ( Value() == B_CONTROL_ON) + { + SetValue(B_CONTROL_OFF); + Invoke(); + } + } + + SetTracking(false); + } +} +//------------------------------------------------------------------------------ +void BButton::DetachedFromWindow() +{ + BControl::DetachedFromWindow(); +} +//------------------------------------------------------------------------------ +void BButton::SetValue(int32 value) +{ + BControl::SetValue(value); +} +//------------------------------------------------------------------------------ +void BButton::GetPreferredSize(float *width, float *height) +{ + font_height fh; + GetFontHeight(&fh); + + *height = 12.0f + (float)ceil(fh.ascent + fh.descent); + *width = 20.0f + (float)ceil(StringWidth(Label())); + + if (*width < 75.0f) + *width = 75.0f; + + if (fDrawAsDefault) + { + *width += 6.0f; + *height += 6.0f; + } +} +//------------------------------------------------------------------------------ +void BButton::ResizeToPreferred() +{ + BControl::ResizeToPreferred(); +} +//------------------------------------------------------------------------------ +status_t BButton::Invoke(BMessage *message) +{ + return BControl::Invoke(message); +} +//------------------------------------------------------------------------------ +void BButton::FrameMoved(BPoint newLocation) +{ + BControl::FrameMoved(newLocation); +} +//------------------------------------------------------------------------------ +void BButton::FrameResized(float width, float height) +{ + BControl::FrameResized(width, height); +} +//------------------------------------------------------------------------------ +void BButton::MakeFocus(bool focused) +{ + BControl::MakeFocus(focused); +} +//------------------------------------------------------------------------------ +void BButton::AllAttached() +{ + BControl::AllAttached(); +} +//------------------------------------------------------------------------------ +void BButton::AllDetached() +{ + BControl::AllDetached(); +} +//------------------------------------------------------------------------------ +BHandler *BButton::ResolveSpecifier(BMessage *message, int32 index, + BMessage *specifier, int32 what, + const char *property) +{ + return BControl::ResolveSpecifier(message, index, specifier, what, property); +} +//------------------------------------------------------------------------------ +status_t BButton::GetSupportedSuites(BMessage *message) +{ + return BControl::GetSupportedSuites(message); +} +//------------------------------------------------------------------------------ +status_t BButton::Perform(perform_code d, void *arg) +{ + return B_ERROR; +} + +//------------------------------------------------------------------------------ +void BButton::_ReservedButton1() {} +void BButton::_ReservedButton2() {} +void BButton::_ReservedButton3() {} +//------------------------------------------------------------------------------ +BButton &BButton::operator=(const BButton &) +{ + return *this; +} +//------------------------------------------------------------------------------ +BRect BButton::DrawDefault(BRect bounds, bool enabled) +{ + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), + lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), + darken1 = tint_color(no_tint, B_DARKEN_1_TINT), + darken4 = tint_color(no_tint, B_DARKEN_4_TINT); + + if (enabled) + { + // Dark border + BeginLineArray(4); + AddLine(BPoint(bounds.left, bounds.bottom - 1.0f), + BPoint(bounds.left, bounds.top + 1.0f), darken4); + AddLine(BPoint(bounds.left + 1.0f, bounds.top), + BPoint(bounds.right - 1.0f, bounds.top), darken4); + AddLine(BPoint(bounds.right, bounds.top + 1.0f), + BPoint(bounds.right, bounds.bottom - 1.0f), darken4); + AddLine(BPoint(bounds.left + 1.0f, bounds.bottom), + BPoint(bounds.right - 1.0f, bounds.bottom), darken4); + EndLineArray(); + + bounds.InsetBy(1.0f, 1.0f); + + // Bevel + SetHighColor(darken1); + StrokeRect(bounds); + + bounds.InsetBy(1.0f, 1.0f); + + // Filling + SetHighColor(lighten1); + FillRect(bounds); + + bounds.InsetBy(2.0f, 2.0f); + } + else + { + // Dark border + BeginLineArray(4); + AddLine(BPoint(bounds.left, bounds.bottom - 1.0f), + BPoint(bounds.left, bounds.top + 1.0f), darken1); + AddLine(BPoint(bounds.left + 1.0f, bounds.top), + BPoint(bounds.right - 1.0f, bounds.top), darken1); + AddLine(BPoint(bounds.right, bounds.top + 1.0f), + BPoint(bounds.right, bounds.bottom - 1.0f), darken1); + AddLine(BPoint(bounds.left + 1.0f, bounds.bottom), + BPoint(bounds.right - 1.0f, bounds.bottom), darken1); + EndLineArray(); + + bounds.InsetBy(1.0f, 1.0f); + + // Filling + SetHighColor(lighten1); + FillRect(bounds); + + bounds.InsetBy(3.0f, 3.0f); + } + + return bounds; +} +//------------------------------------------------------------------------------ +status_t BButton::Execute() +{ + // TODO: Is there a use for this? Maybe visual feedback happens here? + return Invoke(); +} +//------------------------------------------------------------------------------ + +/* + * $Log $ + * + * $Id $ + * + */ diff --git a/src/kits/interface/Control.cpp b/src/kits/interface/Control.cpp index fabe26da4c..ef17becb3f 100644 --- a/src/kits/interface/Control.cpp +++ b/src/kits/interface/Control.cpp @@ -1,536 +1,538 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Control.cpp -// Author: Marc Flerackers (mflerackers@androme.be) -// Description: BControl is the base class for user-event handling objects. -//------------------------------------------------------------------------------ - -// Standard Includes ----------------------------------------------------------- -#include -#include - -// System Includes ------------------------------------------------------------- -#include -#include -#include -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- -static property_info prop_list[] = -{ - { - "Enabled", - { B_GET_PROPERTY, 0 }, - { B_DIRECT_SPECIFIER, 0 }, - "Returns whether or not the BControl is currently enabled.", 0, - { B_BOOL_TYPE, 0 } - }, - { - "Enabled", - { B_SET_PROPERTY, 0 }, - { B_DIRECT_SPECIFIER, 0 }, - "Enables or disables the BControl.", 0, - { B_BOOL_TYPE, 0 } - }, - { - "Label", - { B_GET_PROPERTY, 0 }, - { B_DIRECT_SPECIFIER, 0 }, - "Returns the BControl's label.", 0, - { B_STRING_TYPE, 0 } - }, - { - "Label", - { B_SET_PROPERTY, 0 }, - { B_DIRECT_SPECIFIER, 0 }, - "Sets the label of the BControl.", 0, - { B_STRING_TYPE, 0 } - }, - { - "Value", - { B_GET_PROPERTY, 0 }, - { B_DIRECT_SPECIFIER, 0 }, - "Returns the BControl's value.", 0, - { B_INT32_TYPE, 0 } - }, - { - "Value", - { B_SET_PROPERTY, 0 }, - { B_DIRECT_SPECIFIER, 0 }, - "Sets the value of the BControl.", 0, - { B_INT32_TYPE, 0 }, - }, - { 0 } -}; - -//------------------------------------------------------------------------------ -BControl::BControl(BRect frame, const char *name, const char *label, BMessage *message, - uint32 resizingMode, uint32 flags) - : BView(frame, name, resizingMode, flags), - BInvoker(message, NULL), - fValue(B_CONTROL_OFF), - fEnabled(true), - fFocusChanging(false), - fTracking(false), - fWantsNav(true) -{ - fLabel = strdup(label); -} -//------------------------------------------------------------------------------ -BControl::~BControl() -{ - if (fLabel) - free(fLabel); -} -//------------------------------------------------------------------------------ -BControl::BControl(BMessage *archive) : BView(archive) -{ - const char *label; - - if (archive->FindInt32("_val", &fValue) != B_OK) - fValue = B_CONTROL_OFF; - - if (archive->FindString("_label", &label) != B_OK) - fLabel = NULL; - else - SetLabel(label); - - if ( archive->FindBool("_disable", &fEnabled) != B_OK) - fEnabled = true; - else - fEnabled = !fEnabled; - - fFocusChanging = false; - fTracking = false; - fWantsNav = true; - - BMessage message; - - if (archive->FindMessage("_msg", &message) == B_OK) - SetMessage(new BMessage(message)); -} -//------------------------------------------------------------------------------ -BArchivable *BControl::Instantiate(BMessage *archive) -{ - if (validate_instantiation(archive, "BControl")) - return new BControl(archive); - else - return NULL; -} -//------------------------------------------------------------------------------ -status_t BControl::Archive(BMessage *archive, bool deep) const -{ - status_t err = BView::Archive(archive, deep); - - if (err != B_OK) - return err; - - if (Message()) - err = archive->AddMessage("_msg", Message ()); - - if (err != B_OK) - return err; - - if (fLabel) - err = archive->AddString("_label", fLabel); - - if (err != B_OK ) - return err; - - if (fValue != B_CONTROL_OFF) - err = archive->AddInt32("_val", fValue); - - if (err != B_OK) - return err; - - if (!fEnabled) - err = archive->AddBool("_disable", true); - - return err; -} -//------------------------------------------------------------------------------ -void BControl::WindowActivated(bool active) -{ - // Should we check this? - if (Window()) - { - Draw(Bounds()); - Flush(); - } - - BView::WindowActivated(active); -} -//------------------------------------------------------------------------------ -void BControl::AttachedToWindow() -{ - if (Parent()) - SetViewColor(Parent()->ViewColor()); - - if (Target() == NULL) - BInvoker::SetTarget(BMessenger(Window(), NULL)); - - BView::AttachedToWindow(); -} -//------------------------------------------------------------------------------ -void BControl::MessageReceived(BMessage *message) -{ - switch (message->what) - { - case B_CONTROL_INVOKED: - Invoke(); - break; - - case B_GET_PROPERTY: - case B_SET_PROPERTY: - { - BPropertyInfo propInfo(prop_list); - BMessage specifier; - const char *property; - - if (message->GetCurrentSpecifier(NULL, &specifier) != B_OK || - specifier.FindString("property", &property) != B_OK) - return; - - switch (propInfo.FindMatch(message, 0, &specifier, specifier.what, property)) - { - case B_ERROR: - { - BView::MessageReceived(message); - break; - } - case 0: - { - BMessage reply; - reply.AddBool("result", fEnabled); - reply.AddBool("error", B_OK); - message->SendReply(&reply); - break; - } - case 1: - { - bool enabled; - message->FindBool("data", &enabled); - SetEnabled(enabled); - break; - } - case 2: - { - BMessage reply; - reply.AddString("result", fLabel); - reply.AddBool("error", B_OK); - message->SendReply(&reply); - break; - } - case 3: - { - const char *label; - message->FindString("data", &label); - SetLabel(label); - break; - } - case 4: - { - BMessage reply; - reply.AddInt32("result", fValue); - reply.AddBool("error", B_OK); - message->SendReply(&reply); - break; - } - case 5: - { - int32 value; - message->FindInt32("data", &value); - SetValue(value); - break; - } - } - - break; - } - default: - { - BView::MessageReceived(message); - break; - } - } -} -//------------------------------------------------------------------------------ -void BControl::MakeFocus(bool focused) -{ - BView::MakeFocus(focused); - - if(Window()) - { - fFocusChanging = true; - Draw(Bounds()); - Flush(); - fFocusChanging = false; - } -} -//------------------------------------------------------------------------------ -void BControl::KeyDown(const char *bytes, int32 numBytes) -{ - if (numBytes == 1) - { - switch (bytes[0]) - { - case B_ENTER: - case B_SPACE: - if (Value()) - SetValue(B_CONTROL_OFF); - else - SetValue(B_CONTROL_ON); - - BInvoker::Invoke(); - break; - - default: - BView::KeyDown(bytes, numBytes); - } - } - else - BView::KeyDown(bytes, numBytes); -} -//------------------------------------------------------------------------------ -void BControl::MouseDown(BPoint point) -{ - BView::MouseDown(point); -} -//------------------------------------------------------------------------------ -void BControl::MouseUp(BPoint point) -{ - BView::MouseUp(point); -} -//------------------------------------------------------------------------------ -void BControl::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - BView::MouseMoved(point, transit, message); -} -//------------------------------------------------------------------------------ -void BControl::DetachedFromWindow() -{ - BView::DetachedFromWindow(); -} -//------------------------------------------------------------------------------ -void BControl::SetLabel(const char *string) -{ - if (fLabel) - free(fLabel); - - fLabel = strdup(string); - - Invalidate(); -} -//------------------------------------------------------------------------------ -const char *BControl::Label() const -{ - return fLabel; -} -//------------------------------------------------------------------------------ -void BControl::SetValue(int32 value) -{ - if (fValue == value) - return; - - fValue = value; - - if (Window()) - { - Draw(Bounds()); - Flush(); - } -} -//------------------------------------------------------------------------------ -int32 BControl::Value() const -{ - return fValue; -} -//------------------------------------------------------------------------------ -void BControl::SetEnabled(bool enabled) -{ - if (fEnabled == enabled) - return; - - fEnabled = enabled; - - if (fEnabled) - BView::SetFlags(Flags() | B_NAVIGABLE); - else - BView::SetFlags(Flags() & ~B_NAVIGABLE); - - if (Window()) - { - Draw(Bounds()); - Flush(); - } -} -//------------------------------------------------------------------------------ -bool BControl::IsEnabled() const -{ - return fEnabled; -} -//------------------------------------------------------------------------------ -void BControl::GetPreferredSize(float *width, float *height) -{ - *width = 1.0f; - *height = 1.0f; -} -//------------------------------------------------------------------------------ -void BControl::ResizeToPreferred() -{ - BView::ResizeToPreferred(); -} -//------------------------------------------------------------------------------ -status_t BControl::Invoke(BMessage *message) -{ - if (message) - { - BMessage copy(*message); - copy.AddInt64("when", (int64)system_time()); - copy.AddPointer("source", this); - return BInvoker::Invoke(©); - } - else if ( Message () ) - { - BMessage copy (*Message()); - copy.AddInt64 ("when", (int64)system_time()); - copy.AddPointer ("source", this); - return BInvoker::Invoke(©); - } - - return B_BAD_VALUE; -} -//------------------------------------------------------------------------------ -BHandler *BControl::ResolveSpecifier(BMessage *message, int32 index, - BMessage *specifier, int32 what, - const char *property) -{ - BPropertyInfo propInfo(prop_list); - BHandler *target = NULL; - - switch (propInfo.FindMatch(message, 0, specifier, what, property)) - { - case B_ERROR: - break; - - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - target = this; - break; - } - - if (!target) - target = BView::ResolveSpecifier(message, index, specifier, what, - property); - - return target; -} -//------------------------------------------------------------------------------ -status_t BControl::GetSupportedSuites(BMessage *message) -{ - status_t err; - - if (message == NULL) - return B_BAD_VALUE; - - err = message->AddString("suites", "suite/vnd.Be-control"); - - if (err != B_OK) - return err; - - BPropertyInfo prop_info(prop_list); - err = message->AddFlat("messages", &prop_info); - - if (err != B_OK) - return err; - - return BView::GetSupportedSuites(message); -} -//------------------------------------------------------------------------------ -void BControl::AllAttached() -{ - BView::AllAttached(); -} -//------------------------------------------------------------------------------ -void BControl::AllDetached() -{ - BView::AllDetached(); -} -//------------------------------------------------------------------------------ -status_t BControl::Perform(perform_code d, void *arg) -{ - return B_ERROR; -} -//------------------------------------------------------------------------------ -bool BControl::IsFocusChanging() const -{ - return fFocusChanging; -} -//------------------------------------------------------------------------------ -bool BControl::IsTracking() const -{ - return fTracking; -} -//------------------------------------------------------------------------------ -void BControl::SetTracking(bool state) -{ - fTracking = state; -} -//------------------------------------------------------------------------------ -void BControl::SetValueNoUpdate(int32 value) -{ - fValue = value; -} - -//------------------------------------------------------------------------------ -void BControl::_ReservedControl1() {} -void BControl::_ReservedControl2() {} -void BControl::_ReservedControl3() {} -void BControl::_ReservedControl4() {} -//------------------------------------------------------------------------------ -BControl &BControl::operator=(const BControl &) -{ - return *this; -} -//------------------------------------------------------------------------------ -void BControl::InitData(BMessage *data) -{ - -} -//------------------------------------------------------------------------------ - -/* - * $Log $ - * - * $Id $ - * - */ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: Control.cpp +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: BControl is the base class for user-event handling objects. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include +#include + +// System Includes ------------------------------------------------------------- +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- +static property_info prop_list[] = +{ + { + "Enabled", + { B_GET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, + "Returns whether or not the BControl is currently enabled.", 0, + { B_BOOL_TYPE, 0 } + }, + { + "Enabled", + { B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, + "Enables or disables the BControl.", 0, + { B_BOOL_TYPE, 0 } + }, + { + "Label", + { B_GET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, + "Returns the BControl's label.", 0, + { B_STRING_TYPE, 0 } + }, + { + "Label", + { B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, + "Sets the label of the BControl.", 0, + { B_STRING_TYPE, 0 } + }, + { + "Value", + { B_GET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, + "Returns the BControl's value.", 0, + { B_INT32_TYPE, 0 } + }, + { + "Value", + { B_SET_PROPERTY, 0 }, + { B_DIRECT_SPECIFIER, 0 }, + "Sets the value of the BControl.", 0, + { B_INT32_TYPE, 0 }, + }, + { 0 } +}; + +//------------------------------------------------------------------------------ +BControl::BControl(BRect frame, const char *name, const char *label, BMessage *message, + uint32 resizingMode, uint32 flags) + : BView(frame, name, resizingMode, flags), + BInvoker(message, NULL), + fValue(B_CONTROL_OFF), + fEnabled(true), + fFocusChanging(false), + fTracking(false), + fWantsNav(true) +{ + fLabel = strdup(label); +} +//------------------------------------------------------------------------------ +BControl::~BControl() +{ + if (fLabel) + free(fLabel); +} +//------------------------------------------------------------------------------ +BControl::BControl(BMessage *archive) : BView(archive) +{ + const char *label; + + if (archive->FindInt32("_val", &fValue) != B_OK) + fValue = B_CONTROL_OFF; + + if (archive->FindString("_label", &label) != B_OK) + fLabel = NULL; + else + SetLabel(label); + + if ( archive->FindBool("_disable", &fEnabled) != B_OK) + fEnabled = true; + else + fEnabled = !fEnabled; + + fFocusChanging = false; + fTracking = false; + fWantsNav = true; + + BMessage message; + + if (archive->FindMessage("_msg", &message) == B_OK) + SetMessage(new BMessage(message)); +} +//------------------------------------------------------------------------------ +BArchivable *BControl::Instantiate(BMessage *archive) +{ + if (validate_instantiation(archive, "BControl")) + return new BControl(archive); + else + return NULL; +} +//------------------------------------------------------------------------------ +status_t BControl::Archive(BMessage *archive, bool deep) const +{ + status_t err = BView::Archive(archive, deep); + + if (err != B_OK) + return err; + + if (Message()) + err = archive->AddMessage("_msg", Message ()); + + if (err != B_OK) + return err; + + if (fLabel) + err = archive->AddString("_label", fLabel); + + if (err != B_OK ) + return err; + + if (fValue != B_CONTROL_OFF) + err = archive->AddInt32("_val", fValue); + + if (err != B_OK) + return err; + + if (!fEnabled) + err = archive->AddBool("_disable", true); + + return err; +} +//------------------------------------------------------------------------------ +void BControl::WindowActivated(bool active) +{ + if (IsFocus()) + { + Draw(Bounds()); + Flush(); + } + + BView::WindowActivated(active); +} +//------------------------------------------------------------------------------ +void BControl::AttachedToWindow() +{ + if (Parent()) + SetViewColor(Parent()->ViewColor()); + + if (Target() == NULL) + BInvoker::SetTarget(BMessenger(Window(), NULL)); + + BView::AttachedToWindow(); +} +//------------------------------------------------------------------------------ +void BControl::MessageReceived(BMessage *message) +{ + switch (message->what) + { + case B_CONTROL_INVOKED: + Invoke(); + break; + + case B_GET_PROPERTY: + case B_SET_PROPERTY: + { + BPropertyInfo propInfo(prop_list); + BMessage specifier; + const char *property; + + if (message->GetCurrentSpecifier(NULL, &specifier) != B_OK || + specifier.FindString("property", &property) != B_OK) + return; + + switch (propInfo.FindMatch(message, 0, &specifier, specifier.what, property)) + { + case B_ERROR: + { + BView::MessageReceived(message); + break; + } + case 0: + { + BMessage reply; + reply.AddBool("result", fEnabled); + reply.AddBool("error", B_OK); + message->SendReply(&reply); + break; + } + case 1: + { + bool enabled; + message->FindBool("data", &enabled); + SetEnabled(enabled); + break; + } + case 2: + { + BMessage reply; + reply.AddString("result", fLabel); + reply.AddBool("error", B_OK); + message->SendReply(&reply); + break; + } + case 3: + { + const char *label; + message->FindString("data", &label); + SetLabel(label); + break; + } + case 4: + { + BMessage reply; + reply.AddInt32("result", fValue); + reply.AddBool("error", B_OK); + message->SendReply(&reply); + break; + } + case 5: + { + int32 value; + message->FindInt32("data", &value); + SetValue(value); + break; + } + } + + break; + } + default: + { + BView::MessageReceived(message); + break; + } + } +} +//------------------------------------------------------------------------------ +void BControl::MakeFocus(bool focused) +{ + BView::MakeFocus(focused); + + if(Window()) + { + fFocusChanging = true; + Draw(Bounds()); + Flush(); + fFocusChanging = false; + } +} +//------------------------------------------------------------------------------ +void BControl::KeyDown(const char *bytes, int32 numBytes) +{ + if (numBytes == 1) + { + switch (bytes[0]) + { + case B_ENTER: + case B_SPACE: + if (Value()) + SetValue(B_CONTROL_OFF); + else + SetValue(B_CONTROL_ON); + + BInvoker::Invoke(); + break; + + default: + BView::KeyDown(bytes, numBytes); + } + } + else + BView::KeyDown(bytes, numBytes); +} +//------------------------------------------------------------------------------ +void BControl::MouseDown(BPoint point) +{ + BView::MouseDown(point); +} +//------------------------------------------------------------------------------ +void BControl::MouseUp(BPoint point) +{ + BView::MouseUp(point); +} +//------------------------------------------------------------------------------ +void BControl::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +{ + BView::MouseMoved(point, transit, message); +} +//------------------------------------------------------------------------------ +void BControl::DetachedFromWindow() +{ + BView::DetachedFromWindow(); +} +//------------------------------------------------------------------------------ +void BControl::SetLabel(const char *string) +{ + if (strcmp(fLabel, string) == 0) + return; + + if (fLabel) + free(fLabel); + + fLabel = strdup(string); + + Invalidate(); +} +//------------------------------------------------------------------------------ +const char *BControl::Label() const +{ + return fLabel; +} +//------------------------------------------------------------------------------ +void BControl::SetValue(int32 value) +{ + if (fValue == value) + return; + + fValue = value; + + if (Window()) + { + Draw(Bounds()); + Flush(); + } +} +//------------------------------------------------------------------------------ +int32 BControl::Value() const +{ + return fValue; +} +//------------------------------------------------------------------------------ +void BControl::SetEnabled(bool enabled) +{ + if (fEnabled == enabled) + return; + + fEnabled = enabled; + + if (fEnabled) + BView::SetFlags(Flags() | B_NAVIGABLE); + else + BView::SetFlags(Flags() & ~B_NAVIGABLE); + + if (Window()) + { + Draw(Bounds()); + Flush(); + } +} +//------------------------------------------------------------------------------ +bool BControl::IsEnabled() const +{ + return fEnabled; +} +//------------------------------------------------------------------------------ +void BControl::GetPreferredSize(float *width, float *height) +{ + *width = 1.0f; + *height = 1.0f; +} +//------------------------------------------------------------------------------ +void BControl::ResizeToPreferred() +{ + BView::ResizeToPreferred(); +} +//------------------------------------------------------------------------------ +status_t BControl::Invoke(BMessage *message) +{ + if (message) + { + BMessage copy(*message); + copy.AddInt64("when", (int64)system_time()); + copy.AddPointer("source", this); + return BInvoker::Invoke(©); + } + else if ( Message () ) + { + BMessage copy (*Message()); + copy.AddInt64 ("when", (int64)system_time()); + copy.AddPointer ("source", this); + return BInvoker::Invoke(©); + } + + return B_BAD_VALUE; +} +//------------------------------------------------------------------------------ +BHandler *BControl::ResolveSpecifier(BMessage *message, int32 index, + BMessage *specifier, int32 what, + const char *property) +{ + BPropertyInfo propInfo(prop_list); + BHandler *target = NULL; + + switch (propInfo.FindMatch(message, 0, specifier, what, property)) + { + case B_ERROR: + break; + + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + target = this; + break; + } + + if (!target) + target = BView::ResolveSpecifier(message, index, specifier, what, + property); + + return target; +} +//------------------------------------------------------------------------------ +status_t BControl::GetSupportedSuites(BMessage *message) +{ + status_t err; + + if (message == NULL) + return B_BAD_VALUE; + + err = message->AddString("suites", "suite/vnd.Be-control"); + + if (err != B_OK) + return err; + + BPropertyInfo prop_info(prop_list); + err = message->AddFlat("messages", &prop_info); + + if (err != B_OK) + return err; + + return BView::GetSupportedSuites(message); +} +//------------------------------------------------------------------------------ +void BControl::AllAttached() +{ + BView::AllAttached(); +} +//------------------------------------------------------------------------------ +void BControl::AllDetached() +{ + BView::AllDetached(); +} +//------------------------------------------------------------------------------ +status_t BControl::Perform(perform_code d, void *arg) +{ + return B_ERROR; +} +//------------------------------------------------------------------------------ +bool BControl::IsFocusChanging() const +{ + return fFocusChanging; +} +//------------------------------------------------------------------------------ +bool BControl::IsTracking() const +{ + return fTracking; +} +//------------------------------------------------------------------------------ +void BControl::SetTracking(bool state) +{ + fTracking = state; +} +//------------------------------------------------------------------------------ +void BControl::SetValueNoUpdate(int32 value) +{ + fValue = value; +} + +//------------------------------------------------------------------------------ +void BControl::_ReservedControl1() {} +void BControl::_ReservedControl2() {} +void BControl::_ReservedControl3() {} +void BControl::_ReservedControl4() {} +//------------------------------------------------------------------------------ +BControl &BControl::operator=(const BControl &) +{ + return *this; +} +//------------------------------------------------------------------------------ +void BControl::InitData(BMessage *data) +{ + +} +//------------------------------------------------------------------------------ + +/* + * $Log $ + * + * $Id $ + * + */ diff --git a/src/kits/interface/RadioButton.cpp b/src/kits/interface/RadioButton.cpp index d7e06956e1..8f07d3c0e0 100644 --- a/src/kits/interface/RadioButton.cpp +++ b/src/kits/interface/RadioButton.cpp @@ -1,404 +1,410 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: RadioButton.cpp -// Author: Marc Flerackers (mflerackers@androme.be) -// Description: BRadioButton represents a single on/off button. All -// sibling BRadioButton objects comprise a single -// "multiple choice" control. -//------------------------------------------------------------------------------ - -// Standard Includes ----------------------------------------------------------- - -// System Includes ------------------------------------------------------------- -#include -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - -//------------------------------------------------------------------------------ -BRadioButton::BRadioButton(BRect frame, const char *name, const char *label, - BMessage *message, uint32 resizMask, uint32 flags) - : BControl(frame, name, label, message, resizMask, flags), - fOutlined(false) -{ - if (Bounds().Height() < 18.0f) - ResizeTo(Bounds().Width(), 18.0f); -} -//------------------------------------------------------------------------------ -BRadioButton::BRadioButton(BMessage *archive) - : BControl(archive), - fOutlined(false) -{ -} -//------------------------------------------------------------------------------ -BRadioButton::~BRadioButton() -{ -} -//------------------------------------------------------------------------------ -BArchivable *BRadioButton::Instantiate(BMessage *archive) -{ - if (validate_instantiation(archive, "BRadioButton")) - return new BRadioButton(archive); - else - return NULL; -} -//------------------------------------------------------------------------------ -status_t BRadioButton::Archive(BMessage *archive, bool deep) const -{ - return BControl::Archive(archive, deep); -} -//------------------------------------------------------------------------------ -void BRadioButton::Draw(BRect updateRect) -{ - // Placeholder until sBitmaps is filled in - rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), - lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), - lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), - darken1 = tint_color(no_tint, B_DARKEN_1_TINT), - darken2 = tint_color(no_tint, B_DARKEN_2_TINT), - darken3 = tint_color(no_tint, B_DARKEN_3_TINT), - darken4 = tint_color(no_tint, B_DARKEN_4_TINT), - darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); - - BRect rect(1.0, 3.0, 13.0, 15.0); - - if (IsEnabled()) - { - // Dot - if (Value() == B_CONTROL_ON) - { - rgb_color kb_color = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - - SetHighColor(tint_color(kb_color, B_DARKEN_3_TINT)); - FillEllipse(rect); - SetHighColor(kb_color); - FillEllipse(BRect(rect.left + 3, rect.top + 3, rect.right - 4, rect.bottom - 4)); - SetHighColor(tint_color(kb_color, B_DARKEN_3_TINT)); - StrokeLine(BPoint(rect.right - 5, rect.bottom - 4), - BPoint(rect.right - 4, rect.bottom - 5)); - SetHighColor(tint_color(kb_color, B_LIGHTEN_MAX_TINT)); - StrokeLine(BPoint(rect.left + 4, rect.top + 5), - BPoint(rect.left + 5, rect.top + 4)); - - } - else - { - SetHighColor(lightenmax); - FillEllipse(rect); - } - - // Outer circle - if (fOutlined) - { - SetHighColor(darken3); - StrokeEllipse(rect); - } - else - { - SetHighColor(darken1); - StrokeArc(rect, 45.0f, 180.0f); - SetHighColor(lightenmax); - StrokeArc(rect, 45.0f, -180.0f); - } - - rect.InsetBy(1, 1); - - // Inner circle - SetHighColor(darken3); - StrokeArc(rect, 45.0f, 180.0f); - StrokeLine(BPoint(rect.left + 1, rect.top + 1), - BPoint(rect.left + 1, rect.top + 1)); - SetHighColor(no_tint); - StrokeArc(rect, 45.0f, -180.0f); - StrokeLine(BPoint(rect.left + 1, rect.bottom - 1), - BPoint(rect.left + 1, rect.bottom - 1)); - StrokeLine(BPoint(rect.right - 1, rect.bottom - 1), - BPoint(rect.right - 1, rect.bottom - 1)); - StrokeLine(BPoint(rect.right - 1, rect.top + 1), - BPoint(rect.right - 1, rect.top + 1)); - - // Label - BFont font; - GetFont(&font); - font_height fh; - font.GetHeight(&fh); - - SetHighColor(darkenmax); - DrawString(Label(), BPoint(20.0f, 8.0f + (float)ceil(fh.ascent / 2.0f))); - - // Focus - if (IsFocus()) - { - float h = 8.0f + (float)ceil(fh.ascent / 2.0f) + 2.0f; - - SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); - StrokeLine(BPoint(20.0f, h), BPoint(20.0f + StringWidth(Label()), h)); - } - } - else - { - // Dot - if (Value() == B_CONTROL_ON) - { - rgb_color kb_color = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - - SetHighColor(tint_color(kb_color, B_LIGHTEN_2_TINT)); - FillEllipse(rect); - SetHighColor(tint_color(kb_color, B_LIGHTEN_MAX_TINT)); - StrokeLine(BPoint(rect.left + 4, rect.top + 5), - BPoint(rect.left + 5, rect.top + 4)); - SetHighColor(tint_color(kb_color, B_DARKEN_3_TINT)); - StrokeArc(BRect(rect.left + 2, rect.top + 2, rect.right - 2, rect.bottom - 2), - 45.0f, -180.0f); - } - else - { - SetHighColor(lighten1); - FillEllipse(rect); - } - - // Outer circle - SetHighColor(no_tint); - StrokeArc(rect, 45.0f, 180.0f); - SetHighColor(lighten1); - StrokeArc(rect, 45.0f, -180.0f); - - rect.InsetBy(1, 1); - - // Inner circle - SetHighColor(darken2); - StrokeArc(rect, 45.0f, 180.0f); - StrokeLine(BPoint(rect.left + 1, rect.top + 1), - BPoint(rect.left + 1, rect.top + 1)); - SetHighColor(no_tint); - StrokeArc(rect, 45.0f, -180.0f); - StrokeLine(BPoint(rect.left + 1, rect.bottom - 1), - BPoint(rect.left + 1, rect.bottom - 1)); - StrokeLine(BPoint(rect.right - 1, rect.bottom - 1), - BPoint(rect.right - 1, rect.bottom - 1)); - StrokeLine(BPoint(rect.right - 1, rect.top + 1), - BPoint(rect.right - 1, rect.top + 1)); - - // Label - BFont font; - GetFont(&font); - font_height fh; - font.GetHeight(&fh); - - SetHighColor(tint_color(no_tint, B_DISABLED_LABEL_TINT)); - DrawString(Label(), BPoint(20.0f, 8.0f + (float)ceil(fh.ascent / 2.0f))); - } -} -//------------------------------------------------------------------------------ -void BRadioButton::MouseDown(BPoint point) -{ - if (!IsEnabled()) - { - BControl::MouseDown(point); - return; - } - - SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | - B_SUSPEND_VIEW_FOCUS); - - SetTracking(true); - fOutlined = true; - Invalidate(); -} -//------------------------------------------------------------------------------ -void BRadioButton::AttachedToWindow() -{ - BControl::AttachedToWindow(); -} -//------------------------------------------------------------------------------ -void BRadioButton::KeyDown(const char *bytes, int32 numBytes) -{ - BControl::KeyDown(bytes, numBytes); -} -//------------------------------------------------------------------------------ -void BRadioButton::SetValue(int32 value) -{ - if (BControl::Value() == value) - return; - - if (!IsTracking() && value == B_CONTROL_ON) - { - BView *sibling; - - for (sibling = PreviousSibling(); sibling != NULL; - sibling = sibling->PreviousSibling()) - { - BRadioButton* radio = dynamic_cast(sibling); - - if (radio != NULL) - radio->BControl::SetValue(B_CONTROL_OFF); - } - - for (sibling = NextSibling(); sibling != NULL; - sibling = sibling->NextSibling()) - { - BRadioButton* radio = dynamic_cast(sibling); - - if (radio != NULL) - radio->BControl::SetValue(B_CONTROL_OFF); - } - } - - BControl::SetValue(value); -} -//------------------------------------------------------------------------------ -void BRadioButton::GetPreferredSize(float *width, float *height) -{ - font_height fh; - GetFontHeight(&fh); - - *height = (float)ceil(fh.ascent + fh.descent + fh.leading) + 6.0f; - *width = 22.0f + (float)ceil(StringWidth(Label())); -} -//------------------------------------------------------------------------------ -void BRadioButton::ResizeToPreferred() -{ - float width, height; - GetPreferredSize(&width, &height); - BControl::ResizeTo(width, height); -} -//------------------------------------------------------------------------------ -status_t BRadioButton::Invoke(BMessage *message) -{ - return BControl::Invoke(message); -} -//------------------------------------------------------------------------------ -void BRadioButton::MessageReceived(BMessage *message) -{ - BControl::MessageReceived(message); -} -//------------------------------------------------------------------------------ -void BRadioButton::WindowActivated(bool active) -{ - BControl::WindowActivated(active); -} -//------------------------------------------------------------------------------ -void BRadioButton::MouseUp(BPoint point) -{ - if (IsEnabled() && IsTracking()) - { - fOutlined = false; - SetTracking(false); - - if (Bounds().Contains(point)) - { - SetValue(B_CONTROL_ON); - Invoke(); - } - } - else - { - BControl::MouseUp(point); - return; - } - - Invalidate(); -} -//------------------------------------------------------------------------------ -void BRadioButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - if (IsEnabled() && IsTracking()) - { - if (transit == B_EXITED_VIEW) - fOutlined = false; - else if (transit == B_ENTERED_VIEW) - fOutlined = true; - - Invalidate(); - } - else - BView::MouseMoved(point, transit, message); -} -//------------------------------------------------------------------------------ -void BRadioButton::DetachedFromWindow() -{ - BControl::DetachedFromWindow(); -} -//------------------------------------------------------------------------------ -void BRadioButton::FrameMoved(BPoint newLocation) -{ - BControl::FrameMoved(newLocation); -} -//------------------------------------------------------------------------------ -void BRadioButton::FrameResized(float width, float height) -{ - BControl::FrameResized(width, height); -} -//------------------------------------------------------------------------------ -BHandler *BRadioButton::ResolveSpecifier(BMessage *message, int32 index, - BMessage *specifier, int32 what, - const char *property) -{ - return ResolveSpecifier(message, index, specifier, what, property); -} -//------------------------------------------------------------------------------ -void BRadioButton::MakeFocus(bool focused) -{ - BControl::MakeFocus(); -} -//------------------------------------------------------------------------------ -void BRadioButton::AllAttached() -{ - BControl::AllAttached(); -} -//------------------------------------------------------------------------------ -void BRadioButton::AllDetached() -{ - BControl::AllDetached(); -} -//------------------------------------------------------------------------------ -status_t BRadioButton::GetSupportedSuites(BMessage *message) -{ - return GetSupportedSuites(message); -} -//------------------------------------------------------------------------------ -status_t BRadioButton::Perform(perform_code d, void *arg) -{ - return B_ERROR; -} -//------------------------------------------------------------------------------ -void BRadioButton::_ReservedRadioButton1() {} -void BRadioButton::_ReservedRadioButton2() {} -//------------------------------------------------------------------------------ -BRadioButton &BRadioButton::operator=(const BRadioButton &) -{ - return *this; -} -//------------------------------------------------------------------------------ - -/* - * $Log $ - * - * $Id $ - * - */ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: RadioButton.cpp +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: BRadioButton represents a single on/off button. All +// sibling BRadioButton objects comprise a single +// "multiple choice" control. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +BRadioButton::BRadioButton(BRect frame, const char *name, const char *label, + BMessage *message, uint32 resizMask, uint32 flags) + : BControl(frame, name, label, message, resizMask, flags), + fOutlined(false) +{ + if (Bounds().Height() < 18.0f) + ResizeTo(Bounds().Width(), 18.0f); +} +//------------------------------------------------------------------------------ +BRadioButton::BRadioButton(BMessage *archive) + : BControl(archive), + fOutlined(false) +{ +} +//------------------------------------------------------------------------------ +BRadioButton::~BRadioButton() +{ +} +//------------------------------------------------------------------------------ +BArchivable *BRadioButton::Instantiate(BMessage *archive) +{ + if (validate_instantiation(archive, "BRadioButton")) + return new BRadioButton(archive); + else + return NULL; +} +//------------------------------------------------------------------------------ +status_t BRadioButton::Archive(BMessage *archive, bool deep) const +{ + return BControl::Archive(archive, deep); +} +//------------------------------------------------------------------------------ +void BRadioButton::Draw(BRect updateRect) +{ + font_height fh; + GetFontHeight(&fh); + + // If the focus is changing, just redraw the focus indicator + if (IsFocusChanging()) + { + float h = 8.0f + (float)ceil(fh.ascent / 2.0f) + 2.0f; + + if (IsFocus()) + SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); + else + SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + StrokeLine(BPoint(20.0f, h), BPoint(20.0f + StringWidth(Label()), h)); + + return; + } + + // Placeholder until sBitmaps is filled in + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), + lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), + lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), + darken1 = tint_color(no_tint, B_DARKEN_1_TINT), + darken2 = tint_color(no_tint, B_DARKEN_2_TINT), + darken3 = tint_color(no_tint, B_DARKEN_3_TINT), + darken4 = tint_color(no_tint, B_DARKEN_4_TINT), + darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); + + BRect rect(1.0, 3.0, 13.0, 15.0); + + if (IsEnabled()) + { + // Dot + if (Value() == B_CONTROL_ON) + { + rgb_color kb_color = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + SetHighColor(tint_color(kb_color, B_DARKEN_3_TINT)); + FillEllipse(rect); + SetHighColor(kb_color); + FillEllipse(BRect(rect.left + 3, rect.top + 3, rect.right - 4, rect.bottom - 4)); + SetHighColor(tint_color(kb_color, B_DARKEN_3_TINT)); + StrokeLine(BPoint(rect.right - 5, rect.bottom - 4), + BPoint(rect.right - 4, rect.bottom - 5)); + SetHighColor(tint_color(kb_color, B_LIGHTEN_MAX_TINT)); + StrokeLine(BPoint(rect.left + 4, rect.top + 5), + BPoint(rect.left + 5, rect.top + 4)); + + } + else + { + SetHighColor(lightenmax); + FillEllipse(rect); + } + + // Outer circle + if (fOutlined) + { + SetHighColor(darken3); + StrokeEllipse(rect); + } + else + { + SetHighColor(darken1); + StrokeArc(rect, 45.0f, 180.0f); + SetHighColor(lightenmax); + StrokeArc(rect, 45.0f, -180.0f); + } + + rect.InsetBy(1, 1); + + // Inner circle + SetHighColor(darken3); + StrokeArc(rect, 45.0f, 180.0f); + StrokeLine(BPoint(rect.left + 1, rect.top + 1), + BPoint(rect.left + 1, rect.top + 1)); + SetHighColor(no_tint); + StrokeArc(rect, 45.0f, -180.0f); + StrokeLine(BPoint(rect.left + 1, rect.bottom - 1), + BPoint(rect.left + 1, rect.bottom - 1)); + StrokeLine(BPoint(rect.right - 1, rect.bottom - 1), + BPoint(rect.right - 1, rect.bottom - 1)); + StrokeLine(BPoint(rect.right - 1, rect.top + 1), + BPoint(rect.right - 1, rect.top + 1)); + + // Label + SetHighColor(darkenmax); + DrawString(Label(), BPoint(20.0f, 8.0f + (float)ceil(fh.ascent / 2.0f))); + + // Focus + if (IsFocus()) + { + float h = 8.0f + (float)ceil(fh.ascent / 2.0f) + 2.0f; + + SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); + StrokeLine(BPoint(20.0f, h), BPoint(20.0f + StringWidth(Label()), h)); + } + } + else + { + // Dot + if (Value() == B_CONTROL_ON) + { + rgb_color kb_color = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + SetHighColor(tint_color(kb_color, B_LIGHTEN_2_TINT)); + FillEllipse(rect); + SetHighColor(tint_color(kb_color, B_LIGHTEN_MAX_TINT)); + StrokeLine(BPoint(rect.left + 4, rect.top + 5), + BPoint(rect.left + 5, rect.top + 4)); + SetHighColor(tint_color(kb_color, B_DARKEN_3_TINT)); + StrokeArc(BRect(rect.left + 2, rect.top + 2, rect.right - 2, rect.bottom - 2), + 45.0f, -180.0f); + } + else + { + SetHighColor(lighten1); + FillEllipse(rect); + } + + // Outer circle + SetHighColor(no_tint); + StrokeArc(rect, 45.0f, 180.0f); + SetHighColor(lighten1); + StrokeArc(rect, 45.0f, -180.0f); + + rect.InsetBy(1, 1); + + // Inner circle + SetHighColor(darken2); + StrokeArc(rect, 45.0f, 180.0f); + StrokeLine(BPoint(rect.left + 1, rect.top + 1), + BPoint(rect.left + 1, rect.top + 1)); + SetHighColor(no_tint); + StrokeArc(rect, 45.0f, -180.0f); + StrokeLine(BPoint(rect.left + 1, rect.bottom - 1), + BPoint(rect.left + 1, rect.bottom - 1)); + StrokeLine(BPoint(rect.right - 1, rect.bottom - 1), + BPoint(rect.right - 1, rect.bottom - 1)); + StrokeLine(BPoint(rect.right - 1, rect.top + 1), + BPoint(rect.right - 1, rect.top + 1)); + + // Label + SetHighColor(tint_color(no_tint, B_DISABLED_LABEL_TINT)); + DrawString(Label(), BPoint(20.0f, 8.0f + (float)ceil(fh.ascent / 2.0f))); + } +} +//------------------------------------------------------------------------------ +void BRadioButton::MouseDown(BPoint point) +{ + if (!IsEnabled()) + { + BControl::MouseDown(point); + return; + } + + SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | + B_SUSPEND_VIEW_FOCUS); + + SetTracking(true); + fOutlined = true; + Invalidate(); +} +//------------------------------------------------------------------------------ +void BRadioButton::AttachedToWindow() +{ + BControl::AttachedToWindow(); +} +//------------------------------------------------------------------------------ +void BRadioButton::KeyDown(const char *bytes, int32 numBytes) +{ + BControl::KeyDown(bytes, numBytes); +} +//------------------------------------------------------------------------------ +void BRadioButton::SetValue(int32 value) +{ + if (BControl::Value() == value) + return; + + if (!IsTracking() && value == B_CONTROL_ON) + { + BView *sibling; + + for (sibling = PreviousSibling(); sibling != NULL; + sibling = sibling->PreviousSibling()) + { + BRadioButton* radio = dynamic_cast(sibling); + + if (radio != NULL) + radio->BControl::SetValue(B_CONTROL_OFF); + } + + for (sibling = NextSibling(); sibling != NULL; + sibling = sibling->NextSibling()) + { + BRadioButton* radio = dynamic_cast(sibling); + + if (radio != NULL) + radio->BControl::SetValue(B_CONTROL_OFF); + } + } + + BControl::SetValue(value); +} +//------------------------------------------------------------------------------ +void BRadioButton::GetPreferredSize(float *width, float *height) +{ + font_height fh; + GetFontHeight(&fh); + + *height = (float)ceil(fh.ascent + fh.descent + fh.leading) + 6.0f; + *width = 22.0f + (float)ceil(StringWidth(Label())); +} +//------------------------------------------------------------------------------ +void BRadioButton::ResizeToPreferred() +{ + BControl::ResizeToPreferred(); +} +//------------------------------------------------------------------------------ +status_t BRadioButton::Invoke(BMessage *message) +{ + return BControl::Invoke(message); +} +//------------------------------------------------------------------------------ +void BRadioButton::MessageReceived(BMessage *message) +{ + BControl::MessageReceived(message); +} +//------------------------------------------------------------------------------ +void BRadioButton::WindowActivated(bool active) +{ + BControl::WindowActivated(active); +} +//------------------------------------------------------------------------------ +void BRadioButton::MouseUp(BPoint point) +{ + if (IsEnabled() && IsTracking()) + { + fOutlined = false; + SetTracking(false); + + if (Bounds().Contains(point)) + { + SetValue(B_CONTROL_ON); + Invoke(); + } + } + else + { + BControl::MouseUp(point); + return; + } + + Invalidate(); +} +//------------------------------------------------------------------------------ +void BRadioButton::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +{ + if (IsEnabled() && IsTracking()) + { + if (transit == B_EXITED_VIEW) + fOutlined = false; + else if (transit == B_ENTERED_VIEW) + fOutlined = true; + + Invalidate(); + } + else + BView::MouseMoved(point, transit, message); +} +//------------------------------------------------------------------------------ +void BRadioButton::DetachedFromWindow() +{ + BControl::DetachedFromWindow(); +} +//------------------------------------------------------------------------------ +void BRadioButton::FrameMoved(BPoint newLocation) +{ + BControl::FrameMoved(newLocation); +} +//------------------------------------------------------------------------------ +void BRadioButton::FrameResized(float width, float height) +{ + BControl::FrameResized(width, height); +} +//------------------------------------------------------------------------------ +BHandler *BRadioButton::ResolveSpecifier(BMessage *message, int32 index, + BMessage *specifier, int32 what, + const char *property) +{ + return ResolveSpecifier(message, index, specifier, what, property); +} +//------------------------------------------------------------------------------ +void BRadioButton::MakeFocus(bool focused) +{ + BControl::MakeFocus(focused); +} +//------------------------------------------------------------------------------ +void BRadioButton::AllAttached() +{ + BControl::AllAttached(); +} +//------------------------------------------------------------------------------ +void BRadioButton::AllDetached() +{ + BControl::AllDetached(); +} +//------------------------------------------------------------------------------ +status_t BRadioButton::GetSupportedSuites(BMessage *message) +{ + return GetSupportedSuites(message); +} +//------------------------------------------------------------------------------ +status_t BRadioButton::Perform(perform_code d, void *arg) +{ + return B_ERROR; +} +//------------------------------------------------------------------------------ +void BRadioButton::_ReservedRadioButton1() {} +void BRadioButton::_ReservedRadioButton2() {} +//------------------------------------------------------------------------------ +BRadioButton &BRadioButton::operator=(const BRadioButton &) +{ + return *this; +} +//------------------------------------------------------------------------------ + +/* + * $Log $ + * + * $Id $ + * + */ diff --git a/src/kits/interface/Slider.cpp b/src/kits/interface/Slider.cpp index 4f8cb10fb7..442debaa42 100644 --- a/src/kits/interface/Slider.cpp +++ b/src/kits/interface/Slider.cpp @@ -1,1155 +1,1216 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Slider.h -// Author: Marc Flerackers (mflerackers@androme.be) -// Description: BSlider creates and displays a sliding thumb control. -//------------------------------------------------------------------------------ - -// Standard Includes ----------------------------------------------------------- -#include -#include - -// System Includes ------------------------------------------------------------- -#include -#include -#include -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - -//------------------------------------------------------------------------------ -BSlider::BSlider(BRect frame, const char *name, const char *label, BMessage *message, - int32 minValue, int32 maxValue, thumb_style thumbType, - uint32 resizingMode, uint32 flags) - : BControl(frame, name, label, message, resizingMode, flags), - fModificationMessage(NULL), - fSnoozeAmount(20000), - fUseFillColor(false), - fMinLimitStr(NULL), - fMaxLimitStr(NULL), - fMinValue(minValue), - fMaxValue(maxValue), - fKeyIncrementValue(1), - fHashMarkCount(0), - fHashMarks(B_HASH_MARKS_NONE), - fOffScreenBits(NULL), - fOffScreenView(NULL), - fStyle(thumbType), - fOrientation(B_HORIZONTAL), - fBarThickness(6.0f) -{ - fBarColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_4_TINT); - fFillColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_MAX_TINT); -} -//------------------------------------------------------------------------------ -BSlider::BSlider(BRect frame, const char *name, const char *label, BMessage *message, - int32 minValue, int32 maxValue, orientation posture, - thumb_style thumbType, uint32 resizingMode, uint32 flags) - : BControl(frame, name, label, message, resizingMode, flags), - fModificationMessage(NULL), - fSnoozeAmount(20000), - fUseFillColor(false), - fMinLimitStr(NULL), - fMaxLimitStr(NULL), - fMinValue(minValue), - fMaxValue(maxValue), - fKeyIncrementValue(1), - fHashMarkCount(0), - fHashMarks(B_HASH_MARKS_NONE), - fOffScreenBits(NULL), - fOffScreenView(NULL), - fStyle(thumbType), - fOrientation(posture), - fBarThickness(6.0f) -{ - fBarColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_4_TINT); - fFillColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_MAX_TINT); -} -//------------------------------------------------------------------------------ -BSlider::~BSlider() -{ - if (fMinLimitStr) - free(fMinLimitStr); - - if (fMaxLimitStr) - free(fMaxLimitStr); -} -//------------------------------------------------------------------------------ -BSlider::BSlider(BMessage *archive) - : BControl (archive) -{ - BMessage modMessage; - int16 anInt16; - int32 anInt32; - const char *aString1 = NULL, *aString2 = NULL; - const rgb_color *aColorPtr; - - if (archive->FindMessage("_mod_msg", &modMessage)) - SetModificationMessage(new BMessage(modMessage)); - - if (archive->FindInt32("_sdelay", &anInt32)) - SetSnoozeAmount(anInt32); - - if(archive->FindData("_bcolor", B_INT32_TYPE, (const void**)&aColorPtr, NULL)) - SetBarColor(*aColorPtr); - - if(archive->FindData("_fcolor", B_INT32_TYPE, (const void**)&aColorPtr, NULL)) - UseFillColor(true, aColorPtr); - - if (archive->FindString("_minlbl", &aString1) || - archive->FindString("_maxlbl", &aString2)) - SetLimitLabels(aString1, aString2); - - archive->FindInt32("_min", &fMinValue); - archive->FindInt32("_max", &fMaxValue); - - archive->FindInt32("_incrementvalue", &fKeyIncrementValue); - - archive->FindInt32("_hashcount", &fHashMarkCount); - - if(archive->FindInt16("_hashloc", &anInt16)) - SetHashMarks((hash_mark_location)anInt16); - - if(archive->FindInt32("_sstyle", &anInt32)) - SetStyle((thumb_style)anInt32); -} -//------------------------------------------------------------------------------ -BArchivable *BSlider::Instantiate(BMessage *archive) -{ - if (validate_instantiation(archive, "BSlider")) - return new BSlider(archive); - else - return NULL; -} -//------------------------------------------------------------------------------ -status_t BSlider::Archive(BMessage *archive, bool deep) const -{ - status_t err = BControl::Archive(archive, deep); - - if (err != B_OK) - return err; - - if (fModificationMessage) - err = archive->AddMessage("_mod_msg", fModificationMessage); - - if (err != B_OK) - return err; - - if (fSnoozeAmount != 20000) - err = archive->AddInt32("_sdelay", fSnoozeAmount); - - if (err != B_OK) - return err; - - err = archive->AddData("_bcolor", B_INT32_TYPE, &fBarColor, sizeof(int32)); - - if (err != B_OK) - return err; - - err = archive->AddData("_fcolor", B_INT32_TYPE, &fFillColor, sizeof(int32)); - - if (err != B_OK) - return err; - - if (fMinLimitStr) - err = archive->AddString("_minlbl", fMinLimitStr); - - if (err != B_OK) - return err; - - if (fMaxLimitStr) - err = archive->AddString("_maxlbl", fMaxLimitStr); - - if (err != B_OK) - return err; - - err = archive->AddInt32("_min", fMinValue); - - if (err != B_OK) - return err; - - err = archive->AddInt32("_max", fMaxValue); - - if (err != B_OK) - return err; - - if (fKeyIncrementValue != 1) - err = archive->AddInt32("_incrementvalue", fKeyIncrementValue); - - if (err != B_OK) - return err; - - if (fHashMarkCount != 0) - err = archive->AddInt32("_hashcount", fHashMarkCount); - - if (err != B_OK) - return err; - - if (fHashMarks != B_HASH_MARKS_NONE) - err = archive->AddInt16("_hashloc", fHashMarks); - - if (err != B_OK) - return err; - - if (fStyle != B_BLOCK_THUMB) - err = archive->AddInt32("_sstyle", fStyle); - - return err; -} -//------------------------------------------------------------------------------ -status_t BSlider::Perform(perform_code d, void *arg) -{ - return B_ERROR; -} -//------------------------------------------------------------------------------ -void BSlider::WindowActivated(bool state) -{ - -} -//------------------------------------------------------------------------------ -void BSlider::AttachedToWindow() -{ - BControl::AttachedToWindow(); - - if (Parent()) - SetViewColor(Parent()->ViewColor()); - - ResizeToPreferred(); - - fLocation.Set(9.0f, 0.0f); - - // TODO: Allocate fOffScreenBits and fOffScreenView -} -//------------------------------------------------------------------------------ -void BSlider::AllAttached() -{ -} -//------------------------------------------------------------------------------ -void BSlider::AllDetached() -{ -} -//------------------------------------------------------------------------------ -void BSlider::DetachedFromWindow() -{ -} -//------------------------------------------------------------------------------ -void BSlider::MessageReceived(BMessage *msg) -{ -} -//------------------------------------------------------------------------------ -void BSlider::FrameMoved(BPoint new_position) -{ -} -//------------------------------------------------------------------------------ -void BSlider::FrameResized(float w,float h) -{ -} -//------------------------------------------------------------------------------ -void BSlider::KeyDown(const char *bytes, int32 numBytes) -{ - if (!IsEnabled()) - return; - - int32 value = Value(); - - if (bytes[0] == B_LEFT_ARROW || bytes[0] == B_DOWN_ARROW) - SetValue ( value - 1 ); - else if (bytes[0] == B_RIGHT_ARROW || bytes[0] == B_UP_ARROW) - SetValue(value + 1); - else - BControl::KeyDown(bytes, numBytes); - - if (Value() != value) - Invoke(); -} -//------------------------------------------------------------------------------ -void BSlider::MouseDown(BPoint point) -{ - SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS); - - SetValue(ValueForPoint(point)); - SetTracking(true); -} -//------------------------------------------------------------------------------ -void BSlider::MouseUp(BPoint point) -{ - Invoke(); - - SetTracking(false); -} -//------------------------------------------------------------------------------ -void BSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - if (IsTracking()) - { - SetValue(ValueForPoint(point)); - - if (fModificationMessage) - Invoke(fModificationMessage); - } -} -//------------------------------------------------------------------------------ -void BSlider::Pulse() -{ - BControl::Pulse(); -} -//------------------------------------------------------------------------------ -void BSlider::SetLabel(const char *label) -{ - BControl::SetLabel(label); -} -//------------------------------------------------------------------------------ -void BSlider::SetLimitLabels(const char *minLabel, const char *maxLabel) -{ - if (minLabel) - { - if (fMinLimitStr) - free(fMinLimitStr); - fMinLimitStr = strdup(minLabel); - } - - if (maxLabel) - { - if (fMaxLimitStr) - free(fMaxLimitStr); - fMaxLimitStr = strdup(maxLabel); - } - - ResizeToPreferred(); - Invalidate(); -} -//------------------------------------------------------------------------------ -const char *BSlider::MinLimitLabel() const -{ - return fMinLimitStr; -} -//------------------------------------------------------------------------------ -const char *BSlider::MaxLimitLabel() const -{ - return fMaxLimitStr; -} -//------------------------------------------------------------------------------ -void BSlider::SetValue(int32 value) -{ - value = max_c(fMinValue, min_c(fMaxValue, value)); - BControl::SetValue(value); -} -//------------------------------------------------------------------------------ -int32 BSlider::ValueForPoint(BPoint location) const -{ - if (fOrientation == B_HORIZONTAL) - return (int32)((location.x - _MinPosition()) * (fMaxValue - fMinValue) / - (_MaxPosition() - _MinPosition())) + fMinValue; - else - return (int32)((location.y - _MinPosition()) * (fMaxValue - fMinValue) / - (_MaxPosition() - _MinPosition())) + fMinValue; -} -//------------------------------------------------------------------------------ -void BSlider::SetPosition(float position) -{ - if (position <= 0.0f) - BControl::SetValue(fMinValue); - else if (position >= 1.0f) - BControl::SetValue(fMaxValue); - else - BControl::SetValue((int32)(position *(fMaxValue - fMinValue) + fMinValue)); -} -//------------------------------------------------------------------------------ -float BSlider::Position() const -{ - return ((float)(BControl::Value() - fMinValue) / (float)(fMaxValue - fMinValue)); -} -//------------------------------------------------------------------------------ -void BSlider::SetEnabled(bool on) -{ - BControl::SetEnabled(on); -} -//------------------------------------------------------------------------------ -void BSlider::GetLimits(int32 *minimum, int32 *maximum) -{ - *minimum = fMinValue; - *maximum = fMaxValue; -} -//------------------------------------------------------------------------------ -void BSlider::Draw(BRect updateRect) -{ - DrawSlider(); -} -//------------------------------------------------------------------------------ -void BSlider::DrawSlider() -{ - // TODO: Draw into fOffScreenView and draw fOffScreenBits on the view - // Write drawing code for a vertical slider - - SetHighColor(ViewColor()); - FillRect(Bounds()); - - DrawBar(); - DrawHashMarks(); - DrawThumb(); - - if (IsFocus()) - DrawFocusMark(); - - DrawText(); -} -//------------------------------------------------------------------------------ -void BSlider::DrawBar() -{ - BRect frame = BarFrame(); - - if (fUseFillColor) - { - if (fOrientation == B_HORIZONTAL) - { - SetHighColor(fBarColor); - FillRect(BRect((float)floor(frame.left + 1 + Position() * (frame.Width() - 2)), - frame.top, frame.right, frame.bottom)); - - SetHighColor(fFillColor); - FillRect(BRect(frame.left, frame.top, - (float)floor(frame.left + 1 + Position() * (frame.Width() - 2)), - frame.bottom)); - } - else - { - SetHighColor(fBarColor); - FillRect(BRect(frame.left, frame.top, frame.right, - (float)floor(frame.bottom - 1 - Position() * (frame.Height() - 2)))); - - SetHighColor(fFillColor); - FillRect(BRect(frame.left, - (float)floor(frame.bottom - 1 - Position() * (frame.Height() - 2)), - frame.right, frame.bottom)); - - } - } - else - { - SetHighColor(fBarColor); - FillRect(frame); - } - - rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), - lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), - darken1 = tint_color(no_tint, B_DARKEN_1_TINT), - darken2 = tint_color(no_tint, B_DARKEN_2_TINT), - darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); - - SetHighColor(darken1); - StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.left + 1.0f, frame.top)); - StrokeLine(BPoint(frame.left, frame.bottom), BPoint(frame.left + 1.0f, frame.bottom)); - StrokeLine(BPoint(frame.right - 1.0f, frame.top), BPoint(frame.right, frame.top)); - - SetHighColor(darken2); - StrokeLine(BPoint(frame.left + 1.0f, frame.top), BPoint(frame.right - 1.0f, frame.top)); - StrokeLine(BPoint(frame.left, frame.bottom - 1.0f), BPoint(frame.left, frame.top + 1.0f)); - - SetHighColor(lightenmax); - StrokeLine(BPoint(frame.left + 1.0f, frame.bottom), BPoint(frame.right, frame.bottom)); - StrokeLine(BPoint(frame.right, frame.top + 1.0f)); - - frame.InsetBy(1.0f, 1.0f); - - SetHighColor(darkenmax); - StrokeLine(BPoint(frame.left, frame.bottom), BPoint(frame.left, frame.top)); - StrokeLine(BPoint(frame.right, frame.top)); -} -//------------------------------------------------------------------------------ -void BSlider::DrawHashMarks() -{ - BRect frame = HashMarksFrame(); - rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), - lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), - darken2 = tint_color(no_tint, B_DARKEN_2_TINT); - - float pos = _MinPosition(); - float factor = (_MaxPosition() - pos) / (fHashMarkCount - 1); - - if (fHashMarks & B_HASH_MARKS_TOP) - { - if (fOrientation == B_HORIZONTAL) - { - for (int32 i = 0; i < fHashMarkCount; i++) - { - SetHighColor(darken2); - StrokeLine(BPoint(pos, frame.top), - BPoint(pos, frame.top + 5)); - SetHighColor(lightenmax); - StrokeLine(BPoint(pos + 1, frame.top), - BPoint(pos + 1, frame.top + 5)); - - pos += factor; - } - } - else - { - for (int32 i = 0; i < fHashMarkCount; i++) - { - SetHighColor(darken2); - StrokeLine(BPoint(frame.left, pos), - BPoint(frame.left + 5, pos)); - SetHighColor(lightenmax); - StrokeLine(BPoint(frame.left, pos + 1), - BPoint(frame.left + 5, pos + 1)); - - pos += factor; - } - } - } - - pos = _MinPosition(); - - if (fHashMarks & B_HASH_MARKS_BOTTOM) - { - if (fOrientation == B_HORIZONTAL) - { - for (int32 i = 0; i < fHashMarkCount; i++) - { - SetHighColor(darken2); - StrokeLine(BPoint(pos, frame.bottom - 5), - BPoint(pos, frame.bottom)); - SetHighColor(lightenmax); - StrokeLine(BPoint(pos + 1, frame.bottom - 5), - BPoint(pos + 1, frame.bottom)); - - pos += factor; - } - } - else - { - for (int32 i = 0; i < fHashMarkCount; i++) - { - SetHighColor(darken2); - StrokeLine(BPoint(frame.right - 5, pos), - BPoint(frame.right, pos)); - SetHighColor(lightenmax); - StrokeLine(BPoint(frame.right - 5, pos + 1), - BPoint(frame.right, pos + 1)); - - pos += factor; - } - } - } -} -//------------------------------------------------------------------------------ -void BSlider::DrawThumb() -{ - if (fStyle == B_BLOCK_THUMB) - _DrawBlockThumb(); - else - _DrawTriangleThumb(); -} -//------------------------------------------------------------------------------ -void BSlider::DrawFocusMark() -{ - SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); - StrokeRect(Bounds()); -} -//------------------------------------------------------------------------------ -void BSlider::DrawText() -{ - BRect bounds(Bounds()); - SetHighColor(0, 0, 0); - - font_height fheight; - - GetFontHeight(&fheight); - - if (Orientation() == B_HORIZONTAL) - { - if (Label()) - DrawString(Label(), BPoint(2.0f, (float)ceil(fheight.ascent))); - - if (fMinLimitStr) - DrawString(fMinLimitStr, BPoint(2.0f, bounds.bottom - 4.0f)); - - if (fMaxLimitStr) - DrawString(fMaxLimitStr, BPoint(bounds.right - - StringWidth(fMaxLimitStr) - 2.0f, bounds.bottom - 4.0f)); - } - else - { - float ascent = (float)ceil(fheight.ascent); - - if (Label()) - DrawString(Label(), BPoint(bounds.Width() / 2.0f - - StringWidth(Label()) / 2.0f, ascent)); - - if (fMaxLimitStr) - DrawString(fMaxLimitStr, BPoint(bounds.Width() / 2.0f - - StringWidth(fMaxLimitStr) / 2.0f, ascent + - (Label() ? (float)ceil(ascent + fheight.descent + 2.0f) : 0.0f))); - - if (fMinLimitStr) - DrawString(fMinLimitStr, BPoint(bounds.Width() / 2.0f - - StringWidth(fMinLimitStr) / 2.0f, - bounds.bottom - 2.0f)); - } -} -//------------------------------------------------------------------------------ -char *BSlider::UpdateText() const -{ - return NULL; -} -//------------------------------------------------------------------------------ -BRect BSlider::BarFrame() const -{ - BRect frame = Bounds(); - font_height fheight; - - GetFontHeight(&fheight); - - float textHeight = (float)ceil(fheight.ascent + fheight.descent); - - if (fStyle == B_BLOCK_THUMB) - { - if (Orientation() == B_HORIZONTAL) - { - frame.left = 8.0f; - frame.top = 6.0f + (Label() ? textHeight + 4.0f : 0.0f); - frame.right -= 8.0f; - frame.bottom = frame.bottom - 6.0f - - (fMinLimitStr || fMaxLimitStr ? textHeight + 4.0f : 0.0f); - } - else - { - frame.left = frame.Width() / 2.0f - 3; - frame.top = 12.0f + (Label() ? textHeight : 0.0f) + - (fMaxLimitStr ? textHeight : 0.0f); - frame.right = frame.left + 6; - frame.bottom = frame.bottom - 8.0f - - (fMinLimitStr ? textHeight + 4 : 0.0f); - } - } - else - { - if (Orientation() == B_HORIZONTAL) - { - frame.left = 7.0f; - frame.top = 6.0f + (Label() ? textHeight + 4.0f : 0.0f); - frame.right -= 7.0f; - frame.bottom = frame.bottom - 6.0f - - (fMinLimitStr || fMaxLimitStr ? textHeight + 4.0f : 0.0f); - } - else - { - frame.left = frame.Width() / 2.0f - 3; - frame.top = 11.0f + (Label() ? textHeight : 0.0f) + - (fMaxLimitStr ? textHeight : 0.0f); - frame.right = frame.left + 6; - frame.bottom = frame.bottom - 7.0f - - (fMinLimitStr ? textHeight + 4 : 0.0f); - } - } - - return frame; -} -//------------------------------------------------------------------------------ -BRect BSlider::HashMarksFrame() const -{ - BRect frame(BarFrame()); - - if (fOrientation == B_HORIZONTAL) - { - frame.top -= 6.0f; - frame.bottom += 6.0f; - } - else - { - frame.left -= 6.0f; - frame.right += 6.0f; - } - - return frame; -} -//------------------------------------------------------------------------------ -BRect BSlider::ThumbFrame() const -{ - BRect frame = Bounds(); - font_height fheight; - - GetFontHeight(&fheight); - - float textHeight = (float)ceil(fheight.ascent + fheight.descent); - - if (fStyle == B_BLOCK_THUMB) - { - if (Orientation() == B_HORIZONTAL) - { - frame.left = (float)floor(Position() * (_MaxPosition() - _MinPosition()) + - _MinPosition()) - 8.0f; - frame.top = 2.0f + (Label() ? textHeight + 4.0f : 0.0f); - frame.right = frame.left + 17.0f; - frame.bottom = frame.bottom - 3.0f - - (MinLimitLabel() || MaxLimitLabel() ? textHeight + 4.0f : 0.0f); - } - else - { - frame.left = frame.Width() / 2.0f - 7; - frame.top = (float)floor(Position() * (_MaxPosition() - _MinPosition()) + - _MinPosition()) - 8.0f; - frame.right = frame.left + 13; - frame.bottom = frame.top + 17; - } - } - else - { - if (Orientation() == B_HORIZONTAL) - { - frame.left = (float)floor(Position() * (_MaxPosition() - _MinPosition()) + - _MinPosition()) - 6; - frame.top = 9.0f + (Label() ? textHeight + 4.0f : 0.0f); - frame.right = frame.left + 12.0f; - frame.bottom = frame.bottom - 3.0f - - (MinLimitLabel() || MaxLimitLabel() ? textHeight + 4.0f : 0.0f); - } - else - { - frame.left = frame.Width() / 2.0f - 6; - frame.top = (float)floor(Position() * (_MaxPosition() - _MinPosition())) + - _MinPosition() - 6.0f; - frame.right = frame.left + 7; - frame.bottom = frame.top + 12; - } - } - - return frame; -} -//------------------------------------------------------------------------------ -void BSlider::SetFlags(uint32 flags) -{ - // TODO: Check if we have to filter this - BControl::SetFlags(flags); -} -//------------------------------------------------------------------------------ -void BSlider::SetResizingMode(uint32 mode) -{ - // TODO: Check if we have to filter this - BControl::SetResizingMode(mode); -} -//------------------------------------------------------------------------------ -void BSlider::GetPreferredSize(float *width, float *height) -{ - font_height fheight; - - GetFontHeight(&fheight); - - if (Orientation() == B_HORIZONTAL) - { - *width = (Frame().Width() < 32.0f) ? 32.0f : Frame().Width(); - *height = 18.0f; - - if (Label()) - *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; - - if (MinLimitLabel() || MaxLimitLabel()) - *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; - } - else // B_VERTICAL - { - *width = (Frame().Width() < 18.0f) ? 18.0f : Frame().Width(); - *height = 32.0f; - - if (Label()) - *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; - - if (MaxLimitLabel()) - *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; - - if (MinLimitLabel()) - *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; - - if (Label() && (MaxLimitLabel())) - *height -= 4.0f; - - *height = (Frame().Height() < *height) ? *height : Frame().Height(); - } -} -//------------------------------------------------------------------------------ -void BSlider::ResizeToPreferred() -{ - BControl::ResizeToPreferred(); -} -//------------------------------------------------------------------------------ -status_t BSlider::Invoke(BMessage *msg) -{ - return BControl::Invoke(msg); -} -//------------------------------------------------------------------------------ -BHandler *BSlider::ResolveSpecifier(BMessage *message, int32 index, - BMessage *specifier, int32 command, - const char *property) -{ - return BControl::ResolveSpecifier(message, index, specifier, command, - property); -} -//------------------------------------------------------------------------------ -status_t BSlider::GetSupportedSuites(BMessage *message) -{ - BControl::GetSupportedSuites(message); - - message->AddString("suites", "suite/vnd.Be-slider"); - - return B_OK; -} -//------------------------------------------------------------------------------ -void BSlider::SetModificationMessage(BMessage *message) -{ - if (fModificationMessage) - delete fModificationMessage; - - fModificationMessage = message; -} -//------------------------------------------------------------------------------ -BMessage *BSlider::ModificationMessage() const -{ - return fModificationMessage; -} -//------------------------------------------------------------------------------ -void BSlider::SetSnoozeAmount(int32 snooze_time) -{ - fSnoozeAmount = snooze_time; -} -//------------------------------------------------------------------------------ -int32 BSlider::SnoozeAmount() const -{ - return fSnoozeAmount; -} -//------------------------------------------------------------------------------ -void BSlider::SetKeyIncrementValue(int32 increment_value) -{ - fKeyIncrementValue = increment_value; -} -//------------------------------------------------------------------------------ -int32 BSlider::KeyIncrementValue() const -{ - return fKeyIncrementValue; -} -//------------------------------------------------------------------------------ -void BSlider::SetHashMarkCount(int32 hash_mark_count) -{ - fHashMarkCount = hash_mark_count; - Invalidate(); -} -//------------------------------------------------------------------------------ -int32 BSlider::HashMarkCount() const -{ - return fHashMarkCount; -} -//------------------------------------------------------------------------------ -void BSlider::SetHashMarks(hash_mark_location where) -{ - fHashMarks = where; - Invalidate(); -} -//------------------------------------------------------------------------------ -hash_mark_location BSlider::HashMarks() const -{ - return fHashMarks; -} -//------------------------------------------------------------------------------ -void BSlider::SetStyle(thumb_style style) -{ - // TODO: Do the necessary to change the style - fStyle = style; -} -//------------------------------------------------------------------------------ -thumb_style BSlider::Style() const -{ - return fStyle; -} -//------------------------------------------------------------------------------ -void BSlider::SetBarColor(rgb_color bar_color) -{ - fBarColor = bar_color; -} -//------------------------------------------------------------------------------ -rgb_color BSlider::BarColor() const -{ - return fBarColor; -} -//------------------------------------------------------------------------------ -void BSlider::UseFillColor(bool use_fill, const rgb_color *bar_color) -{ - fUseFillColor = use_fill; - - if (bar_color) - fFillColor = *bar_color; -} -//------------------------------------------------------------------------------ -bool BSlider::FillColor(rgb_color *bar_color) const -{ - *bar_color = fFillColor; - - return fUseFillColor; -} -//------------------------------------------------------------------------------ -BView *BSlider::OffscreenView() const -{ - // TODO: return fOffscreenView - return (BView*)this; -} -//------------------------------------------------------------------------------ -orientation BSlider::Orientation() const -{ - return fOrientation; -} -//------------------------------------------------------------------------------ -void BSlider::SetOrientation(orientation posture) -{ - // TODO: Do the necessary to change the orientation - fOrientation = posture; -} -//------------------------------------------------------------------------------ -float BSlider::BarThickness() const -{ - return fBarThickness; -} -//------------------------------------------------------------------------------ -void BSlider::SetBarThickness(float thickness) -{ - // TODO: Resize the control - fBarThickness = thickness; -} -//------------------------------------------------------------------------------ -void BSlider::SetFont(const BFont *font, uint32 properties) -{ - // TODO: Resize the control - BControl::SetFont(font, properties); -} -//------------------------------------------------------------------------------ -void BSlider::_DrawBlockThumb() -{ - BRect frame = ThumbFrame(); - - rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), - lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT), - darken2 = tint_color(no_tint, B_DARKEN_2_TINT), - darken3 = tint_color(no_tint, B_DARKEN_3_TINT), - darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); - - // Outline - SetHighColor(darken3); - StrokeLine(BPoint(frame.left, frame.bottom - 2.0f), - BPoint(frame.left, frame.top + 1.0f)); - StrokeLine(BPoint(frame.left + 1.0f, frame.top), - BPoint(frame.right - 2.0f, frame.top)); - StrokeLine(BPoint(frame.right, frame.top + 2.0f), - BPoint(frame.right, frame.bottom - 1.0f)); - StrokeLine(BPoint(frame.left + 2.0f, frame.bottom), - BPoint(frame.right - 1.0f, frame.bottom)); - - // First bevel - frame.InsetBy(1.0f, 1.0f); - - SetHighColor(lighten2); - FillRect(frame); - - SetHighColor(darkenmax); - StrokeLine(BPoint(frame.left, frame.bottom), - BPoint(frame.right - 1.0f, frame.bottom)); - StrokeLine(BPoint(frame.right, frame.bottom - 1), - BPoint(frame.right, frame.top)); - - frame.InsetBy(1.0f, 1.0f); - - // Second bevel and center dots - SetHighColor(darken2); - StrokeLine(BPoint(frame.left, frame.bottom), - BPoint(frame.right, frame.bottom)); - StrokeLine(BPoint(frame.right, frame.top)); - - if (Orientation() == B_HORIZONTAL) - { - StrokeLine(BPoint(frame.left + 6.0f, frame.top + 2.0f), - BPoint(frame.left + 6.0f, frame.top + 2.0f)); - StrokeLine(BPoint(frame.left + 6.0f, frame.top + 4.0f), - BPoint(frame.left + 6.0f, frame.top + 4.0f)); - StrokeLine(BPoint(frame.left + 6.0f, frame.top + 6.0f), - BPoint(frame.left + 6.0f, frame.top + 6.0f)); - } - else - { - StrokeLine(BPoint(frame.left + 2.0f, frame.top + 6.0f), - BPoint(frame.left + 2.0f, frame.top + 6.0f)); - StrokeLine(BPoint(frame.left + 4.0f, frame.top + 6.0f), - BPoint(frame.left + 4.0f, frame.top + 6.0f)); - StrokeLine(BPoint(frame.left + 6.0f, frame.top + 6.0f), - BPoint(frame.left + 6.0f, frame.top + 6.0f)); - } - - StrokeLine(BPoint(frame.right + 1.0f, frame.bottom + 1.0f), - BPoint(frame.right + 1.0f, frame.bottom + 1.0f)); - - frame.InsetBy(1.0f, 1.0f); - - // Third bevel - SetHighColor(no_tint); - StrokeLine(BPoint(frame.left, frame.bottom), - BPoint(frame.right, frame.bottom)); - StrokeLine(BPoint(frame.right, frame.top)); -} -//------------------------------------------------------------------------------ -void BSlider::_DrawTriangleThumb() -{ - BRect frame = ThumbFrame(); - - rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), - lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), -// lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT), -// lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), -// darken1 = tint_color(no_tint, B_DARKEN_1_TINT), - darken2 = tint_color(no_tint, B_DARKEN_2_TINT), -// darken3 = tint_color(no_tint, B_DARKEN_3_TINT), - darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); - - if (Orientation() == B_HORIZONTAL) - { - SetHighColor(lighten1); - FillTriangle(BPoint(frame.left, frame.bottom - 1.0f), - BPoint(frame.left + 6.0f, frame.top), - BPoint(frame.right, frame.bottom - 1.0f)); - - SetHighColor(darkenmax); - StrokeLine(BPoint(frame.right, frame.bottom + 1), - BPoint(frame.left, frame.bottom + 1)); - StrokeLine(BPoint(frame.right, frame.bottom), - BPoint(frame.left + 6.0f, frame.top)); - - SetHighColor(darken2); - StrokeLine(BPoint(frame.right - 1, frame.bottom), - BPoint(frame.left, frame.bottom)); - StrokeLine(BPoint(frame.left, frame.bottom), - BPoint(frame.left + 5.0f, frame.top + 1)); - - SetHighColor(no_tint); - StrokeLine(BPoint(frame.right - 2, frame.bottom - 1.0f), - BPoint(frame.left + 3.0f, frame.bottom - 1.0f)); - StrokeLine(BPoint(frame.right - 3, frame.bottom - 2.0f), - BPoint(frame.left + 6.0f, frame.top + 1)); - } - else - { - SetHighColor(lighten1); - FillTriangle(BPoint(frame.left + 1.0f, frame.top), - BPoint(frame.left + 7.0f, frame.top + 6.0f), - BPoint(frame.left + 1.0f, frame.bottom)); - - SetHighColor(darkenmax); - StrokeLine(BPoint(frame.left, frame.top + 1), - BPoint(frame.left, frame.bottom)); - StrokeLine(BPoint(frame.left + 1.0f, frame.bottom), - BPoint(frame.left + 7.0f, frame.top + 6.0f)); - - SetHighColor(darken2); - StrokeLine(BPoint(frame.left, frame.top), - BPoint(frame.left, frame.bottom - 1)); - StrokeLine(BPoint(frame.left + 1.0f, frame.top), - BPoint(frame.left + 6.0f, frame.top + 5.0f)); - - SetHighColor(no_tint); - StrokeLine(BPoint(frame.left + 1.0f, frame.top + 2.0f), - BPoint(frame.left + 1.0f, frame.bottom - 1.0f)); - StrokeLine(BPoint(frame.left + 2.0f, frame.bottom - 2.0f), - BPoint(frame.left + 6.0f, frame.top + 6.0f)); - } -} -//------------------------------------------------------------------------------ -BPoint BSlider::_Location() const -{ - return fLocation; -} -//------------------------------------------------------------------------------ -void BSlider::_SetLocation(BPoint p) -{ - fLocation = p; -} -//------------------------------------------------------------------------------ -float BSlider::_MinPosition() const -{ - if (Orientation() == B_HORIZONTAL) - return BarFrame().left + 1.0f; - else - return BarFrame().bottom - 1.0f; -} -//------------------------------------------------------------------------------ -float BSlider::_MaxPosition() const -{ - if (Orientation() == B_HORIZONTAL) - return BarFrame().right - 1.0f; - else - return BarFrame().top + 1.0f; -} -//------------------------------------------------------------------------------ -void BSlider::_ReservedSlider4() {} -void BSlider::_ReservedSlider5() {} -void BSlider::_ReservedSlider6() {} -void BSlider::_ReservedSlider7() {} -void BSlider::_ReservedSlider8() {} -void BSlider::_ReservedSlider9() {} -void BSlider::_ReservedSlider10() {} -void BSlider::_ReservedSlider11() {} -void BSlider::_ReservedSlider12() {} -//------------------------------------------------------------------------------ -BSlider &BSlider::operator=(const BSlider &) -{ - return *this; -} -//------------------------------------------------------------------------------ -void BSlider::_InitObject() -{ -} -//------------------------------------------------------------------------------ - - - - - - - - - - - - - - - - - - - - - - - - - - - +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: Slider.h +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: BSlider creates and displays a sliding thumb control. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include +#include + +// System Includes ------------------------------------------------------------- +#include +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +BSlider::BSlider(BRect frame, const char *name, const char *label, BMessage *message, + int32 minValue, int32 maxValue, thumb_style thumbType, + uint32 resizingMode, uint32 flags) + : BControl(frame, name, label, message, resizingMode, flags), + fModificationMessage(NULL), + fSnoozeAmount(20000), + fUseFillColor(false), + fMinLimitStr(NULL), + fMaxLimitStr(NULL), + fMinValue(minValue), + fMaxValue(maxValue), + fKeyIncrementValue(1), + fHashMarkCount(0), + fHashMarks(B_HASH_MARKS_NONE), + fOffScreenBits(NULL), + fOffScreenView(NULL), + fStyle(thumbType), + fOrientation(B_HORIZONTAL), + fBarThickness(6.0f) +{ + fBarColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_4_TINT); + fFillColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_MAX_TINT); +} +//------------------------------------------------------------------------------ +BSlider::BSlider(BRect frame, const char *name, const char *label, BMessage *message, + int32 minValue, int32 maxValue, orientation posture, + thumb_style thumbType, uint32 resizingMode, uint32 flags) + : BControl(frame, name, label, message, resizingMode, flags), + fModificationMessage(NULL), + fSnoozeAmount(20000), + fUseFillColor(false), + fMinLimitStr(NULL), + fMaxLimitStr(NULL), + fMinValue(minValue), + fMaxValue(maxValue), + fKeyIncrementValue(1), + fHashMarkCount(0), + fHashMarks(B_HASH_MARKS_NONE), + fOffScreenBits(NULL), + fOffScreenView(NULL), + fStyle(thumbType), + fOrientation(posture), + fBarThickness(6.0f) +{ + fBarColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_4_TINT); + fFillColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_MAX_TINT); +} +//------------------------------------------------------------------------------ +BSlider::~BSlider() +{ + if (fMinLimitStr) + free(fMinLimitStr); + + if (fMaxLimitStr) + free(fMaxLimitStr); +} +//------------------------------------------------------------------------------ +BSlider::BSlider(BMessage *archive) + : BControl (archive), + fModificationMessage(NULL), + fSnoozeAmount(20000), + fUseFillColor(false), + fMinLimitStr(NULL), + fMaxLimitStr(NULL), + fMinValue(0), + fMaxValue(100), + fKeyIncrementValue(1), + fHashMarkCount(0), + fHashMarks(B_HASH_MARKS_NONE), + fOffScreenBits(NULL), + fOffScreenView(NULL), + fStyle(B_BLOCK_THUMB), + fOrientation(B_HORIZONTAL), + fBarThickness(6.0f) +{ + BMessage modMessage; + int16 anInt16; + int32 anInt32; + const char *aString1 = NULL, *aString2 = NULL; + const rgb_color *aColorPtr; + + if (archive->FindMessage("_mod_msg", &modMessage)) + SetModificationMessage(new BMessage(modMessage)); + + if (archive->FindInt32("_sdelay", &anInt32)) + SetSnoozeAmount(anInt32); + + if(archive->FindData("_bcolor", B_INT32_TYPE, (const void**)&aColorPtr, NULL)) + SetBarColor(*aColorPtr); + + if(archive->FindData("_fcolor", B_INT32_TYPE, (const void**)&aColorPtr, NULL)) + UseFillColor(true, aColorPtr); + + if (archive->FindString("_minlbl", &aString1) || + archive->FindString("_maxlbl", &aString2)) + SetLimitLabels(aString1, aString2); + + archive->FindInt32("_min", &fMinValue); + archive->FindInt32("_max", &fMaxValue); + + archive->FindInt32("_incrementvalue", &fKeyIncrementValue); + + archive->FindInt32("_hashcount", &fHashMarkCount); + + if(archive->FindInt16("_hashloc", &anInt16)) + SetHashMarks((hash_mark_location)anInt16); + + if(archive->FindInt32("_sstyle", &anInt32)) + SetStyle((thumb_style)anInt32); +} +//------------------------------------------------------------------------------ +BArchivable *BSlider::Instantiate(BMessage *archive) +{ + if (validate_instantiation(archive, "BSlider")) + return new BSlider(archive); + else + return NULL; +} +//------------------------------------------------------------------------------ +status_t BSlider::Archive(BMessage *archive, bool deep) const +{ + status_t err = BControl::Archive(archive, deep); + + if (err != B_OK) + return err; + + if (fModificationMessage) + err = archive->AddMessage("_mod_msg", fModificationMessage); + + if (err != B_OK) + return err; + + if (fSnoozeAmount != 20000) + err = archive->AddInt32("_sdelay", fSnoozeAmount); + + if (err != B_OK) + return err; + + err = archive->AddData("_bcolor", B_INT32_TYPE, &fBarColor, sizeof(int32)); + + if (err != B_OK) + return err; + + err = archive->AddData("_fcolor", B_INT32_TYPE, &fFillColor, sizeof(int32)); + + if (err != B_OK) + return err; + + if (fMinLimitStr) + err = archive->AddString("_minlbl", fMinLimitStr); + + if (err != B_OK) + return err; + + if (fMaxLimitStr) + err = archive->AddString("_maxlbl", fMaxLimitStr); + + if (err != B_OK) + return err; + + err = archive->AddInt32("_min", fMinValue); + + if (err != B_OK) + return err; + + err = archive->AddInt32("_max", fMaxValue); + + if (err != B_OK) + return err; + + if (fKeyIncrementValue != 1) + err = archive->AddInt32("_incrementvalue", fKeyIncrementValue); + + if (err != B_OK) + return err; + + if (fHashMarkCount != 0) + err = archive->AddInt32("_hashcount", fHashMarkCount); + + if (err != B_OK) + return err; + + if (fHashMarks != B_HASH_MARKS_NONE) + err = archive->AddInt16("_hashloc", fHashMarks); + + if (err != B_OK) + return err; + + if (fStyle != B_BLOCK_THUMB) + err = archive->AddInt32("_sstyle", fStyle); + + return err; +} +//------------------------------------------------------------------------------ +status_t BSlider::Perform(perform_code d, void *arg) +{ + return B_ERROR; +} +//------------------------------------------------------------------------------ +void BSlider::WindowActivated(bool state) +{ + +} +//------------------------------------------------------------------------------ +void BSlider::AttachedToWindow() +{ + BControl::AttachedToWindow(); + + ResizeToPreferred(); + + fLocation.Set(9.0f, 0.0f); + + fOffScreenBits = new BBitmap(Bounds(), B_CMAP8, true, false); + fOffScreenView = new BView(Bounds(), "", B_FOLLOW_NONE, B_WILL_DRAW); + fOffScreenBits->AddChild(fOffScreenView); +} +//------------------------------------------------------------------------------ +void BSlider::AllAttached() +{ +} +//------------------------------------------------------------------------------ +void BSlider::AllDetached() +{ +} +//------------------------------------------------------------------------------ +void BSlider::DetachedFromWindow() +{ + // TODO rewrite this + if (fOffScreenView) + { + fOffScreenBits->Lock(); + fOffScreenView->RemoveSelf(); + fOffScreenBits->Unlock(); + delete fOffScreenView; + fOffScreenView = NULL; + } + + if (fOffScreenBits) + { + delete fOffScreenBits; + fOffScreenBits = NULL; + } +} +//------------------------------------------------------------------------------ +void BSlider::MessageReceived(BMessage *msg) +{ +} +//------------------------------------------------------------------------------ +void BSlider::FrameMoved(BPoint new_position) +{ +} +//------------------------------------------------------------------------------ +void BSlider::FrameResized(float w,float h) +{ + if (fOffScreenView) + { + fOffScreenBits->Lock(); + fOffScreenView->RemoveSelf(); + fOffScreenView->ResizeTo(Bounds().Width(), Bounds().Height()); + fOffScreenBits->Unlock(); + } + else + fOffScreenView = new BView(Bounds(), "", B_FOLLOW_NONE, B_WILL_DRAW); + + if (fOffScreenBits) + delete fOffScreenBits; + + fOffScreenBits = new BBitmap(Bounds(), B_CMAP8, true, false); + fOffScreenBits->AddChild(fOffScreenView); +} +//------------------------------------------------------------------------------ +void BSlider::KeyDown(const char *bytes, int32 numBytes) +{ + if (!IsEnabled()) + return; + + int32 value = Value(); + + if (bytes[0] == B_LEFT_ARROW || bytes[0] == B_DOWN_ARROW) + SetValue ( value - 1 ); + else if (bytes[0] == B_RIGHT_ARROW || bytes[0] == B_UP_ARROW) + SetValue(value + 1); + else + BControl::KeyDown(bytes, numBytes); + + if (Value() != value) + Invoke(); +} +//------------------------------------------------------------------------------ +void BSlider::MouseDown(BPoint point) +{ + SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS); + + SetValue(ValueForPoint(point)); + SetTracking(true); +} +//------------------------------------------------------------------------------ +void BSlider::MouseUp(BPoint point) +{ + Invoke(); + + SetTracking(false); +} +//------------------------------------------------------------------------------ +void BSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +{ + if (IsTracking()) + { + SetValue(ValueForPoint(point)); + + if (fModificationMessage) + Invoke(fModificationMessage); + } +} +//------------------------------------------------------------------------------ +void BSlider::Pulse() +{ + BControl::Pulse(); +} +//------------------------------------------------------------------------------ +void BSlider::SetLabel(const char *label) +{ + BControl::SetLabel(label); +} +//------------------------------------------------------------------------------ +void BSlider::SetLimitLabels(const char *minLabel, const char *maxLabel) +{ + if (minLabel) + { + if (fMinLimitStr) + free(fMinLimitStr); + fMinLimitStr = strdup(minLabel); + } + + if (maxLabel) + { + if (fMaxLimitStr) + free(fMaxLimitStr); + fMaxLimitStr = strdup(maxLabel); + } + + ResizeToPreferred(); + Invalidate(); +} +//------------------------------------------------------------------------------ +const char *BSlider::MinLimitLabel() const +{ + return fMinLimitStr; +} +//------------------------------------------------------------------------------ +const char *BSlider::MaxLimitLabel() const +{ + return fMaxLimitStr; +} +//------------------------------------------------------------------------------ +void BSlider::SetValue(int32 value) +{ + value = max_c(fMinValue, min_c(fMaxValue, value)); + BControl::SetValue(value); +} +//------------------------------------------------------------------------------ +int32 BSlider::ValueForPoint(BPoint location) const +{ + if (fOrientation == B_HORIZONTAL) + return (int32)((location.x - _MinPosition()) * (fMaxValue - fMinValue) / + (_MaxPosition() - _MinPosition())) + fMinValue; + else + return (int32)((location.y - _MinPosition()) * (fMaxValue - fMinValue) / + (_MaxPosition() - _MinPosition())) + fMinValue; +} +//------------------------------------------------------------------------------ +void BSlider::SetPosition(float position) +{ + if (position <= 0.0f) + BControl::SetValue(fMinValue); + else if (position >= 1.0f) + BControl::SetValue(fMaxValue); + else + BControl::SetValue((int32)(position *(fMaxValue - fMinValue) + fMinValue)); +} +//------------------------------------------------------------------------------ +float BSlider::Position() const +{ + return ((float)(BControl::Value() - fMinValue) / (float)(fMaxValue - fMinValue)); +} +//------------------------------------------------------------------------------ +void BSlider::SetEnabled(bool on) +{ + BControl::SetEnabled(on); +} +//------------------------------------------------------------------------------ +void BSlider::GetLimits(int32 *minimum, int32 *maximum) +{ + *minimum = fMinValue; + *maximum = fMaxValue; +} +//------------------------------------------------------------------------------ +void BSlider::Draw(BRect updateRect) +{ + fOffScreenBits->Lock(); + DrawSlider(); + fOffScreenView->Sync(); + fOffScreenBits->Unlock(); + + if (fOffScreenBits) + DrawBitmap(fOffScreenBits, B_ORIGIN); +} +//------------------------------------------------------------------------------ +void BSlider::DrawSlider() +{ + OffscreenView()->SetHighColor(ViewColor()); + OffscreenView()->FillRect(Bounds()); + + DrawBar(); + DrawHashMarks(); + DrawThumb(); + + if (IsFocus()) + DrawFocusMark(); + + DrawText(); +} +//------------------------------------------------------------------------------ +void BSlider::DrawBar() +{ + BRect frame = BarFrame(); + BView *view = OffscreenView(); + + if (fUseFillColor) + { + if (fOrientation == B_HORIZONTAL) + { + view->SetHighColor(fBarColor); + view->FillRect(BRect((float)floor(frame.left + 1 + Position() * + (frame.Width() - 2)), frame.top, frame.right, frame.bottom)); + + view->SetHighColor(fFillColor); + view->FillRect(BRect(frame.left, frame.top, + (float)floor(frame.left + 1 + Position() * (frame.Width() - 2)), + frame.bottom)); + } + else + { + view->SetHighColor(fBarColor); + view->FillRect(BRect(frame.left, frame.top, frame.right, + (float)floor(frame.bottom - 1 - Position() * (frame.Height() - 2)))); + + view->SetHighColor(fFillColor); + view->FillRect(BRect(frame.left, + (float)floor(frame.bottom - 1 - Position() * + (frame.Height() - 2)), frame.right, frame.bottom)); + + } + } + else + { + view->SetHighColor(fBarColor); + view->FillRect(frame); + } + + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), + lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), + darken1 = tint_color(no_tint, B_DARKEN_1_TINT), + darken2 = tint_color(no_tint, B_DARKEN_2_TINT), + darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); + + view->SetHighColor(darken1); + view->StrokeLine(BPoint(frame.left, frame.top), + BPoint(frame.left + 1.0f, frame.top)); + view->StrokeLine(BPoint(frame.left, frame.bottom), + BPoint(frame.left + 1.0f, frame.bottom)); + view->StrokeLine(BPoint(frame.right - 1.0f, frame.top), + BPoint(frame.right, frame.top)); + + view->SetHighColor(darken2); + view->StrokeLine(BPoint(frame.left + 1.0f, frame.top), + BPoint(frame.right - 1.0f, frame.top)); + view->StrokeLine(BPoint(frame.left, frame.bottom - 1.0f), + BPoint(frame.left, frame.top + 1.0f)); + + view->SetHighColor(lightenmax); + view->StrokeLine(BPoint(frame.left + 1.0f, frame.bottom), + BPoint(frame.right, frame.bottom)); + view->StrokeLine(BPoint(frame.right, frame.top + 1.0f)); + + frame.InsetBy(1.0f, 1.0f); + + view->SetHighColor(darkenmax); + view->StrokeLine(BPoint(frame.left, frame.bottom), + BPoint(frame.left, frame.top)); + view->StrokeLine(BPoint(frame.right, frame.top)); +} +//------------------------------------------------------------------------------ +void BSlider::DrawHashMarks() +{ + BRect frame = HashMarksFrame(); + BView *view = OffscreenView(); + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), + lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), + darken2 = tint_color(no_tint, B_DARKEN_2_TINT); + + float pos = _MinPosition(); + float factor = (_MaxPosition() - pos) / (fHashMarkCount - 1); + + if (fHashMarks & B_HASH_MARKS_TOP) + { + if (fOrientation == B_HORIZONTAL) + { + for (int32 i = 0; i < fHashMarkCount; i++) + { + view->SetHighColor(darken2); + view->StrokeLine(BPoint(pos, frame.top), + BPoint(pos, frame.top + 5)); + view->SetHighColor(lightenmax); + view->StrokeLine(BPoint(pos + 1, frame.top), + BPoint(pos + 1, frame.top + 5)); + + pos += factor; + } + } + else + { + for (int32 i = 0; i < fHashMarkCount; i++) + { + view->SetHighColor(darken2); + view->StrokeLine(BPoint(frame.left, pos), + BPoint(frame.left + 5, pos)); + view->SetHighColor(lightenmax); + view->StrokeLine(BPoint(frame.left, pos + 1), + BPoint(frame.left + 5, pos + 1)); + + pos += factor; + } + } + } + + pos = _MinPosition(); + + if (fHashMarks & B_HASH_MARKS_BOTTOM) + { + if (fOrientation == B_HORIZONTAL) + { + for (int32 i = 0; i < fHashMarkCount; i++) + { + view->SetHighColor(darken2); + view->StrokeLine(BPoint(pos, frame.bottom - 5), + BPoint(pos, frame.bottom)); + view->SetHighColor(lightenmax); + view->StrokeLine(BPoint(pos + 1, frame.bottom - 5), + BPoint(pos + 1, frame.bottom)); + + pos += factor; + } + } + else + { + for (int32 i = 0; i < fHashMarkCount; i++) + { + view->SetHighColor(darken2); + view->StrokeLine(BPoint(frame.right - 5, pos), + BPoint(frame.right, pos)); + view->SetHighColor(lightenmax); + view->StrokeLine(BPoint(frame.right - 5, pos + 1), + BPoint(frame.right, pos + 1)); + + pos += factor; + } + } + } +} +//------------------------------------------------------------------------------ +void BSlider::DrawThumb() +{ + if (fStyle == B_BLOCK_THUMB) + _DrawBlockThumb(); + else + _DrawTriangleThumb(); +} +//------------------------------------------------------------------------------ +void BSlider::DrawFocusMark() +{ + OffscreenView()->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); + OffscreenView()->StrokeRect(Bounds()); +} +//------------------------------------------------------------------------------ +void BSlider::DrawText() +{ + BRect bounds(Bounds()); + BView *view = OffscreenView(); + + view->SetHighColor(0, 0, 0); + + font_height fheight; + + GetFontHeight(&fheight); + + if (Orientation() == B_HORIZONTAL) + { + if (Label()) + view->DrawString(Label(), BPoint(2.0f, (float)ceil(fheight.ascent))); + + if (fMinLimitStr) + view->DrawString(fMinLimitStr, BPoint(2.0f, bounds.bottom - 4.0f)); + + if (fMaxLimitStr) + view->DrawString(fMaxLimitStr, BPoint(bounds.right - + StringWidth(fMaxLimitStr) - 2.0f, bounds.bottom - 4.0f)); + } + else + { + float ascent = (float)ceil(fheight.ascent); + + if (Label()) + view->DrawString(Label(), BPoint(bounds.Width() / 2.0f - + StringWidth(Label()) / 2.0f, ascent)); + + if (fMaxLimitStr) + view->DrawString(fMaxLimitStr, BPoint(bounds.Width() / 2.0f - + StringWidth(fMaxLimitStr) / 2.0f, ascent + + (Label() ? (float)ceil(ascent + fheight.descent + 2.0f) : 0.0f))); + + if (fMinLimitStr) + view->DrawString(fMinLimitStr, BPoint(bounds.Width() / 2.0f - + StringWidth(fMinLimitStr) / 2.0f, + bounds.bottom - 2.0f)); + } +} +//------------------------------------------------------------------------------ +char *BSlider::UpdateText() const +{ + return NULL; +} +//------------------------------------------------------------------------------ +BRect BSlider::BarFrame() const +{ + BRect frame = Bounds(); + font_height fheight; + + GetFontHeight(&fheight); + + float textHeight = (float)ceil(fheight.ascent + fheight.descent); + + if (fStyle == B_BLOCK_THUMB) + { + if (Orientation() == B_HORIZONTAL) + { + frame.left = 8.0f; + frame.top = 6.0f + (Label() ? textHeight + 4.0f : 0.0f); + frame.right -= 8.0f; + frame.bottom = frame.bottom - 6.0f - + (fMinLimitStr || fMaxLimitStr ? textHeight + 4.0f : 0.0f); + } + else + { + frame.left = frame.Width() / 2.0f - 3; + frame.top = 12.0f + (Label() ? textHeight : 0.0f) + + (fMaxLimitStr ? textHeight : 0.0f); + frame.right = frame.left + 6; + frame.bottom = frame.bottom - 8.0f - + (fMinLimitStr ? textHeight + 4 : 0.0f); + } + } + else + { + if (Orientation() == B_HORIZONTAL) + { + frame.left = 7.0f; + frame.top = 6.0f + (Label() ? textHeight + 4.0f : 0.0f); + frame.right -= 7.0f; + frame.bottom = frame.bottom - 6.0f - + (fMinLimitStr || fMaxLimitStr ? textHeight + 4.0f : 0.0f); + } + else + { + frame.left = frame.Width() / 2.0f - 3; + frame.top = 11.0f + (Label() ? textHeight : 0.0f) + + (fMaxLimitStr ? textHeight : 0.0f); + frame.right = frame.left + 6; + frame.bottom = frame.bottom - 7.0f - + (fMinLimitStr ? textHeight + 4 : 0.0f); + } + } + + return frame; +} +//------------------------------------------------------------------------------ +BRect BSlider::HashMarksFrame() const +{ + BRect frame(BarFrame()); + + if (fOrientation == B_HORIZONTAL) + { + frame.top -= 6.0f; + frame.bottom += 6.0f; + } + else + { + frame.left -= 6.0f; + frame.right += 6.0f; + } + + return frame; +} +//------------------------------------------------------------------------------ +BRect BSlider::ThumbFrame() const +{ + BRect frame = Bounds(); + font_height fheight; + + GetFontHeight(&fheight); + + float textHeight = (float)ceil(fheight.ascent + fheight.descent); + + if (fStyle == B_BLOCK_THUMB) + { + if (Orientation() == B_HORIZONTAL) + { + frame.left = (float)floor(Position() * (_MaxPosition() - _MinPosition()) + + _MinPosition()) - 8.0f; + frame.top = 2.0f + (Label() ? textHeight + 4.0f : 0.0f); + frame.right = frame.left + 17.0f; + frame.bottom = frame.bottom - 3.0f - + (MinLimitLabel() || MaxLimitLabel() ? textHeight + 4.0f : 0.0f); + } + else + { + frame.left = frame.Width() / 2.0f - 7; + frame.top = (float)floor(Position() * (_MaxPosition() - _MinPosition()) + + _MinPosition()) - 8.0f; + frame.right = frame.left + 13; + frame.bottom = frame.top + 17; + } + } + else + { + if (Orientation() == B_HORIZONTAL) + { + frame.left = (float)floor(Position() * (_MaxPosition() - _MinPosition()) + + _MinPosition()) - 6; + frame.top = 9.0f + (Label() ? textHeight + 4.0f : 0.0f); + frame.right = frame.left + 12.0f; + frame.bottom = frame.bottom - 3.0f - + (MinLimitLabel() || MaxLimitLabel() ? textHeight + 4.0f : 0.0f); + } + else + { + frame.left = frame.Width() / 2.0f - 6; + frame.top = (float)floor(Position() * (_MaxPosition() - _MinPosition())) + + _MinPosition() - 6.0f; + frame.right = frame.left + 7; + frame.bottom = frame.top + 12; + } + } + + return frame; +} +//------------------------------------------------------------------------------ +void BSlider::SetFlags(uint32 flags) +{ + // TODO: Check if we have to filter this + BControl::SetFlags(flags); +} +//------------------------------------------------------------------------------ +void BSlider::SetResizingMode(uint32 mode) +{ + // TODO: Check if we have to filter this + BControl::SetResizingMode(mode); +} +//------------------------------------------------------------------------------ +void BSlider::GetPreferredSize(float *width, float *height) +{ + font_height fheight; + + GetFontHeight(&fheight); + + if (Orientation() == B_HORIZONTAL) + { + *width = (Frame().Width() < 32.0f) ? 32.0f : Frame().Width(); + *height = 18.0f; + + if (Label()) + *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; + + if (MinLimitLabel() || MaxLimitLabel()) + *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; + } + else // B_VERTICAL + { + *width = (Frame().Width() < 18.0f) ? 18.0f : Frame().Width(); + *height = 32.0f; + + if (Label()) + *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; + + if (MaxLimitLabel()) + *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; + + if (MinLimitLabel()) + *height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f; + + if (Label() && (MaxLimitLabel())) + *height -= 4.0f; + + *height = (Frame().Height() < *height) ? *height : Frame().Height(); + } +} +//------------------------------------------------------------------------------ +void BSlider::ResizeToPreferred() +{ + BControl::ResizeToPreferred(); +} +//------------------------------------------------------------------------------ +status_t BSlider::Invoke(BMessage *msg) +{ + return BControl::Invoke(msg); +} +//------------------------------------------------------------------------------ +BHandler *BSlider::ResolveSpecifier(BMessage *message, int32 index, + BMessage *specifier, int32 command, + const char *property) +{ + return BControl::ResolveSpecifier(message, index, specifier, command, + property); +} +//------------------------------------------------------------------------------ +status_t BSlider::GetSupportedSuites(BMessage *message) +{ + BControl::GetSupportedSuites(message); + + message->AddString("suites", "suite/vnd.Be-slider"); + + return B_OK; +} +//------------------------------------------------------------------------------ +void BSlider::SetModificationMessage(BMessage *message) +{ + if (fModificationMessage) + delete fModificationMessage; + + fModificationMessage = message; +} +//------------------------------------------------------------------------------ +BMessage *BSlider::ModificationMessage() const +{ + return fModificationMessage; +} +//------------------------------------------------------------------------------ +void BSlider::SetSnoozeAmount(int32 snooze_time) +{ + fSnoozeAmount = snooze_time; +} +//------------------------------------------------------------------------------ +int32 BSlider::SnoozeAmount() const +{ + return fSnoozeAmount; +} +//------------------------------------------------------------------------------ +void BSlider::SetKeyIncrementValue(int32 increment_value) +{ + fKeyIncrementValue = increment_value; +} +//------------------------------------------------------------------------------ +int32 BSlider::KeyIncrementValue() const +{ + return fKeyIncrementValue; +} +//------------------------------------------------------------------------------ +void BSlider::SetHashMarkCount(int32 hash_mark_count) +{ + fHashMarkCount = hash_mark_count; + Invalidate(); +} +//------------------------------------------------------------------------------ +int32 BSlider::HashMarkCount() const +{ + return fHashMarkCount; +} +//------------------------------------------------------------------------------ +void BSlider::SetHashMarks(hash_mark_location where) +{ + fHashMarks = where; + Invalidate(); +} +//------------------------------------------------------------------------------ +hash_mark_location BSlider::HashMarks() const +{ + return fHashMarks; +} +//------------------------------------------------------------------------------ +void BSlider::SetStyle(thumb_style style) +{ + // TODO: Do the necessary to change the style + fStyle = style; +} +//------------------------------------------------------------------------------ +thumb_style BSlider::Style() const +{ + return fStyle; +} +//------------------------------------------------------------------------------ +void BSlider::SetBarColor(rgb_color bar_color) +{ + fBarColor = bar_color; +} +//------------------------------------------------------------------------------ +rgb_color BSlider::BarColor() const +{ + return fBarColor; +} +//------------------------------------------------------------------------------ +void BSlider::UseFillColor(bool use_fill, const rgb_color *bar_color) +{ + fUseFillColor = use_fill; + + if (bar_color) + fFillColor = *bar_color; +} +//------------------------------------------------------------------------------ +bool BSlider::FillColor(rgb_color *bar_color) const +{ + *bar_color = fFillColor; + + return fUseFillColor; +} +//------------------------------------------------------------------------------ +BView *BSlider::OffscreenView() const +{ + return fOffScreenView; +} +//------------------------------------------------------------------------------ +orientation BSlider::Orientation() const +{ + return fOrientation; +} +//------------------------------------------------------------------------------ +void BSlider::SetOrientation(orientation posture) +{ + // TODO: Do the necessary to change the orientation + fOrientation = posture; +} +//------------------------------------------------------------------------------ +float BSlider::BarThickness() const +{ + return fBarThickness; +} +//------------------------------------------------------------------------------ +void BSlider::SetBarThickness(float thickness) +{ + // TODO: Resize the control + fBarThickness = thickness; +} +//------------------------------------------------------------------------------ +void BSlider::SetFont(const BFont *font, uint32 properties) +{ + // TODO: Resize the control + BControl::SetFont(font, properties); +} +//------------------------------------------------------------------------------ +void BSlider::_DrawBlockThumb() +{ + BRect frame = ThumbFrame(); + BView *view = OffscreenView(); + + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), + lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT), + darken2 = tint_color(no_tint, B_DARKEN_2_TINT), + darken3 = tint_color(no_tint, B_DARKEN_3_TINT), + darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); + + // Outline + view->SetHighColor(darken3); + view->StrokeLine(BPoint(frame.left, frame.bottom - 2.0f), + BPoint(frame.left, frame.top + 1.0f)); + view->StrokeLine(BPoint(frame.left + 1.0f, frame.top), + BPoint(frame.right - 2.0f, frame.top)); + view->StrokeLine(BPoint(frame.right, frame.top + 2.0f), + BPoint(frame.right, frame.bottom - 1.0f)); + view->StrokeLine(BPoint(frame.left + 2.0f, frame.bottom), + BPoint(frame.right - 1.0f, frame.bottom)); + + // First bevel + frame.InsetBy(1.0f, 1.0f); + + view->SetHighColor(lighten2); + view->FillRect(frame); + + view->SetHighColor(darkenmax); + view->StrokeLine(BPoint(frame.left, frame.bottom), + BPoint(frame.right - 1.0f, frame.bottom)); + view->StrokeLine(BPoint(frame.right, frame.bottom - 1), + BPoint(frame.right, frame.top)); + + frame.InsetBy(1.0f, 1.0f); + + // Second bevel and center dots + view->SetHighColor(darken2); + view->StrokeLine(BPoint(frame.left, frame.bottom), + BPoint(frame.right, frame.bottom)); + view->StrokeLine(BPoint(frame.right, frame.top)); + + if (Orientation() == B_HORIZONTAL) + { + view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 2.0f), + BPoint(frame.left + 6.0f, frame.top + 2.0f)); + view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 4.0f), + BPoint(frame.left + 6.0f, frame.top + 4.0f)); + view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 6.0f), + BPoint(frame.left + 6.0f, frame.top + 6.0f)); + } + else + { + view->StrokeLine(BPoint(frame.left + 2.0f, frame.top + 6.0f), + BPoint(frame.left + 2.0f, frame.top + 6.0f)); + view->StrokeLine(BPoint(frame.left + 4.0f, frame.top + 6.0f), + BPoint(frame.left + 4.0f, frame.top + 6.0f)); + view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 6.0f), + BPoint(frame.left + 6.0f, frame.top + 6.0f)); + } + + view->StrokeLine(BPoint(frame.right + 1.0f, frame.bottom + 1.0f), + BPoint(frame.right + 1.0f, frame.bottom + 1.0f)); + + frame.InsetBy(1.0f, 1.0f); + + // Third bevel + view->SetHighColor(no_tint); + view->StrokeLine(BPoint(frame.left, frame.bottom), + BPoint(frame.right, frame.bottom)); + view->StrokeLine(BPoint(frame.right, frame.top)); +} +//------------------------------------------------------------------------------ +void BSlider::_DrawTriangleThumb() +{ + BRect frame = ThumbFrame(); + BView *view = OffscreenView(); + + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR), + lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT), +// lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT), +// lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT), +// darken1 = tint_color(no_tint, B_DARKEN_1_TINT), + darken2 = tint_color(no_tint, B_DARKEN_2_TINT), +// darken3 = tint_color(no_tint, B_DARKEN_3_TINT), + darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT); + + if (Orientation() == B_HORIZONTAL) + { + view->SetHighColor(lighten1); + view->FillTriangle(BPoint(frame.left, frame.bottom - 1.0f), + BPoint(frame.left + 6.0f, frame.top), + BPoint(frame.right, frame.bottom - 1.0f)); + + view->SetHighColor(darkenmax); + view->StrokeLine(BPoint(frame.right, frame.bottom + 1), + BPoint(frame.left, frame.bottom + 1)); + view->StrokeLine(BPoint(frame.right, frame.bottom), + BPoint(frame.left + 6.0f, frame.top)); + + view->SetHighColor(darken2); + view->StrokeLine(BPoint(frame.right - 1, frame.bottom), + BPoint(frame.left, frame.bottom)); + view->StrokeLine(BPoint(frame.left, frame.bottom), + BPoint(frame.left + 5.0f, frame.top + 1)); + + view->SetHighColor(no_tint); + view->StrokeLine(BPoint(frame.right - 2, frame.bottom - 1.0f), + BPoint(frame.left + 3.0f, frame.bottom - 1.0f)); + view->StrokeLine(BPoint(frame.right - 3, frame.bottom - 2.0f), + BPoint(frame.left + 6.0f, frame.top + 1)); + } + else + { + view->SetHighColor(lighten1); + view->FillTriangle(BPoint(frame.left + 1.0f, frame.top), + BPoint(frame.left + 7.0f, frame.top + 6.0f), + BPoint(frame.left + 1.0f, frame.bottom)); + + view->SetHighColor(darkenmax); + view->StrokeLine(BPoint(frame.left, frame.top + 1), + BPoint(frame.left, frame.bottom)); + view->StrokeLine(BPoint(frame.left + 1.0f, frame.bottom), + BPoint(frame.left + 7.0f, frame.top + 6.0f)); + + view->SetHighColor(darken2); + view->StrokeLine(BPoint(frame.left, frame.top), + BPoint(frame.left, frame.bottom - 1)); + view->StrokeLine(BPoint(frame.left + 1.0f, frame.top), + BPoint(frame.left + 6.0f, frame.top + 5.0f)); + + view->SetHighColor(no_tint); + view->StrokeLine(BPoint(frame.left + 1.0f, frame.top + 2.0f), + BPoint(frame.left + 1.0f, frame.bottom - 1.0f)); + view->StrokeLine(BPoint(frame.left + 2.0f, frame.bottom - 2.0f), + BPoint(frame.left + 6.0f, frame.top + 6.0f)); + } +} +//------------------------------------------------------------------------------ +BPoint BSlider::_Location() const +{ + return fLocation; +} +//------------------------------------------------------------------------------ +void BSlider::_SetLocation(BPoint p) +{ + fLocation = p; +} +//------------------------------------------------------------------------------ +float BSlider::_MinPosition() const +{ + if (Orientation() == B_HORIZONTAL) + return BarFrame().left + 1.0f; + else + return BarFrame().bottom - 1.0f; +} +//------------------------------------------------------------------------------ +float BSlider::_MaxPosition() const +{ + if (Orientation() == B_HORIZONTAL) + return BarFrame().right - 1.0f; + else + return BarFrame().top + 1.0f; +} +//------------------------------------------------------------------------------ +void BSlider::_ReservedSlider4() {} +void BSlider::_ReservedSlider5() {} +void BSlider::_ReservedSlider6() {} +void BSlider::_ReservedSlider7() {} +void BSlider::_ReservedSlider8() {} +void BSlider::_ReservedSlider9() {} +void BSlider::_ReservedSlider10() {} +void BSlider::_ReservedSlider11() {} +void BSlider::_ReservedSlider12() {} +//------------------------------------------------------------------------------ +BSlider &BSlider::operator=(const BSlider &) +{ + return *this; +} +//------------------------------------------------------------------------------ +void BSlider::_InitObject() +{ + // TODO: Move common init code here +} +//------------------------------------------------------------------------------ + + + + + + + + + + + + + + + + + + + + + + + + + + +