diff --git a/src/kits/interface/Button.cpp b/src/kits/interface/Button.cpp index 1cc0cf2fab..809c083849 100644 --- a/src/kits/interface/Button.cpp +++ b/src/kits/interface/Button.cpp @@ -79,8 +79,8 @@ status_t BButton::Archive(BMessage* archive, bool deep) const if (err != B_OK) return err; - if (fDrawAsDefault) - err = archive->AddBool("_default", fDrawAsDefault); + if (IsDefault()) + err = archive->AddBool("_default", true); return err; } @@ -181,10 +181,7 @@ void BButton::Draw(BRect updateRect) rect.top -= 3; rect.right += 2; rect.bottom += 2; - SetDrawingMode(B_OP_INVERT); - SetHighColor(0, 0, 0); - FillRect(rect); - SetDrawingMode(B_OP_COPY); + InvertRect(rect); } // Label @@ -275,15 +272,35 @@ void BButton::Draw(BRect updateRect) 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); + + if (Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) + { + BRect bounds = Bounds(); + uint32 buttons; + + do + { + snooze(40000); + + GetMouse(&point, &buttons, true); + + bool inside = bounds.Contains(point); + + if ((Value() == B_CONTROL_ON) != inside) + SetValue(inside ? B_CONTROL_ON : B_CONTROL_OFF); + } while (buttons != 0); + + if (Value() == B_CONTROL_ON) + Invoke(); + } + else + { + SetTracking(true); + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); + } } //------------------------------------------------------------------------------ void BButton::AttachedToWindow() @@ -294,23 +311,15 @@ void BButton::AttachedToWindow() Window()->SetDefaultButton(this); } //------------------------------------------------------------------------------ -void BButton::KeyDown ( const char *bytes, int32 numBytes ) +void BButton::KeyDown(const char *bytes, int32 numBytes) { - if (numBytes == 1) + if (*bytes == B_ENTER || *bytes == B_SPACE) { - switch (bytes[0]) - { - case B_ENTER: - case B_SPACE: - SetValue(B_CONTROL_ON); - snooze(50000); - SetValue(B_CONTROL_OFF); - Invoke(); - break; + if (!IsEnabled()) + return; - default: - BControl::KeyDown(bytes, numBytes); - } + SetValue(B_CONTROL_ON); + Invoke(); } else BControl::KeyDown(bytes, numBytes); @@ -318,26 +327,36 @@ void BButton::KeyDown ( const char *bytes, int32 numBytes ) //------------------------------------------------------------------------------ void BButton::MakeDefault(bool flag) { - if (flag == IsDefault()) - return; - - fDrawAsDefault = flag; + BButton *oldDefault = NULL; BWindow *window = Window(); - + + if (window) + oldDefault = window->DefaultButton(); + if (flag) { + if (fDrawAsDefault && oldDefault == this) + return; + + fDrawAsDefault = true; + ResizeBy(6.0f, 6.0f); MoveBy(-3.0f, -3.0f); - if (window) - window->SetDefaultButton((BButton*)this); + if (window && oldDefault != this) + window->SetDefaultButton(this); } else { + if (!fDrawAsDefault) + return; + + fDrawAsDefault = false; + ResizeBy(-6.0f, -6.0f); MoveBy(3.0f, 3.0f); - - if (window) + + if (window && oldDefault == this) window->SetDefaultButton(NULL); } } @@ -364,32 +383,24 @@ void BButton::WindowActivated(bool 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); + if (!IsTracking()) + return; + + bool inside = Bounds().Contains(point); + + if ((Value() == B_CONTROL_ON) != inside) + SetValue(inside ? B_CONTROL_ON : B_CONTROL_OFF); } //------------------------------------------------------------------------------ void BButton::MouseUp(BPoint point) { - if (IsEnabled() && IsTracking()) - { - if (Bounds().Contains(point)) - { - if ( Value() == B_CONTROL_ON) - { - SetValue(B_CONTROL_OFF); - Invoke(); - } - } - - SetTracking(false); - } + if (!IsTracking()) + return; + + if (Bounds().Contains(point)) + Invoke(); + + SetTracking(false); } //------------------------------------------------------------------------------ void BButton::DetachedFromWindow() @@ -427,7 +438,14 @@ void BButton::ResizeToPreferred() //------------------------------------------------------------------------------ status_t BButton::Invoke(BMessage *message) { - return BControl::Invoke(message); + Sync(); + snooze(50000); + + status_t err = BControl::Invoke(message); + + SetValue(B_CONTROL_OFF); + + return err; } //------------------------------------------------------------------------------ void BButton::FrameMoved(BPoint newLocation) @@ -469,9 +487,8 @@ status_t BButton::GetSupportedSuites(BMessage *message) //------------------------------------------------------------------------------ status_t BButton::Perform(perform_code d, void *arg) { - return B_ERROR; + return BControl::Perform(d, arg); } - //------------------------------------------------------------------------------ void BButton::_ReservedButton1() {} void BButton::_ReservedButton2() {} @@ -545,7 +562,10 @@ BRect BButton::DrawDefault(BRect bounds, bool enabled) //------------------------------------------------------------------------------ status_t BButton::Execute() { - // TODO: Is there a use for this? Maybe visual feedback happens here? + if (!IsEnabled()) + return B_ERROR; + + SetValue(B_CONTROL_ON); return Invoke(); } //------------------------------------------------------------------------------ diff --git a/src/kits/interface/CheckBox.cpp b/src/kits/interface/CheckBox.cpp index f57dfd6117..738c26524b 100644 --- a/src/kits/interface/CheckBox.cpp +++ b/src/kits/interface/CheckBox.cpp @@ -28,6 +28,7 @@ // System Includes ------------------------------------------------------------- #include +#include #include // Project Includes ------------------------------------------------------------ @@ -47,7 +48,7 @@ BCheckBox::BCheckBox(BRect frame, const char *name, const char *label, // Resize to minimum height if needed font_height fh; GetFontHeight(&fh); - float minHeight = 6.0f + (float)ceil(fh.ascent + fh.descent); + float minHeight = (float)ceil(6.0f + fh.ascent + fh.descent); if (Bounds().Height() < minHeight) ResizeTo(Bounds().Width(), minHeight); } @@ -240,17 +241,50 @@ void BCheckBox::AttachedToWindow() void BCheckBox::MouseDown(BPoint point) { if (!IsEnabled()) - { - BControl::MouseDown(point); return; - } - - SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | - B_SUSPEND_VIEW_FOCUS); fOutlined = true; - SetTracking(true); - Invalidate(); + Draw(Bounds()); + Flush(); + + if (Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) + { + BRect bounds = Bounds(); + uint32 buttons; + + do + { + snooze(40000); + + GetMouse(&point, &buttons, true); + + bool inside = bounds.Contains(point); + + if (fOutlined != inside) + { + fOutlined = inside; + Draw(Bounds()); + Flush(); + } + } while (buttons != 0); + + if (fOutlined) + { + fOutlined = false; + SetValue(!Value()); + Invoke(); + } + else + { + Draw(Bounds()); + Flush(); + } + } + else + { + SetTracking(true); + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); + } } //------------------------------------------------------------------------------ void BCheckBox::MessageReceived(BMessage *message) @@ -270,41 +304,50 @@ void BCheckBox::KeyDown(const char *bytes, int32 numBytes) //------------------------------------------------------------------------------ void BCheckBox::MouseUp(BPoint point) { - if (IsEnabled() && IsTracking()) - { - fOutlined = false; - - if (Bounds().Contains(point)) - { - if (Value() == B_CONTROL_OFF) - SetValue(B_CONTROL_ON); - else - SetValue(B_CONTROL_OFF); - - BControl::Invoke(); - } - SetTracking(false); - } - else - { - BControl::MouseUp(point); + if (!IsTracking()) return; + + bool inside = Bounds().Contains(point); + + if (fOutlined != inside) + { + fOutlined = inside; + Draw(Bounds()); + Flush(); } + + if (fOutlined) + { + if (fOutlined) + { + fOutlined = false; + SetValue(!Value()); + Invoke(); + } + else + { + Draw(Bounds()); + Flush(); + } + } + + SetTracking(false); } //------------------------------------------------------------------------------ -void BCheckBox::MouseMoved(BPoint point, uint32 transit, const BMessage *message) +void BCheckBox::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; + if (!IsTracking()) + return; - Invalidate(); + bool inside = Bounds().Contains(point); + + if (fOutlined != inside) + { + fOutlined = inside; + Draw(Bounds()); + Flush(); } - else - BControl::MouseMoved(point, transit, message); } //------------------------------------------------------------------------------ void BCheckBox::DetachedFromWindow() @@ -322,8 +365,13 @@ void BCheckBox::GetPreferredSize(float *width, float *height) font_height fh; GetFontHeight(&fh); - *height = 6.0f + (float)ceil(fh.ascent + fh.descent); - *width = 12.0f + (float)ceil(fh.ascent) + (float)ceil(StringWidth(Label())); + *height = (float)ceil(6.0f + fh.ascent + fh.descent); + *width = 12.0f + fh.ascent; + + if (Label()) + *width += StringWidth(Label()); + + *width = (float)ceil(*width); } //------------------------------------------------------------------------------ void BCheckBox::ResizeToPreferred() @@ -375,7 +423,7 @@ void BCheckBox::AllDetached() //------------------------------------------------------------------------------ status_t BCheckBox::Perform(perform_code d, void *arg) { - return B_ERROR; + return BControl::Perform(d, arg); } //------------------------------------------------------------------------------ void BCheckBox::_ReservedCheckBox1() {} diff --git a/src/kits/interface/Control.cpp b/src/kits/interface/Control.cpp index ef17becb3f..3723162be4 100644 --- a/src/kits/interface/Control.cpp +++ b/src/kits/interface/Control.cpp @@ -89,50 +89,51 @@ static property_info prop_list[] = }; //------------------------------------------------------------------------------ -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) +BControl::BControl(BRect frame, const char *name, const char *label, + BMessage *message, uint32 resizingMode, uint32 flags) + : BView(frame, name, resizingMode, flags) { - fLabel = strdup(label); + InitData(NULL); + + SetLabel(label); + SetMessage(message); } //------------------------------------------------------------------------------ BControl::~BControl() { if (fLabel) free(fLabel); + + SetMessage(NULL); } //------------------------------------------------------------------------------ -BControl::BControl(BMessage *archive) : BView(archive) +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; + InitData(archive); BMessage message; if (archive->FindMessage("_msg", &message) == B_OK) SetMessage(new BMessage(message)); + + const char *label; + + if (archive->FindString("_label", &label) != B_OK) + SetLabel(label); + + int32 value; + + if (archive->FindInt32("_val", &value) != B_OK) + SetValue(value); + + bool toggle; + + if (archive->FindBool("_disable", &toggle) != B_OK) + SetEnabled(!toggle); + + if (archive->FindBool("be:wants_nav", &toggle) != B_OK) + fWantsNav = toggle; } //------------------------------------------------------------------------------ BArchivable *BControl::Instantiate(BMessage *archive) @@ -176,21 +177,23 @@ status_t BControl::Archive(BMessage *archive, bool deep) const //------------------------------------------------------------------------------ void BControl::WindowActivated(bool active) { - if (IsFocus()) - { - Draw(Bounds()); - Flush(); - } - BView::WindowActivated(active); + + if (IsFocus()) + Draw(Bounds()); } //------------------------------------------------------------------------------ void BControl::AttachedToWindow() { if (Parent()) - SetViewColor(Parent()->ViewColor()); + { + rgb_color color = Parent()->ViewColor(); - if (Target() == NULL) + SetViewColor(color); + SetLowColor(color); + } + + if (!Messenger().IsValid()) BInvoker::SetTarget(BMessenger(Window(), NULL)); BView::AttachedToWindow(); @@ -198,89 +201,90 @@ void BControl::AttachedToWindow() //------------------------------------------------------------------------------ void BControl::MessageReceived(BMessage *message) { - switch (message->what) + bool handled = false; + BMessage reply(B_REPLY); + + if (message->what == B_GET_PROPERTY || message->what == B_SET_PROPERTY) { - case B_CONTROL_INVOKED: - Invoke(); - break; + BPropertyInfo propInfo(prop_list); + BMessage specifier; + int32 index; + int32 form; + const char *property; - case B_GET_PROPERTY: - case B_SET_PROPERTY: + if (message->GetCurrentSpecifier(&index, &specifier, &form, &property) == B_OK) { - 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)) + if (strcmp(property, "Label") == 0) { - case B_ERROR: + if (message->what == B_GET_PROPERTY) { - 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; + handled = true; } - case 3: + else { 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; + + if (message->FindString("data", &label) == B_OK) + { + SetLabel(label); + reply.AddInt32("error", B_OK); + handled = true; + } + } + } + else if (strcmp(property, "Value") == 0) + { + if (message->what == B_GET_PROPERTY) + { + reply.AddInt32("result", fValue); + handled = true; + } + else + { + int32 value; + + if (message->FindInt32("data", &value) == B_OK) + { + SetValue(value); + reply.AddInt32("error", B_OK); + handled = true; + } + } + } + else if (strcmp(property, "Enabled") == 0) + { + if (message->what == B_GET_PROPERTY) + { + reply.AddBool("result", fEnabled); + handled = true; + } + else + { + bool enabled; + + if (message->FindBool("data", &enabled) == B_OK) + { + SetEnabled(enabled); + reply.AddInt32("error", B_OK); + handled = true; + } } } - - break; - } - default: - { - BView::MessageReceived(message); - break; } } + + if (handled) + message->SendReply(&reply); + else + BView::MessageReceived(message); } //------------------------------------------------------------------------------ void BControl::MakeFocus(bool focused) { + if (focused == IsFocus()) + return; + BView::MakeFocus(focused); if(Window()) @@ -294,23 +298,17 @@ void BControl::MakeFocus(bool focused) //------------------------------------------------------------------------------ void BControl::KeyDown(const char *bytes, int32 numBytes) { - if (numBytes == 1) + if (*bytes == B_ENTER || *bytes == B_SPACE) { - switch (bytes[0]) - { - case B_ENTER: - case B_SPACE: - if (Value()) - SetValue(B_CONTROL_OFF); - else - SetValue(B_CONTROL_ON); - - BInvoker::Invoke(); - break; + if (!fEnabled) + return; - default: - BView::KeyDown(bytes, numBytes); - } + if (Value()) + SetValue(B_CONTROL_OFF); + else + SetValue(B_CONTROL_ON); + + Invoke(); } else BView::KeyDown(bytes, numBytes); @@ -338,13 +336,16 @@ void BControl::DetachedFromWindow() //------------------------------------------------------------------------------ void BControl::SetLabel(const char *string) { - if (strcmp(fLabel, string) == 0) + if (fLabel && string && strcmp(fLabel, string) == 0) return; if (fLabel) free(fLabel); - fLabel = strdup(string); + if (string) + fLabel = strdup(string); + else + fLabel = NULL; Invalidate(); } @@ -399,8 +400,7 @@ bool BControl::IsEnabled() const //------------------------------------------------------------------------------ void BControl::GetPreferredSize(float *width, float *height) { - *width = 1.0f; - *height = 1.0f; + BView::GetPreferredSize(width, height); } //------------------------------------------------------------------------------ void BControl::ResizeToPreferred() @@ -410,22 +410,35 @@ void BControl::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(©); - } + bool notify = false; + uint32 kind = InvokeKind(¬ify); - return B_BAD_VALUE; + BMessage clone(kind); + status_t err = B_BAD_VALUE; + + if (!message && !notify) + message = Message(); + + if (!message) + { + if (!IsWatched()) + return err; + } + else + clone = *message; + + clone.AddInt64("when", (int64)system_time()); + clone.AddPointer("source", this); + clone.AddInt32("be:value", fValue); + clone.AddMessenger("be:sender", BMessenger(this)); + + if (message) + err = BInvoker::Invoke(&clone); + +// TODO: assynchronous messaging +// SendNotices(kind, &clone); + + return err; } //------------------------------------------------------------------------------ BHandler *BControl::ResolveSpecifier(BMessage *message, int32 index, @@ -433,47 +446,20 @@ BHandler *BControl::ResolveSpecifier(BMessage *message, int32 index, 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; + if (propInfo.FindMatch(message, 0, specifier, what, property) < B_OK) + return BView::ResolveSpecifier(message, index, specifier, what, + property); + else + return this; } //------------------------------------------------------------------------------ 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; + message->AddString("suites", "suite/vnd.Be-control"); BPropertyInfo prop_info(prop_list); - err = message->AddFlat("messages", &prop_info); - - if (err != B_OK) - return err; + message->AddFlat("messages", &prop_info); return BView::GetSupportedSuites(message); } @@ -490,7 +476,7 @@ void BControl::AllDetached() //------------------------------------------------------------------------------ status_t BControl::Perform(perform_code d, void *arg) { - return B_ERROR; + return BView::Perform(d, arg); } //------------------------------------------------------------------------------ bool BControl::IsFocusChanging() const @@ -526,7 +512,15 @@ BControl &BControl::operator=(const BControl &) //------------------------------------------------------------------------------ void BControl::InitData(BMessage *data) { + fLabel = NULL; + fValue = B_CONTROL_OFF; + fEnabled = true; + fFocusChanging = false; + fTracking = false; + fWantsNav = true; + if (data && data->HasString("_fname")) + SetFont(be_plain_font, B_FONT_FAMILY_AND_STYLE); } //------------------------------------------------------------------------------