2 * Copyright 2001-2013, 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
},
51 BControl::BControl(BRect frame
, const char* name
, const char* label
,
52 BMessage
* message
, uint32 resizingMode
, uint32 flags
)
54 BView(frame
, name
, resizingMode
, flags
)
63 BControl::BControl(const char* name
, const char* label
, BMessage
* message
,
83 BControl::BControl(BMessage
* data
)
90 if (data
->FindMessage("_msg", &message
) == B_OK
)
91 SetMessage(new BMessage(message
));
94 if (data
->FindString("_label", &label
) == B_OK
)
98 if (data
->FindInt32("_val", &value
) == B_OK
)
102 if (data
->FindBool("_disable", &toggle
) == B_OK
)
105 if (data
->FindBool("be:wants_nav", &toggle
) == B_OK
)
111 BControl::Instantiate(BMessage
* data
)
113 if (validate_instantiation(data
, "BControl"))
114 return new BControl(data
);
121 BControl::Archive(BMessage
* data
, bool deep
) const
123 status_t status
= BView::Archive(data
, deep
);
125 if (status
== B_OK
&& Message())
126 status
= data
->AddMessage("_msg", Message());
128 if (status
== B_OK
&& fLabel
)
129 status
= data
->AddString("_label", fLabel
);
131 if (status
== B_OK
&& fValue
!= B_CONTROL_OFF
)
132 status
= data
->AddInt32("_val", fValue
);
134 if (status
== B_OK
&& !fEnabled
)
135 status
= data
->AddBool("_disable", true);
142 BControl::WindowActivated(bool active
)
144 BView::WindowActivated(active
);
152 BControl::AttachedToWindow()
156 BView
* parent
= Parent();
157 if (parent
!= NULL
) {
158 // inherit the color from parent
159 color
= parent
->ViewColor();
160 if (color
== B_TRANSPARENT_COLOR
)
161 color
= ui_color(B_PANEL_BACKGROUND_COLOR
);
163 color
= ui_color(B_PANEL_BACKGROUND_COLOR
);
168 if (!Messenger().IsValid())
171 BView::AttachedToWindow();
176 BControl::DetachedFromWindow()
178 BView::DetachedFromWindow();
183 BControl::AllAttached()
185 BView::AllAttached();
190 BControl::AllDetached()
192 BView::AllDetached();
197 BControl::MessageReceived(BMessage
* message
)
199 if (message
->what
== B_GET_PROPERTY
|| message
->what
== B_SET_PROPERTY
) {
200 BMessage
reply(B_REPLY
);
201 bool handled
= false;
206 const char* property
;
207 if (message
->GetCurrentSpecifier(&index
, &specifier
, &form
, &property
) == B_OK
) {
208 if (strcmp(property
, "Label") == 0) {
209 if (message
->what
== B_GET_PROPERTY
) {
210 reply
.AddString("result", fLabel
);
215 if (message
->FindString("data", &label
) == B_OK
) {
217 reply
.AddInt32("error", B_OK
);
221 } else if (strcmp(property
, "Value") == 0) {
222 if (message
->what
== B_GET_PROPERTY
) {
223 reply
.AddInt32("result", fValue
);
228 if (message
->FindInt32("data", &value
) == B_OK
) {
230 reply
.AddInt32("error", B_OK
);
234 } else if (strcmp(property
, "Enabled") == 0) {
235 if (message
->what
== B_GET_PROPERTY
) {
236 reply
.AddBool("result", fEnabled
);
241 if (message
->FindBool("data", &enabled
) == B_OK
) {
243 reply
.AddInt32("error", B_OK
);
251 message
->SendReply(&reply
);
256 BView::MessageReceived(message
);
261 BControl::MakeFocus(bool focus
)
263 if (focus
== IsFocus())
266 BView::MakeFocus(focus
);
268 if (Window() != NULL
) {
269 fFocusChanging
= true;
270 Invalidate(Bounds());
272 fFocusChanging
= false;
278 BControl::KeyDown(const char* bytes
, int32 numBytes
)
280 if (*bytes
== B_ENTER
|| *bytes
== B_SPACE
) {
284 SetValue(Value() ? B_CONTROL_OFF
: B_CONTROL_ON
);
287 BView::KeyDown(bytes
, numBytes
);
292 BControl::MouseDown(BPoint where
)
294 BView::MouseDown(where
);
299 BControl::MouseUp(BPoint where
)
301 BView::MouseUp(where
);
306 BControl::MouseMoved(BPoint where
, uint32 code
, const BMessage
* dragMessage
)
308 BView::MouseMoved(where
, code
, dragMessage
);
313 BControl::SetLabel(const char* label
)
315 if (label
!= NULL
&& !label
[0])
318 // Has the label been changed?
319 if ((fLabel
&& label
&& !strcmp(fLabel
, label
))
320 || ((fLabel
== NULL
|| !fLabel
[0]) && label
== NULL
))
324 fLabel
= label
? strdup(label
) : NULL
;
332 BControl::Label() const
339 BControl::SetValue(int32 value
)
350 BControl::SetValueNoUpdate(int32 value
)
357 BControl::Value() const
364 BControl::SetEnabled(bool enabled
)
366 if (fEnabled
== enabled
)
371 if (fEnabled
&& fWantsNav
)
372 SetFlags(Flags() | B_NAVIGABLE
);
373 else if (!fEnabled
&& (Flags() & B_NAVIGABLE
)) {
375 SetFlags(Flags() & ~B_NAVIGABLE
);
380 Invalidate(Bounds());
387 BControl::IsEnabled() const
394 BControl::GetPreferredSize(float* _width
, float* _height
)
396 BView::GetPreferredSize(_width
, _height
);
401 BControl::ResizeToPreferred()
403 BView::ResizeToPreferred();
408 BControl::Invoke(BMessage
* message
)
411 uint32 kind
= InvokeKind(¬ify
);
413 if (!message
&& !notify
)
416 BMessage
clone(kind
);
424 clone
.AddInt64("when", (int64
)system_time());
425 clone
.AddPointer("source", this);
426 clone
.AddInt32("be:value", fValue
);
427 clone
.AddMessenger("be:sender", BMessenger(this));
429 // ToDo: is this correct? If message == NULL (even if IsWatched()), we always return B_BAD_VALUE
432 err
= BInvoker::Invoke(&clone
);
436 // TODO: asynchronous messaging
437 SendNotices(kind
, &clone
);
444 BControl::ResolveSpecifier(BMessage
* message
, int32 index
,
445 BMessage
* specifier
, int32 what
, const char* property
)
447 BPropertyInfo
propInfo(sPropertyList
);
449 if (propInfo
.FindMatch(message
, 0, specifier
, what
, property
) >= B_OK
)
452 return BView::ResolveSpecifier(message
, index
, specifier
, what
,
458 BControl::GetSupportedSuites(BMessage
* message
)
460 message
->AddString("suites", "suite/vnd.Be-control");
462 BPropertyInfo
propInfo(sPropertyList
);
463 message
->AddFlat("messages", &propInfo
);
465 return BView::GetSupportedSuites(message
);
470 BControl::Perform(perform_code code
, void* _data
)
473 case PERFORM_CODE_MIN_SIZE
:
474 ((perform_data_min_size
*)_data
)->return_value
475 = BControl::MinSize();
477 case PERFORM_CODE_MAX_SIZE
:
478 ((perform_data_max_size
*)_data
)->return_value
479 = BControl::MaxSize();
481 case PERFORM_CODE_PREFERRED_SIZE
:
482 ((perform_data_preferred_size
*)_data
)->return_value
483 = BControl::PreferredSize();
485 case PERFORM_CODE_LAYOUT_ALIGNMENT
:
486 ((perform_data_layout_alignment
*)_data
)->return_value
487 = BControl::LayoutAlignment();
489 case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH
:
490 ((perform_data_has_height_for_width
*)_data
)->return_value
491 = BControl::HasHeightForWidth();
493 case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH
:
495 perform_data_get_height_for_width
* data
496 = (perform_data_get_height_for_width
*)_data
;
497 BControl::GetHeightForWidth(data
->width
, &data
->min
, &data
->max
,
501 case PERFORM_CODE_SET_LAYOUT
:
503 perform_data_set_layout
* data
= (perform_data_set_layout
*)_data
;
504 BControl::SetLayout(data
->layout
);
507 case PERFORM_CODE_LAYOUT_INVALIDATED
:
509 perform_data_layout_invalidated
* data
510 = (perform_data_layout_invalidated
*)_data
;
511 BControl::LayoutInvalidated(data
->descendants
);
514 case PERFORM_CODE_DO_LAYOUT
:
516 BControl::DoLayout();
519 case PERFORM_CODE_SET_ICON
:
521 perform_data_set_icon
* data
= (perform_data_set_icon
*)_data
;
522 return BControl::SetIcon(data
->icon
, data
->flags
);
526 return BView::Perform(code
, _data
);
531 BControl::SetIcon(const BBitmap
* bitmap
, uint32 flags
)
533 status_t error
= BIcon::UpdateIcon(bitmap
, flags
, fIcon
);
545 BControl::SetIconBitmap(const BBitmap
* bitmap
, uint32 which
, uint32 flags
)
547 status_t error
= BIcon::SetIconBitmap(bitmap
, which
, flags
, fIcon
);
559 BControl::IconBitmap(uint32 which
) const
561 return fIcon
!= NULL
? fIcon
->Bitmap(which
) : NULL
;
566 BControl::IsFocusChanging() const
568 return fFocusChanging
;
573 BControl::IsTracking() const
580 BControl::SetTracking(bool state
)
587 B_IF_GCC_2(_ReservedControl1__8BControl
, _ZN8BControl17_ReservedControl1Ev
)(
588 BControl
* control
, const BBitmap
* icon
, uint32 flags
)
591 perform_data_set_icon data
;
594 return control
->Perform(PERFORM_CODE_SET_ICON
, &data
);
598 void BControl::_ReservedControl2() {}
599 void BControl::_ReservedControl3() {}
600 void BControl::_ReservedControl4() {}
604 BControl::operator=(const BControl
&)
611 BControl::InitData(BMessage
* data
)
614 SetLabel(B_EMPTY_STRING
);
615 fValue
= B_CONTROL_OFF
;
617 fFocusChanging
= false;
619 fWantsNav
= Flags() & B_NAVIGABLE
;
622 if (data
&& data
->HasString("_fname"))
623 SetFont(be_plain_font
, B_FONT_FAMILY_AND_STYLE
);