2 * Copyright 2001-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
6 * Marc Flerackers, mflerackers@androme.be
7 * Ingo Weinhold, ingo_weinhold@gmx.de
11 // BControl is the base class for user-event handling objects.
18 #include <PropertyInfo.h>
21 #include <binary_compatibility/Interface.h>
25 static property_info sPropertyList
[] = {
28 { B_GET_PROPERTY
, B_SET_PROPERTY
},
29 { B_DIRECT_SPECIFIER
},
35 { B_GET_PROPERTY
, B_SET_PROPERTY
},
36 { B_DIRECT_SPECIFIER
},
42 { B_GET_PROPERTY
, B_SET_PROPERTY
},
43 { B_DIRECT_SPECIFIER
},
52 BControl::BControl(BRect frame
, const char* name
, const char* label
,
53 BMessage
* message
, uint32 resizingMode
, uint32 flags
)
55 BView(frame
, name
, resizingMode
, flags
)
64 BControl::BControl(const char* name
, const char* label
, BMessage
* message
,
84 BControl::BControl(BMessage
* data
)
91 if (data
->FindMessage("_msg", &message
) == B_OK
)
92 SetMessage(new BMessage(message
));
95 if (data
->FindString("_label", &label
) == B_OK
)
99 if (data
->FindInt32("_val", &value
) == B_OK
)
103 if (data
->FindBool("_disable", &toggle
) == B_OK
)
106 if (data
->FindBool("be:wants_nav", &toggle
) == B_OK
)
112 BControl::Instantiate(BMessage
* data
)
114 if (validate_instantiation(data
, "BControl"))
115 return new BControl(data
);
122 BControl::Archive(BMessage
* data
, bool deep
) const
124 status_t status
= BView::Archive(data
, deep
);
126 if (status
== B_OK
&& Message())
127 status
= data
->AddMessage("_msg", Message());
129 if (status
== B_OK
&& fLabel
)
130 status
= data
->AddString("_label", fLabel
);
132 if (status
== B_OK
&& fValue
!= B_CONTROL_OFF
)
133 status
= data
->AddInt32("_val", fValue
);
135 if (status
== B_OK
&& !fEnabled
)
136 status
= data
->AddBool("_disable", true);
143 BControl::WindowActivated(bool active
)
145 BView::WindowActivated(active
);
153 BControl::AttachedToWindow()
157 if (ViewColor() == B_TRANSPARENT_COLOR
158 || Parent() == NULL
) {
162 // Force view color as low color
163 if (Parent() != NULL
) {
164 float tint
= B_NO_TINT
;
165 color_which which
= ViewUIColor(&tint
);
166 if (which
!= B_NO_COLOR
)
167 SetLowUIColor(which
, tint
);
169 SetLowColor(ViewColor());
172 if (!Messenger().IsValid())
175 BView::AttachedToWindow();
180 BControl::DetachedFromWindow()
182 BView::DetachedFromWindow();
187 BControl::AllAttached()
189 BView::AllAttached();
194 BControl::AllDetached()
196 BView::AllDetached();
201 BControl::MessageReceived(BMessage
* message
)
203 if (message
->what
== B_GET_PROPERTY
|| message
->what
== B_SET_PROPERTY
) {
204 BMessage
reply(B_REPLY
);
205 bool handled
= false;
210 const char* property
;
211 if (message
->GetCurrentSpecifier(&index
, &specifier
, &form
, &property
) == B_OK
) {
212 if (strcmp(property
, "Label") == 0) {
213 if (message
->what
== B_GET_PROPERTY
) {
214 reply
.AddString("result", fLabel
);
219 if (message
->FindString("data", &label
) == B_OK
) {
221 reply
.AddInt32("error", B_OK
);
225 } else if (strcmp(property
, "Value") == 0) {
226 if (message
->what
== B_GET_PROPERTY
) {
227 reply
.AddInt32("result", fValue
);
232 if (message
->FindInt32("data", &value
) == B_OK
) {
234 reply
.AddInt32("error", B_OK
);
238 } else if (strcmp(property
, "Enabled") == 0) {
239 if (message
->what
== B_GET_PROPERTY
) {
240 reply
.AddBool("result", fEnabled
);
245 if (message
->FindBool("data", &enabled
) == B_OK
) {
247 reply
.AddInt32("error", B_OK
);
255 message
->SendReply(&reply
);
260 BView::MessageReceived(message
);
265 BControl::MakeFocus(bool focus
)
267 if (focus
== IsFocus())
270 BView::MakeFocus(focus
);
272 if (Window() != NULL
) {
273 fFocusChanging
= true;
274 Invalidate(Bounds());
276 fFocusChanging
= false;
282 BControl::KeyDown(const char* bytes
, int32 numBytes
)
284 if (*bytes
== B_ENTER
|| *bytes
== B_SPACE
) {
288 SetValue(Value() ? B_CONTROL_OFF
: B_CONTROL_ON
);
291 BView::KeyDown(bytes
, numBytes
);
296 BControl::MouseDown(BPoint where
)
298 BView::MouseDown(where
);
303 BControl::MouseUp(BPoint where
)
305 BView::MouseUp(where
);
310 BControl::MouseMoved(BPoint where
, uint32 code
, const BMessage
* dragMessage
)
312 BView::MouseMoved(where
, code
, dragMessage
);
317 BControl::SetLabel(const char* label
)
319 if (label
!= NULL
&& !label
[0])
322 // Has the label been changed?
323 if ((fLabel
&& label
&& !strcmp(fLabel
, label
))
324 || ((fLabel
== NULL
|| !fLabel
[0]) && label
== NULL
))
328 fLabel
= label
? strdup(label
) : NULL
;
336 BControl::Label() const
343 BControl::SetValue(int32 value
)
354 BControl::SetValueNoUpdate(int32 value
)
361 BControl::Value() const
368 BControl::SetEnabled(bool enabled
)
370 if (fEnabled
== enabled
)
375 if (fEnabled
&& fWantsNav
)
376 SetFlags(Flags() | B_NAVIGABLE
);
377 else if (!fEnabled
&& (Flags() & B_NAVIGABLE
)) {
379 SetFlags(Flags() & ~B_NAVIGABLE
);
384 Invalidate(Bounds());
391 BControl::IsEnabled() const
398 BControl::GetPreferredSize(float* _width
, float* _height
)
400 BView::GetPreferredSize(_width
, _height
);
405 BControl::ResizeToPreferred()
407 BView::ResizeToPreferred();
412 BControl::Invoke(BMessage
* message
)
415 uint32 kind
= InvokeKind(¬ify
);
417 if (!message
&& !notify
)
420 BMessage
clone(kind
);
428 clone
.AddInt64("when", (int64
)system_time());
429 clone
.AddPointer("source", this);
430 clone
.AddInt32("be:value", fValue
);
431 clone
.AddMessenger("be:sender", BMessenger(this));
433 // ToDo: is this correct? If message == NULL (even if IsWatched()), we always return B_BAD_VALUE
436 err
= BInvoker::Invoke(&clone
);
440 // TODO: asynchronous messaging
441 SendNotices(kind
, &clone
);
448 BControl::ResolveSpecifier(BMessage
* message
, int32 index
,
449 BMessage
* specifier
, int32 what
, const char* property
)
451 BPropertyInfo
propInfo(sPropertyList
);
453 if (propInfo
.FindMatch(message
, 0, specifier
, what
, property
) >= B_OK
)
456 return BView::ResolveSpecifier(message
, index
, specifier
, what
,
462 BControl::GetSupportedSuites(BMessage
* message
)
464 message
->AddString("suites", "suite/vnd.Be-control");
466 BPropertyInfo
propInfo(sPropertyList
);
467 message
->AddFlat("messages", &propInfo
);
469 return BView::GetSupportedSuites(message
);
474 BControl::Perform(perform_code code
, void* _data
)
477 case PERFORM_CODE_MIN_SIZE
:
478 ((perform_data_min_size
*)_data
)->return_value
479 = BControl::MinSize();
481 case PERFORM_CODE_MAX_SIZE
:
482 ((perform_data_max_size
*)_data
)->return_value
483 = BControl::MaxSize();
485 case PERFORM_CODE_PREFERRED_SIZE
:
486 ((perform_data_preferred_size
*)_data
)->return_value
487 = BControl::PreferredSize();
489 case PERFORM_CODE_LAYOUT_ALIGNMENT
:
490 ((perform_data_layout_alignment
*)_data
)->return_value
491 = BControl::LayoutAlignment();
493 case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH
:
494 ((perform_data_has_height_for_width
*)_data
)->return_value
495 = BControl::HasHeightForWidth();
497 case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH
:
499 perform_data_get_height_for_width
* data
500 = (perform_data_get_height_for_width
*)_data
;
501 BControl::GetHeightForWidth(data
->width
, &data
->min
, &data
->max
,
505 case PERFORM_CODE_SET_LAYOUT
:
507 perform_data_set_layout
* data
= (perform_data_set_layout
*)_data
;
508 BControl::SetLayout(data
->layout
);
511 case PERFORM_CODE_LAYOUT_INVALIDATED
:
513 perform_data_layout_invalidated
* data
514 = (perform_data_layout_invalidated
*)_data
;
515 BControl::LayoutInvalidated(data
->descendants
);
518 case PERFORM_CODE_DO_LAYOUT
:
520 BControl::DoLayout();
523 case PERFORM_CODE_SET_ICON
:
525 perform_data_set_icon
* data
= (perform_data_set_icon
*)_data
;
526 return BControl::SetIcon(data
->icon
, data
->flags
);
530 return BView::Perform(code
, _data
);
535 BControl::SetIcon(const BBitmap
* bitmap
, uint32 flags
)
537 status_t error
= BIcon::UpdateIcon(bitmap
, flags
, fIcon
);
549 BControl::SetIconBitmap(const BBitmap
* bitmap
, uint32 which
, uint32 flags
)
551 status_t error
= BIcon::SetIconBitmap(bitmap
, which
, flags
, fIcon
);
563 BControl::IconBitmap(uint32 which
) const
565 return fIcon
!= NULL
? fIcon
->Bitmap(which
) : NULL
;
570 BControl::IsFocusChanging() const
572 return fFocusChanging
;
577 BControl::IsTracking() const
584 BControl::SetTracking(bool state
)
591 B_IF_GCC_2(_ReservedControl1__8BControl
, _ZN8BControl17_ReservedControl1Ev
)(
592 BControl
* control
, const BBitmap
* icon
, uint32 flags
)
595 perform_data_set_icon data
;
598 return control
->Perform(PERFORM_CODE_SET_ICON
, &data
);
602 void BControl::_ReservedControl2() {}
603 void BControl::_ReservedControl3() {}
604 void BControl::_ReservedControl4() {}
608 BControl::operator=(const BControl
&)
615 BControl::InitData(BMessage
* data
)
617 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
618 SetLowUIColor(ViewUIColor());
621 SetLabel(B_EMPTY_STRING
);
622 fValue
= B_CONTROL_OFF
;
624 fFocusChanging
= false;
626 fWantsNav
= Flags() & B_NAVIGABLE
;
629 if (data
&& data
->HasString("_fname"))
630 SetFont(be_plain_font
, B_FONT_FAMILY_AND_STYLE
);