2 * Copyright 2001-2017 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Stephan Aßmus, superstippi@gmx.de
7 * Axel Dörfler, axeld@pinc-software.de
8 * Adrian Oanca, adioanca@cotty.iren.ro
9 * Ingo Weinhold. ingo_weinhold@gmx.de
10 * Julian Harnath, julian.harnath@rwth-aachen.de
11 * Joseph Groover, looncraz@looncraz.net
23 #include <Application.h>
28 #include <GradientLinear.h>
29 #include <GradientRadial.h>
30 #include <GradientRadialFocus.h>
31 #include <GradientDiamond.h>
32 #include <GradientConic.h>
33 #include <InterfaceDefs.h>
35 #include <LayoutContext.h>
36 #include <LayoutUtils.h>
39 #include <MessageQueue.h>
40 #include <ObjectList.h>
44 #include <PropertyInfo.h>
46 #include <ScrollBar.h>
53 #include <AppServerLink.h>
54 #include <binary_compatibility/Interface.h>
55 #include <binary_compatibility/Support.h>
56 #include <MessagePrivate.h>
57 #include <MessageUtils.h>
59 #include <ServerProtocol.h>
60 #include <ServerProtocolStructs.h>
61 #include <ShapePrivate.h>
63 #include <ToolTipManager.h>
64 #include <TokenSpace.h>
65 #include <ViewPrivate.h>
72 # define STRACE(x) printf x
73 # define BVTRACE _PrintToStream()
80 static property_info sViewPropInfo
[] = {
81 { "Frame", { B_GET_PROPERTY
, B_SET_PROPERTY
},
82 { B_DIRECT_SPECIFIER
, 0 }, "The view's frame rectangle.", 0,
85 { "Hidden", { B_GET_PROPERTY
, B_SET_PROPERTY
},
86 { B_DIRECT_SPECIFIER
, 0 }, "Whether or not the view is hidden.",
90 { B_DIRECT_SPECIFIER
, 0 }, "Directs the scripting message to the "
93 { "View", { B_COUNT_PROPERTIES
, 0 },
94 { B_DIRECT_SPECIFIER
, 0 }, "Returns the number of child views.", 0,
98 { B_INDEX_SPECIFIER
, B_REVERSE_INDEX_SPECIFIER
, B_NAME_SPECIFIER
, 0 },
99 "Directs the scripting message to the specified view.", 0
110 get_uint32_color(rgb_color color
)
112 return B_BENDIAN_TO_HOST_INT32(*(uint32
*)&color
);
113 // rgb_color is always in rgba format, no matter what endian;
114 // we always return the int32 value in host endian.
118 static inline rgb_color
119 get_rgb_color(uint32 value
)
121 value
= B_HOST_TO_BENDIAN_INT32(value
);
122 return *(rgb_color
*)&value
;
131 ViewState::ViewState()
133 pen_location
.Set(0, 0);
136 // NOTE: the clipping_region is empty
137 // on construction but it is not used yet,
138 // we avoid having to keep track of it via
140 clipping_region_used
= false;
142 high_color
= (rgb_color
){ 0, 0, 0, 255 };
143 low_color
= (rgb_color
){ 255, 255, 255, 255 };
144 view_color
= low_color
;
145 which_view_color
= B_NO_COLOR
;
146 which_view_color_tint
= B_NO_TINT
;
148 which_high_color
= B_NO_COLOR
;
149 which_high_color_tint
= B_NO_TINT
;
151 which_low_color
= B_NO_COLOR
;
152 which_low_color_tint
= B_NO_TINT
;
154 pattern
= B_SOLID_HIGH
;
155 drawing_mode
= B_OP_COPY
;
159 line_join
= B_MITER_JOIN
;
160 line_cap
= B_BUTT_CAP
;
161 miter_limit
= B_DEFAULT_MITER_LIMIT
;
162 fill_rule
= B_NONZERO
;
164 alpha_source_mode
= B_PIXEL_ALPHA
;
165 alpha_function_mode
= B_ALPHA_OVERLAY
;
169 font
= *be_plain_font
;
170 font_flags
= font
.Flags();
171 font_aliasing
= false;
173 // We only keep the B_VIEW_CLIP_REGION_BIT flag invalidated,
174 // because we should get the clipping region from app_server.
175 // The other flags do not need to be included because the data they
176 // represent is already in sync with app_server - app_server uses the
177 // same init (default) values.
178 valid_flags
= ~B_VIEW_CLIP_REGION_BIT
;
180 archiving_flags
= B_VIEW_FRAME_BIT
| B_VIEW_RESIZE_BIT
;
185 ViewState::UpdateServerFontState(BPrivate::PortLink
&link
)
187 link
.StartMessage(AS_VIEW_SET_FONT_STATE
);
188 link
.Attach
<uint16
>(font_flags
);
191 if (font_flags
& B_FONT_FAMILY_AND_STYLE
)
192 link
.Attach
<uint32
>(font
.FamilyAndStyle());
194 if (font_flags
& B_FONT_SIZE
)
195 link
.Attach
<float>(font
.Size());
197 if (font_flags
& B_FONT_SHEAR
)
198 link
.Attach
<float>(font
.Shear());
200 if (font_flags
& B_FONT_ROTATION
)
201 link
.Attach
<float>(font
.Rotation());
203 if (font_flags
& B_FONT_FALSE_BOLD_WIDTH
)
204 link
.Attach
<float>(font
.FalseBoldWidth());
206 if (font_flags
& B_FONT_SPACING
)
207 link
.Attach
<uint8
>(font
.Spacing());
209 if (font_flags
& B_FONT_ENCODING
)
210 link
.Attach
<uint8
>(font
.Encoding());
212 if (font_flags
& B_FONT_FACE
)
213 link
.Attach
<uint16
>(font
.Face());
215 if (font_flags
& B_FONT_FLAGS
)
216 link
.Attach
<uint32
>(font
.Flags());
221 ViewState::UpdateServerState(BPrivate::PortLink
&link
)
223 UpdateServerFontState(link
);
225 link
.StartMessage(AS_VIEW_SET_STATE
);
227 ViewSetStateInfo info
;
228 info
.penLocation
= pen_location
;
229 info
.penSize
= pen_size
;
230 info
.highColor
= high_color
;
231 info
.lowColor
= low_color
;
232 info
.whichHighColor
= which_high_color
;
233 info
.whichLowColor
= which_low_color
;
234 info
.whichHighColorTint
= which_high_color_tint
;
235 info
.whichLowColorTint
= which_low_color_tint
;
236 info
.pattern
= pattern
;
237 info
.drawingMode
= drawing_mode
;
238 info
.origin
= origin
;
240 info
.transform
= transform
;
241 info
.lineJoin
= line_join
;
242 info
.lineCap
= line_cap
;
243 info
.miterLimit
= miter_limit
;
244 info
.fillRule
= fill_rule
;
245 info
.alphaSourceMode
= alpha_source_mode
;
246 info
.alphaFunctionMode
= alpha_function_mode
;
247 info
.fontAntialiasing
= font_aliasing
;
248 link
.Attach
<ViewSetStateInfo
>(info
);
250 // we send the 'local' clipping region... if we have one...
251 // TODO: Could be optimized, but is low prio, since most views won't
252 // have a custom clipping region.
253 if (clipping_region_used
) {
254 int32 count
= clipping_region
.CountRects();
255 link
.Attach
<int32
>(count
);
256 for (int32 i
= 0; i
< count
; i
++)
257 link
.Attach
<BRect
>(clipping_region
.RectAt(i
));
259 // no clipping region
260 link
.Attach
<int32
>(-1);
263 // Although we might have a 'local' clipping region, when we call
264 // BView::GetClippingRegion() we ask for the 'global' one and it
265 // is kept on server, so we must invalidate B_VIEW_CLIP_REGION_BIT flag
267 valid_flags
= ~B_VIEW_CLIP_REGION_BIT
;
272 ViewState::UpdateFrom(BPrivate::PortLink
&link
)
274 link
.StartMessage(AS_VIEW_GET_STATE
);
277 if (link
.FlushWithReply(code
) != B_OK
281 ViewGetStateInfo info
;
282 link
.Read
<ViewGetStateInfo
>(&info
);
284 // set view's font state
285 font_flags
= B_FONT_ALL
;
286 font
.SetFamilyAndStyle(info
.fontID
);
287 font
.SetSize(info
.fontSize
);
288 font
.SetShear(info
.fontShear
);
289 font
.SetRotation(info
.fontRotation
);
290 font
.SetFalseBoldWidth(info
.fontFalseBoldWidth
);
291 font
.SetSpacing(info
.fontSpacing
);
292 font
.SetEncoding(info
.fontEncoding
);
293 font
.SetFace(info
.fontFace
);
294 font
.SetFlags(info
.fontFlags
);
297 pen_location
= info
.viewStateInfo
.penLocation
;
298 pen_size
= info
.viewStateInfo
.penSize
;
299 high_color
= info
.viewStateInfo
.highColor
;
300 low_color
= info
.viewStateInfo
.lowColor
;
301 pattern
= info
.viewStateInfo
.pattern
;
302 drawing_mode
= info
.viewStateInfo
.drawingMode
;
303 origin
= info
.viewStateInfo
.origin
;
304 scale
= info
.viewStateInfo
.scale
;
305 transform
= info
.viewStateInfo
.transform
;
306 line_join
= info
.viewStateInfo
.lineJoin
;
307 line_cap
= info
.viewStateInfo
.lineCap
;
308 miter_limit
= info
.viewStateInfo
.miterLimit
;
309 fill_rule
= info
.viewStateInfo
.fillRule
;
310 alpha_source_mode
= info
.viewStateInfo
.alphaSourceMode
;
311 alpha_function_mode
= info
.viewStateInfo
.alphaFunctionMode
;
312 font_aliasing
= info
.viewStateInfo
.fontAntialiasing
;
314 // read the user clipping
315 // (that's NOT the current View visible clipping but the additional
316 // user specified clipping!)
317 int32 clippingRectCount
;
318 link
.Read
<int32
>(&clippingRectCount
);
319 if (clippingRectCount
>= 0) {
320 clipping_region
.MakeEmpty();
321 for (int32 i
= 0; i
< clippingRectCount
; i
++) {
323 link
.Read
<BRect
>(&rect
);
324 clipping_region
.Include(rect
);
327 // no user clipping used
328 clipping_region_used
= false;
331 valid_flags
= ~B_VIEW_CLIP_REGION_BIT
;
334 } // namespace BPrivate
340 // archiving constants
342 const char* const kSizesField
= "BView:sizes";
343 // kSizesField = {min, max, pref}
344 const char* const kAlignmentField
= "BView:alignment";
345 const char* const kLayoutField
= "BView:layout";
349 struct BView::LayoutData
{
356 fLayoutInvalidationDisabled(0),
358 fLayoutContext(NULL
),
359 fLayoutItems(5, false),
360 fLayoutValid(true), // TODO: Rethink these initial values!
361 fMinMaxValid(true), //
362 fLayoutInProgress(false),
368 AddDataToArchive(BMessage
* archive
)
370 status_t err
= archive
->AddSize(kSizesField
, fMinSize
);
373 err
= archive
->AddSize(kSizesField
, fMaxSize
);
376 err
= archive
->AddSize(kSizesField
, fPreferredSize
);
379 err
= archive
->AddAlignment(kAlignmentField
, fAlignment
);
385 PopulateFromArchive(BMessage
* archive
)
387 archive
->FindSize(kSizesField
, 0, &fMinSize
);
388 archive
->FindSize(kSizesField
, 1, &fMaxSize
);
389 archive
->FindSize(kSizesField
, 2, &fPreferredSize
);
390 archive
->FindAlignment(kAlignmentField
, &fAlignment
);
395 BSize fPreferredSize
;
396 BAlignment fAlignment
;
397 int fLayoutInvalidationDisabled
;
399 BLayoutContext
* fLayoutContext
;
400 BObjectList
<BLayoutItem
> fLayoutItems
;
403 bool fLayoutInProgress
;
408 BView::BView(const char* name
, uint32 flags
, BLayout
* layout
)
412 _InitData(BRect(0, 0, -1, -1), name
, B_FOLLOW_NONE
,
413 flags
| B_SUPPORTS_LAYOUT
);
418 BView::BView(BRect frame
, const char* name
, uint32 resizingMode
, uint32 flags
)
422 _InitData(frame
, name
, resizingMode
, flags
);
426 BView::BView(BMessage
* archive
)
428 BHandler(BUnarchiver::PrepareArchive(archive
))
430 BUnarchiver
unarchiver(archive
);
432 debugger("BView cannot be constructed from a NULL archive.");
435 archive
->FindRect("_frame", &frame
);
438 if (archive
->FindInt32("_resize_mode", (int32
*)&resizingMode
) != B_OK
)
442 if (archive
->FindInt32("_flags", (int32
*)&flags
) != B_OK
)
445 _InitData(frame
, Name(), resizingMode
, flags
);
449 if (archive
->FindString("_fname", 0, (const char**)&family
) == B_OK
450 && archive
->FindString("_fname", 1, (const char**)&style
) == B_OK
) {
452 font
.SetFamilyAndStyle(family
, style
);
455 if (archive
->FindFloat("_fflt", 0, &size
) == B_OK
)
459 if (archive
->FindFloat("_fflt", 1, &shear
) == B_OK
460 && shear
>= 45.0 && shear
<= 135.0)
461 font
.SetShear(shear
);
464 if (archive
->FindFloat("_fflt", 2, &rotation
) == B_OK
465 && rotation
>=0 && rotation
<= 360)
466 font
.SetRotation(rotation
);
468 SetFont(&font
, B_FONT_FAMILY_AND_STYLE
| B_FONT_SIZE
469 | B_FONT_SHEAR
| B_FONT_ROTATION
);
473 if (archive
->FindInt32("_color", 0, &color
) == B_OK
)
474 SetHighColor(get_rgb_color(color
));
475 if (archive
->FindInt32("_color", 1, &color
) == B_OK
)
476 SetLowColor(get_rgb_color(color
));
477 if (archive
->FindInt32("_color", 2, &color
) == B_OK
)
478 SetViewColor(get_rgb_color(color
));
480 float tint
= B_NO_TINT
;
481 if (archive
->FindInt32("_uicolor", 0, &color
) == B_OK
482 && color
!= B_NO_COLOR
) {
483 if (archive
->FindFloat("_uitint", 0, &tint
) != B_OK
)
486 SetHighUIColor((color_which
)color
, tint
);
488 if (archive
->FindInt32("_uicolor", 1, &color
) == B_OK
489 && color
!= B_NO_COLOR
) {
490 if (archive
->FindFloat("_uitint", 1, &tint
) != B_OK
)
493 SetLowUIColor((color_which
)color
, tint
);
495 if (archive
->FindInt32("_uicolor", 2, &color
) == B_OK
496 && color
!= B_NO_COLOR
) {
497 if (archive
->FindFloat("_uitint", 2, &tint
) != B_OK
)
500 SetViewUIColor((color_which
)color
, tint
);
505 if (archive
->FindInt32("_evmask", 0, (int32
*)&evMask
) == B_OK
506 && archive
->FindInt32("_evmask", 1, (int32
*)&options
) == B_OK
)
507 SetEventMask(evMask
, options
);
510 if (archive
->FindPoint("_origin", &origin
) == B_OK
)
514 if (archive
->FindFloat("_scale", &scale
) == B_OK
)
517 BAffineTransform transform
;
518 if (archive
->FindFlat("_transform", &transform
) == B_OK
)
519 SetTransform(transform
);
522 if (archive
->FindFloat("_psize", &penSize
) == B_OK
)
526 if (archive
->FindPoint("_ploc", &penLocation
) == B_OK
)
527 MovePenTo(penLocation
);
532 if (archive
->FindInt16("_lmcapjoin", 0, &lineCap
) == B_OK
533 && archive
->FindInt16("_lmcapjoin", 1, &lineJoin
) == B_OK
534 && archive
->FindFloat("_lmmiter", &lineMiter
) == B_OK
)
535 SetLineMode((cap_mode
)lineCap
, (join_mode
)lineJoin
, lineMiter
);
538 if (archive
->FindInt16("_fillrule", &fillRule
) == B_OK
)
539 SetFillRule(fillRule
);
543 if (archive
->FindInt16("_blend", 0, &alphaBlend
) == B_OK
544 && archive
->FindInt16("_blend", 1, &modeBlend
) == B_OK
)
545 SetBlendingMode( (source_alpha
)alphaBlend
, (alpha_function
)modeBlend
);
548 if (archive
->FindInt32("_dmod", (int32
*)&drawingMode
) == B_OK
)
549 SetDrawingMode((drawing_mode
)drawingMode
);
551 fLayoutData
->PopulateFromArchive(archive
);
553 if (archive
->FindInt16("_show", &fShowLevel
) != B_OK
)
556 if (BUnarchiver::IsArchiveManaged(archive
)) {
558 while (unarchiver
.EnsureUnarchived("_views", i
++) == B_OK
)
560 unarchiver
.EnsureUnarchived(kLayoutField
);
564 for (int32 i
= 0; archive
->FindMessage("_views", i
, &msg
) == B_OK
;
566 BArchivable
* object
= instantiate_object(&msg
);
567 if (BView
* child
= dynamic_cast<BView
*>(object
))
575 BView::Instantiate(BMessage
* data
)
577 if (!validate_instantiation(data
, "BView"))
580 return new(std::nothrow
) BView(data
);
585 BView::Archive(BMessage
* data
, bool deep
) const
587 BArchiver
archiver(data
);
588 status_t ret
= BHandler::Archive(data
, deep
);
593 if ((fState
->archiving_flags
& B_VIEW_FRAME_BIT
) != 0)
594 ret
= data
->AddRect("_frame", Bounds().OffsetToCopy(fParentOffset
));
597 ret
= data
->AddInt32("_resize_mode", ResizingMode());
600 ret
= data
->AddInt32("_flags", Flags());
602 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_EVENT_MASK_BIT
) != 0) {
603 ret
= data
->AddInt32("_evmask", fEventMask
);
605 ret
= data
->AddInt32("_evmask", fEventOptions
);
608 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_FONT_BIT
) != 0) {
614 font
.GetFamilyAndStyle(&family
, &style
);
615 ret
= data
->AddString("_fname", family
);
617 ret
= data
->AddString("_fname", style
);
619 ret
= data
->AddFloat("_fflt", font
.Size());
621 ret
= data
->AddFloat("_fflt", font
.Shear());
623 ret
= data
->AddFloat("_fflt", font
.Rotation());
628 ret
= data
->AddInt32("_color", get_uint32_color(HighColor()));
630 ret
= data
->AddInt32("_color", get_uint32_color(LowColor()));
632 ret
= data
->AddInt32("_color", get_uint32_color(ViewColor()));
635 ret
= data
->AddInt32("_uicolor", (int32
)HighUIColor());
637 ret
= data
->AddInt32("_uicolor", (int32
)LowUIColor());
639 ret
= data
->AddInt32("_uicolor", (int32
)ViewUIColor());
642 ret
= data
->AddFloat("_uitint", fState
->which_high_color_tint
);
644 ret
= data
->AddFloat("_uitint", fState
->which_low_color_tint
);
646 ret
= data
->AddFloat("_uitint", fState
->which_view_color_tint
);
648 // NOTE: we do not use this flag any more
650 // ret = data->AddInt32("_dbuf", 1);
653 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_ORIGIN_BIT
) != 0)
654 ret
= data
->AddPoint("_origin", Origin());
656 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_SCALE_BIT
) != 0)
657 ret
= data
->AddFloat("_scale", Scale());
659 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_TRANSFORM_BIT
) != 0) {
660 BAffineTransform transform
= Transform();
661 ret
= data
->AddFlat("_transform", &transform
);
664 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_PEN_SIZE_BIT
) != 0)
665 ret
= data
->AddFloat("_psize", PenSize());
667 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_PEN_LOCATION_BIT
) != 0)
668 ret
= data
->AddPoint("_ploc", PenLocation());
670 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_LINE_MODES_BIT
) != 0) {
671 ret
= data
->AddInt16("_lmcapjoin", (int16
)LineCapMode());
673 ret
= data
->AddInt16("_lmcapjoin", (int16
)LineJoinMode());
675 ret
= data
->AddFloat("_lmmiter", LineMiterLimit());
678 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_FILL_RULE_BIT
) != 0)
679 ret
= data
->AddInt16("_fillrule", (int16
)FillRule());
681 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_BLENDING_BIT
) != 0) {
682 source_alpha alphaSourceMode
;
683 alpha_function alphaFunctionMode
;
684 GetBlendingMode(&alphaSourceMode
, &alphaFunctionMode
);
686 ret
= data
->AddInt16("_blend", (int16
)alphaSourceMode
);
688 ret
= data
->AddInt16("_blend", (int16
)alphaFunctionMode
);
691 if (ret
== B_OK
&& (fState
->archiving_flags
& B_VIEW_DRAWING_MODE_BIT
) != 0)
692 ret
= data
->AddInt32("_dmod", DrawingMode());
695 ret
= fLayoutData
->AddDataToArchive(data
);
698 ret
= data
->AddInt16("_show", fShowLevel
);
700 if (deep
&& ret
== B_OK
) {
701 for (BView
* child
= fFirstChild
; child
!= NULL
&& ret
== B_OK
;
702 child
= child
->fNextSibling
)
703 ret
= archiver
.AddArchivable("_views", child
, deep
);
706 ret
= archiver
.AddArchivable(kLayoutField
, GetLayout(), deep
);
709 return archiver
.Finish(ret
);
714 BView::AllUnarchived(const BMessage
* from
)
716 BUnarchiver
unarchiver(from
);
720 from
->GetInfo("_views", NULL
, &count
);
722 for (int32 i
= 0; err
== B_OK
&& i
< count
; i
++) {
724 err
= unarchiver
.FindObject
<BView
>("_views", i
, child
);
726 err
= _AddChild(child
, NULL
) ? B_OK
: B_ERROR
;
730 BLayout
*& layout
= fLayoutData
->fLayout
;
731 err
= unarchiver
.FindObject(kLayoutField
, layout
);
732 if (err
== B_OK
&& layout
) {
733 fFlags
|= B_SUPPORTS_LAYOUT
;
734 fLayoutData
->fLayout
->SetOwner(this);
743 BView::AllArchived(BMessage
* into
) const
745 return BHandler::AllArchived(into
);
751 STRACE(("BView(%s)::~BView()\n", this->Name()));
753 if (fOwner
!= NULL
) {
754 debugger("Trying to delete a view that belongs to a window. "
755 "Call RemoveSelf first.");
758 // we also delete all our children
760 BView
* child
= fFirstChild
;
762 BView
* nextChild
= child
->fNextSibling
;
769 _RemoveLayoutItemsFromLayout(true);
775 if (fToolTip
!= NULL
)
776 fToolTip
->ReleaseReference();
778 if (fVerScroller
!= NULL
)
779 fVerScroller
->SetTarget((BView
*)NULL
);
780 if (fHorScroller
!= NULL
)
781 fHorScroller
->SetTarget((BView
*)NULL
);
791 BView::Bounds() const
796 return fState
->print_rect
;
803 BView::_ConvertToParent(BPoint
* point
, bool checkLock
) const
811 // - our scrolling offset
812 // + our bounds location within the parent
813 point
->x
+= -fBounds
.left
+ fParentOffset
.x
;
814 point
->y
+= -fBounds
.top
+ fParentOffset
.y
;
819 BView::ConvertToParent(BPoint
* point
) const
821 _ConvertToParent(point
, true);
826 BView::ConvertToParent(BPoint point
) const
828 ConvertToParent(&point
);
835 BView::_ConvertFromParent(BPoint
* point
, bool checkLock
) const
843 // - our bounds location within the parent
844 // + our scrolling offset
845 point
->x
+= -fParentOffset
.x
+ fBounds
.left
;
846 point
->y
+= -fParentOffset
.y
+ fBounds
.top
;
851 BView::ConvertFromParent(BPoint
* point
) const
853 _ConvertFromParent(point
, true);
858 BView::ConvertFromParent(BPoint point
) const
860 ConvertFromParent(&point
);
867 BView::ConvertToParent(BRect
* rect
) const
874 // - our scrolling offset
875 // + our bounds location within the parent
876 rect
->OffsetBy(-fBounds
.left
+ fParentOffset
.x
,
877 -fBounds
.top
+ fParentOffset
.y
);
882 BView::ConvertToParent(BRect rect
) const
884 ConvertToParent(&rect
);
891 BView::ConvertFromParent(BRect
* rect
) const
898 // - our bounds location within the parent
899 // + our scrolling offset
900 rect
->OffsetBy(-fParentOffset
.x
+ fBounds
.left
,
901 -fParentOffset
.y
+ fBounds
.top
);
906 BView::ConvertFromParent(BRect rect
) const
908 ConvertFromParent(&rect
);
915 BView::_ConvertToScreen(BPoint
* point
, bool checkLock
) const
919 fOwner
->ConvertToScreen(point
);
927 _ConvertToParent(point
, false);
928 fParent
->_ConvertToScreen(point
, false);
933 BView::ConvertToScreen(BPoint
* point
) const
935 _ConvertToScreen(point
, true);
940 BView::ConvertToScreen(BPoint point
) const
942 ConvertToScreen(&point
);
949 BView::_ConvertFromScreen(BPoint
* point
, bool checkLock
) const
953 fOwner
->ConvertFromScreen(point
);
961 _ConvertFromParent(point
, false);
962 fParent
->_ConvertFromScreen(point
, false);
967 BView::ConvertFromScreen(BPoint
* point
) const
969 _ConvertFromScreen(point
, true);
974 BView::ConvertFromScreen(BPoint point
) const
976 ConvertFromScreen(&point
);
983 BView::ConvertToScreen(BRect
* rect
) const
985 BPoint
offset(0.0, 0.0);
986 ConvertToScreen(&offset
);
987 rect
->OffsetBy(offset
);
992 BView::ConvertToScreen(BRect rect
) const
994 ConvertToScreen(&rect
);
1001 BView::ConvertFromScreen(BRect
* rect
) const
1003 BPoint
offset(0.0, 0.0);
1004 ConvertFromScreen(&offset
);
1005 rect
->OffsetBy(offset
);
1010 BView::ConvertFromScreen(BRect rect
) const
1012 ConvertFromScreen(&rect
);
1019 BView::Flags() const
1022 return fFlags
& ~_RESIZE_MASK_
;
1027 BView::SetFlags(uint32 flags
)
1029 if (Flags() == flags
)
1033 if (flags
& B_PULSE_NEEDED
) {
1035 if (fOwner
->fPulseRunner
== NULL
)
1036 fOwner
->SetPulseRate(fOwner
->PulseRate());
1039 uint32 changesFlags
= flags
^ fFlags
;
1040 if (changesFlags
& (B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
1041 | B_FRAME_EVENTS
| B_SUBPIXEL_PRECISE
)) {
1042 _CheckLockAndSwitchCurrent();
1044 fOwner
->fLink
->StartMessage(AS_VIEW_SET_FLAGS
);
1045 fOwner
->fLink
->Attach
<uint32
>(flags
);
1046 fOwner
->fLink
->Flush();
1050 /* Some useful info:
1051 fFlags is a unsigned long (32 bits)
1052 * bits 1-16 are used for BView's flags
1053 * bits 17-32 are used for BView' resize mask
1054 * _RESIZE_MASK_ is used for that. Look into View.h to see how
1057 fFlags
= (flags
& ~_RESIZE_MASK_
) | (fFlags
& _RESIZE_MASK_
);
1059 fState
->archiving_flags
|= B_VIEW_FLAGS_BIT
;
1064 BView::Frame() const
1066 return Bounds().OffsetToCopy(fParentOffset
.x
, fParentOffset
.y
);
1073 if (fOwner
&& fShowLevel
== 0) {
1074 _CheckLockAndSwitchCurrent();
1075 fOwner
->fLink
->StartMessage(AS_VIEW_HIDE
);
1076 fOwner
->fLink
->Flush();
1080 if (fShowLevel
== 1)
1081 _InvalidateParentLayout();
1089 if (fOwner
&& fShowLevel
== 0) {
1090 _CheckLockAndSwitchCurrent();
1091 fOwner
->fLink
->StartMessage(AS_VIEW_SHOW
);
1092 fOwner
->fLink
->Flush();
1095 if (fShowLevel
== 0)
1096 _InvalidateParentLayout();
1101 BView::IsFocus() const
1105 return fOwner
->CurrentFocus() == this;
1112 BView::IsHidden(const BView
* lookingFrom
) const
1117 // may we be egocentric?
1118 if (lookingFrom
== this)
1121 // we have the same visibility state as our
1122 // parent, if there is one
1124 return fParent
->IsHidden(lookingFrom
);
1126 // if we're the top view, and we're interested
1127 // in the "global" view, we're inheriting the
1128 // state of the window's visibility
1129 if (fOwner
&& lookingFrom
== NULL
)
1130 return fOwner
->IsHidden();
1137 BView::IsHidden() const
1139 return IsHidden(NULL
);
1144 BView::IsPrinting() const
1151 BView::LeftTop() const
1153 return Bounds().LeftTop();
1158 BView::SetResizingMode(uint32 mode
)
1161 _CheckLockAndSwitchCurrent();
1163 fOwner
->fLink
->StartMessage(AS_VIEW_RESIZE_MODE
);
1164 fOwner
->fLink
->Attach
<uint32
>(mode
);
1167 // look at SetFlags() for more info on the below line
1168 fFlags
= (fFlags
& ~_RESIZE_MASK_
) | (mode
& _RESIZE_MASK_
);
1173 BView::ResizingMode() const
1175 return fFlags
& _RESIZE_MASK_
;
1180 BView::SetViewCursor(const BCursor
* cursor
, bool sync
)
1182 if (cursor
== NULL
|| fOwner
== NULL
)
1187 ViewSetViewCursorInfo info
;
1188 info
.cursorToken
= cursor
->fServerToken
;
1189 info
.viewToken
= _get_object_token_(this);
1192 BPrivate::AppServerLink link
;
1193 link
.StartMessage(AS_SET_VIEW_CURSOR
);
1194 link
.Attach
<ViewSetViewCursorInfo
>(info
);
1197 // Make sure the server has processed the message.
1199 link
.FlushWithReply(code
);
1205 BView::Flush() const
1222 BView::Window() const
1228 // #pragma mark - Hook Functions
1232 BView::AttachedToWindow()
1235 STRACE(("\tHOOK: BView(%s)::AttachedToWindow()\n", Name()));
1240 BView::AllAttached()
1243 STRACE(("\tHOOK: BView(%s)::AllAttached()\n", Name()));
1248 BView::DetachedFromWindow()
1251 STRACE(("\tHOOK: BView(%s)::DetachedFromWindow()\n", Name()));
1256 BView::AllDetached()
1259 STRACE(("\tHOOK: BView(%s)::AllDetached()\n", Name()));
1264 BView::Draw(BRect updateRect
)
1267 STRACE(("\tHOOK: BView(%s)::Draw()\n", Name()));
1272 BView::DrawAfterChildren(BRect updateRect
)
1275 STRACE(("\tHOOK: BView(%s)::DrawAfterChildren()\n", Name()));
1280 BView::FrameMoved(BPoint newPosition
)
1283 STRACE(("\tHOOK: BView(%s)::FrameMoved()\n", Name()));
1288 BView::FrameResized(float newWidth
, float newHeight
)
1291 STRACE(("\tHOOK: BView(%s)::FrameResized()\n", Name()));
1296 BView::GetPreferredSize(float* _width
, float* _height
)
1298 STRACE(("\tHOOK: BView(%s)::GetPreferredSize()\n", Name()));
1301 *_width
= fBounds
.Width();
1302 if (_height
!= NULL
)
1303 *_height
= fBounds
.Height();
1308 BView::ResizeToPreferred()
1310 STRACE(("\tHOOK: BView(%s)::ResizeToPreferred()\n", Name()));
1314 GetPreferredSize(&width
, &height
);
1316 ResizeTo(width
, height
);
1321 BView::KeyDown(const char* bytes
, int32 numBytes
)
1324 STRACE(("\tHOOK: BView(%s)::KeyDown()\n", Name()));
1327 Window()->_KeyboardNavigation();
1332 BView::KeyUp(const char* bytes
, int32 numBytes
)
1335 STRACE(("\tHOOK: BView(%s)::KeyUp()\n", Name()));
1340 BView::MouseDown(BPoint where
)
1343 STRACE(("\tHOOK: BView(%s)::MouseDown()\n", Name()));
1348 BView::MouseUp(BPoint where
)
1351 STRACE(("\tHOOK: BView(%s)::MouseUp()\n", Name()));
1356 BView::MouseMoved(BPoint where
, uint32 code
, const BMessage
* dragMessage
)
1359 STRACE(("\tHOOK: BView(%s)::MouseMoved()\n", Name()));
1367 STRACE(("\tHOOK: BView(%s)::Pulse()\n", Name()));
1372 BView::TargetedByScrollView(BScrollView
* scroll_view
)
1375 STRACE(("\tHOOK: BView(%s)::TargetedByScrollView()\n", Name()));
1380 BView::WindowActivated(bool active
)
1383 STRACE(("\tHOOK: BView(%s)::WindowActivated()\n", Name()));
1387 // #pragma mark - Input Functions
1391 BView::BeginRectTracking(BRect startRect
, uint32 style
)
1393 if (_CheckOwnerLockAndSwitchCurrent()) {
1394 fOwner
->fLink
->StartMessage(AS_VIEW_BEGIN_RECT_TRACK
);
1395 fOwner
->fLink
->Attach
<BRect
>(startRect
);
1396 fOwner
->fLink
->Attach
<uint32
>(style
);
1397 fOwner
->fLink
->Flush();
1403 BView::EndRectTracking()
1405 if (_CheckOwnerLockAndSwitchCurrent()) {
1406 fOwner
->fLink
->StartMessage(AS_VIEW_END_RECT_TRACK
);
1407 fOwner
->fLink
->Flush();
1413 BView::DragMessage(BMessage
* message
, BRect dragRect
, BHandler
* replyTo
)
1420 // calculate the offset
1423 BMessage
* current
= fOwner
->CurrentMessage();
1424 if (!current
|| current
->FindPoint("be:view_where", &offset
) != B_OK
)
1425 GetMouse(&offset
, &buttons
, false);
1426 offset
-= dragRect
.LeftTop();
1428 if (!dragRect
.IsValid()) {
1429 DragMessage(message
, NULL
, B_OP_BLEND
, offset
, replyTo
);
1433 // TODO: that's not really what should happen - the app_server should take
1434 // the chance *NOT* to need to drag a whole bitmap around but just a frame.
1436 // create a drag bitmap for the rect
1437 BBitmap
* bitmap
= new(std::nothrow
) BBitmap(dragRect
, B_RGBA32
);
1441 uint32
* bits
= (uint32
*)bitmap
->Bits();
1442 uint32 bytesPerRow
= bitmap
->BytesPerRow();
1443 uint32 width
= dragRect
.IntegerWidth() + 1;
1444 uint32 height
= dragRect
.IntegerHeight() + 1;
1445 uint32 lastRow
= (height
- 1) * width
;
1447 memset(bits
, 0x00, height
* bytesPerRow
);
1450 for (uint32 i
= 0; i
< width
; i
+= 2)
1451 bits
[i
] = 0xff000000;
1454 for (uint32 i
= (height
% 2 == 0 ? 1 : 0); i
< width
; i
+= 2)
1455 bits
[lastRow
+ i
] = 0xff000000;
1458 for (uint32 i
= 0; i
< lastRow
; i
+= width
* 2)
1459 bits
[i
] = 0xff000000;
1462 for (uint32 i
= (width
% 2 == 0 ? width
: 0); i
< lastRow
; i
+= width
* 2)
1463 bits
[width
- 1 + i
] = 0xff000000;
1465 DragMessage(message
, bitmap
, B_OP_BLEND
, offset
, replyTo
);
1470 BView::DragMessage(BMessage
* message
, BBitmap
* image
, BPoint offset
,
1473 DragMessage(message
, image
, B_OP_COPY
, offset
, replyTo
);
1478 BView::DragMessage(BMessage
* message
, BBitmap
* image
,
1479 drawing_mode dragMode
, BPoint offset
, BHandler
* replyTo
)
1481 if (message
== NULL
)
1484 if (image
== NULL
) {
1485 // TODO: workaround for drags without a bitmap - should not be necessary if
1486 // we move the rectangle dragging into the app_server
1487 image
= new(std::nothrow
) BBitmap(BRect(0, 0, 0, 0), B_RGBA32
);
1492 if (replyTo
== NULL
)
1495 if (replyTo
->Looper() == NULL
)
1496 debugger("DragMessage: warning - the Handler needs a looper");
1500 if (!message
->HasInt32("buttons")) {
1501 BMessage
* msg
= fOwner
->CurrentMessage();
1505 || msg
->FindInt32("buttons", (int32
*)&buttons
) != B_OK
) {
1507 GetMouse(&point
, &buttons
, false);
1510 message
->AddInt32("buttons", buttons
);
1513 BMessage::Private
privateMessage(message
);
1514 privateMessage
.SetReply(BMessenger(replyTo
, replyTo
->Looper()));
1516 int32 bufferSize
= message
->FlattenedSize();
1517 char* buffer
= new(std::nothrow
) char[bufferSize
];
1518 if (buffer
!= NULL
) {
1519 message
->Flatten(buffer
, bufferSize
);
1521 fOwner
->fLink
->StartMessage(AS_VIEW_DRAG_IMAGE
);
1522 fOwner
->fLink
->Attach
<int32
>(image
->_ServerToken());
1523 fOwner
->fLink
->Attach
<int32
>((int32
)dragMode
);
1524 fOwner
->fLink
->Attach
<BPoint
>(offset
);
1525 fOwner
->fLink
->Attach
<int32
>(bufferSize
);
1526 fOwner
->fLink
->Attach(buffer
, bufferSize
);
1528 // we need to wait for the server
1529 // to actually process this message
1530 // before we can delete the bitmap
1532 fOwner
->fLink
->FlushWithReply(code
);
1536 fprintf(stderr
, "BView::DragMessage() - no memory to flatten drag "
1545 BView::GetMouse(BPoint
* _location
, uint32
* _buttons
, bool checkMessageQueue
)
1547 if (_location
== NULL
&& _buttons
== NULL
)
1550 _CheckOwnerLockAndSwitchCurrent();
1552 uint32 eventOptions
= fEventOptions
| fMouseEventOptions
;
1553 bool noHistory
= eventOptions
& B_NO_POINTER_HISTORY
;
1554 bool fullHistory
= eventOptions
& B_FULL_POINTER_HISTORY
;
1556 if (checkMessageQueue
&& !noHistory
) {
1557 Window()->UpdateIfNeeded();
1558 BMessageQueue
* queue
= Window()->MessageQueue();
1561 // Look out for mouse update messages
1564 for (int32 i
= 0; (message
= queue
->FindMessage(i
)) != NULL
; i
++) {
1565 switch (message
->what
) {
1570 if (!Window()->_StealMouseMessage(message
, deleteMessage
))
1573 if (!fullHistory
&& message
->what
== B_MOUSE_MOVED
) {
1574 // Check if the message is too old. Some applications
1575 // check the message queue in such a way that mouse
1576 // messages *must* pile up. This check makes them work
1577 // as intended, although these applications could simply
1578 // use the version of BView::GetMouse() that does not
1579 // check the history. Also note that it isn't a problem
1580 // to delete the message in case there is not a newer
1581 // one. If we don't find a message in the queue, we will
1582 // just fall back to asking the app_sever directly. So
1583 // the imposed delay will not be a problem on slower
1584 // computers. This check also prevents another problem,
1585 // when the message that we use is *not* removed from
1586 // the queue. Subsequent calls to GetMouse() would find
1587 // this message over and over!
1588 bigtime_t eventTime
;
1589 if (message
->FindInt64("when", &eventTime
) == B_OK
1590 && system_time() - eventTime
> 10000) {
1591 // just discard the message
1597 if (_location
!= NULL
)
1598 message
->FindPoint("screen_where", _location
);
1599 if (_buttons
!= NULL
)
1600 message
->FindInt32("buttons", (int32
*)_buttons
);
1602 // we need to hold the queue lock until here, because
1603 // the message might still be used for something else
1605 if (_location
!= NULL
)
1606 ConvertFromScreen(_location
);
1617 // If no mouse update message has been found in the message queue,
1618 // we get the current mouse location and buttons from the app_server
1620 fOwner
->fLink
->StartMessage(AS_GET_MOUSE
);
1623 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
1627 fOwner
->fLink
->Read
<BPoint
>(&location
);
1628 fOwner
->fLink
->Read
<uint32
>(&buttons
);
1629 // TODO: ServerWindow replies with an int32 here
1631 ConvertFromScreen(&location
);
1632 // TODO: in beos R5, location is already converted to the view
1633 // local coordinate system, so if an app checks the window message
1634 // queue by itself, it might not find what it expects.
1635 // NOTE: the fact that we have mouse coords in screen space in our
1636 // queue avoids the problem that messages already in the queue will
1637 // be outdated as soon as a window or even the view moves. The
1638 // second situation being quite common actually, also with regards
1639 // to scrolling. An app reading these messages would have to know
1640 // the locations of the window and view for each message...
1641 // otherwise it is potentially broken anyways.
1642 if (_location
!= NULL
)
1643 *_location
= location
;
1644 if (_buttons
!= NULL
)
1645 *_buttons
= buttons
;
1647 if (_location
!= NULL
)
1648 _location
->Set(0, 0);
1649 if (_buttons
!= NULL
)
1656 BView::MakeFocus(bool focus
)
1661 // TODO: If this view has focus and focus == false,
1662 // will there really be no other view with focus? No
1663 // cycling to the next one?
1664 BView
* focusView
= fOwner
->CurrentFocus();
1666 // Unfocus a previous focus view
1667 if (focusView
!= NULL
&& focusView
!= this)
1668 focusView
->MakeFocus(false);
1670 // if we want to make this view the current focus view
1671 fOwner
->_SetFocus(this, true);
1673 // we want to unfocus this view, but only if it actually has focus
1674 if (focusView
== this)
1675 fOwner
->_SetFocus(NULL
, true);
1681 BView::ScrollBar(orientation direction
) const
1683 switch (direction
) {
1685 return fVerScroller
;
1688 return fHorScroller
;
1697 BView::ScrollBy(float deltaX
, float deltaY
)
1699 ScrollTo(BPoint(fBounds
.left
+ deltaX
, fBounds
.top
+ deltaY
));
1704 BView::ScrollTo(BPoint where
)
1706 // scrolling by fractional values is not supported
1707 where
.x
= roundf(where
.x
);
1708 where
.y
= roundf(where
.y
);
1710 // no reason to process this further if no scroll is intended.
1711 if (where
.x
== fBounds
.left
&& where
.y
== fBounds
.top
)
1714 // make sure scrolling is within valid bounds
1717 fHorScroller
->GetRange(&min
, &max
);
1721 else if (where
.x
> max
)
1726 fVerScroller
->GetRange(&min
, &max
);
1730 else if (where
.y
> max
)
1734 _CheckLockAndSwitchCurrent();
1736 float xDiff
= where
.x
- fBounds
.left
;
1737 float yDiff
= where
.y
- fBounds
.top
;
1739 // if we're attached to a window tell app_server about this change
1741 fOwner
->fLink
->StartMessage(AS_VIEW_SCROLL
);
1742 fOwner
->fLink
->Attach
<float>(xDiff
);
1743 fOwner
->fLink
->Attach
<float>(yDiff
);
1745 fOwner
->fLink
->Flush();
1747 // fState->valid_flags &= ~B_VIEW_FRAME_BIT;
1750 // we modify our bounds rectangle by deltaX/deltaY coord units hor/ver.
1751 fBounds
.OffsetTo(where
.x
, where
.y
);
1753 // then set the new values of the scrollbars
1754 if (fHorScroller
&& xDiff
!= 0.0)
1755 fHorScroller
->SetValue(fBounds
.left
);
1756 if (fVerScroller
&& yDiff
!= 0.0)
1757 fVerScroller
->SetValue(fBounds
.top
);
1763 BView::SetEventMask(uint32 mask
, uint32 options
)
1765 if (fEventMask
== mask
&& fEventOptions
== options
)
1768 // don't change the mask if it's zero and we've got options
1769 if (mask
!= 0 || options
== 0)
1770 fEventMask
= mask
| (fEventMask
& 0xffff0000);
1771 fEventOptions
= options
;
1773 fState
->archiving_flags
|= B_VIEW_EVENT_MASK_BIT
;
1776 _CheckLockAndSwitchCurrent();
1778 fOwner
->fLink
->StartMessage(AS_VIEW_SET_EVENT_MASK
);
1779 fOwner
->fLink
->Attach
<uint32
>(mask
);
1780 fOwner
->fLink
->Attach
<uint32
>(options
);
1781 fOwner
->fLink
->Flush();
1796 BView::SetMouseEventMask(uint32 mask
, uint32 options
)
1798 // Just don't do anything if the view is not yet attached
1799 // or we were called outside of BView::MouseDown()
1801 && fOwner
->CurrentMessage() != NULL
1802 && fOwner
->CurrentMessage()->what
== B_MOUSE_DOWN
) {
1803 _CheckLockAndSwitchCurrent();
1804 fMouseEventOptions
= options
;
1806 fOwner
->fLink
->StartMessage(AS_VIEW_SET_MOUSE_EVENT_MASK
);
1807 fOwner
->fLink
->Attach
<uint32
>(mask
);
1808 fOwner
->fLink
->Attach
<uint32
>(options
);
1809 fOwner
->fLink
->Flush();
1817 // #pragma mark - Graphic State Functions
1823 _CheckOwnerLockAndSwitchCurrent();
1825 fOwner
->fLink
->StartMessage(AS_VIEW_PUSH_STATE
);
1827 // initialize origin, scale and transform, new states start "clean".
1828 fState
->valid_flags
|= B_VIEW_SCALE_BIT
| B_VIEW_ORIGIN_BIT
1829 | B_VIEW_TRANSFORM_BIT
;
1830 fState
->scale
= 1.0f
;
1831 fState
->origin
.Set(0, 0);
1832 fState
->transform
.Reset();
1839 _CheckOwnerLockAndSwitchCurrent();
1841 fOwner
->fLink
->StartMessage(AS_VIEW_POP_STATE
);
1842 _FlushIfNotInTransaction();
1844 // invalidate all flags (except those that are not part of pop/push)
1845 fState
->valid_flags
= B_VIEW_VIEW_COLOR_BIT
;
1850 BView::SetOrigin(BPoint where
)
1852 SetOrigin(where
.x
, where
.y
);
1857 BView::SetOrigin(float x
, float y
)
1859 if (fState
->IsValid(B_VIEW_ORIGIN_BIT
)
1860 && x
== fState
->origin
.x
&& y
== fState
->origin
.y
)
1863 fState
->origin
.x
= x
;
1864 fState
->origin
.y
= y
;
1866 if (_CheckOwnerLockAndSwitchCurrent()) {
1867 fOwner
->fLink
->StartMessage(AS_VIEW_SET_ORIGIN
);
1868 fOwner
->fLink
->Attach
<float>(x
);
1869 fOwner
->fLink
->Attach
<float>(y
);
1871 fState
->valid_flags
|= B_VIEW_ORIGIN_BIT
;
1874 // our local coord system origin has changed, so when archiving we'll add
1876 fState
->archiving_flags
|= B_VIEW_ORIGIN_BIT
;
1881 BView::Origin() const
1883 if (!fState
->IsValid(B_VIEW_ORIGIN_BIT
)) {
1884 // we don't keep graphics state information, therefor
1885 // we need to ask the server for the origin after PopState()
1886 _CheckOwnerLockAndSwitchCurrent();
1888 fOwner
->fLink
->StartMessage(AS_VIEW_GET_ORIGIN
);
1891 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
&& code
== B_OK
)
1892 fOwner
->fLink
->Read
<BPoint
>(&fState
->origin
);
1894 fState
->valid_flags
|= B_VIEW_ORIGIN_BIT
;
1897 return fState
->origin
;
1902 BView::SetScale(float scale
) const
1904 if (fState
->IsValid(B_VIEW_SCALE_BIT
) && scale
== fState
->scale
)
1908 _CheckLockAndSwitchCurrent();
1910 fOwner
->fLink
->StartMessage(AS_VIEW_SET_SCALE
);
1911 fOwner
->fLink
->Attach
<float>(scale
);
1913 fState
->valid_flags
|= B_VIEW_SCALE_BIT
;
1916 fState
->scale
= scale
;
1917 fState
->archiving_flags
|= B_VIEW_SCALE_BIT
;
1922 BView::Scale() const
1924 if (!fState
->IsValid(B_VIEW_SCALE_BIT
) && fOwner
) {
1925 _CheckLockAndSwitchCurrent();
1927 fOwner
->fLink
->StartMessage(AS_VIEW_GET_SCALE
);
1930 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
&& code
== B_OK
)
1931 fOwner
->fLink
->Read
<float>(&fState
->scale
);
1933 fState
->valid_flags
|= B_VIEW_SCALE_BIT
;
1936 return fState
->scale
;
1941 BView::SetTransform(BAffineTransform transform
)
1943 if (fState
->IsValid(B_VIEW_TRANSFORM_BIT
) && transform
== fState
->transform
)
1946 if (fOwner
!= NULL
) {
1947 _CheckLockAndSwitchCurrent();
1949 fOwner
->fLink
->StartMessage(AS_VIEW_SET_TRANSFORM
);
1950 fOwner
->fLink
->Attach
<BAffineTransform
>(transform
);
1952 fState
->valid_flags
|= B_VIEW_TRANSFORM_BIT
;
1955 fState
->transform
= transform
;
1956 fState
->archiving_flags
|= B_VIEW_TRANSFORM_BIT
;
1961 BView::Transform() const
1963 if (!fState
->IsValid(B_VIEW_TRANSFORM_BIT
) && fOwner
!= NULL
) {
1964 _CheckLockAndSwitchCurrent();
1966 fOwner
->fLink
->StartMessage(AS_VIEW_GET_TRANSFORM
);
1969 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
&& code
== B_OK
)
1970 fOwner
->fLink
->Read
<BAffineTransform
>(&fState
->transform
);
1972 fState
->valid_flags
|= B_VIEW_TRANSFORM_BIT
;
1975 return fState
->transform
;
1980 BView::TranslateBy(double x
, double y
)
1982 if (fOwner
!= NULL
) {
1983 _CheckLockAndSwitchCurrent();
1985 fOwner
->fLink
->StartMessage(AS_VIEW_AFFINE_TRANSLATE
);
1986 fOwner
->fLink
->Attach
<double>(x
);
1987 fOwner
->fLink
->Attach
<double>(y
);
1989 fState
->valid_flags
&= ~B_VIEW_TRANSFORM_BIT
;
1992 fState
->archiving_flags
|= B_VIEW_TRANSFORM_BIT
;
1997 BView::ScaleBy(double x
, double y
)
1999 if (fOwner
!= NULL
) {
2000 _CheckLockAndSwitchCurrent();
2002 fOwner
->fLink
->StartMessage(AS_VIEW_AFFINE_SCALE
);
2003 fOwner
->fLink
->Attach
<double>(x
);
2004 fOwner
->fLink
->Attach
<double>(y
);
2006 fState
->valid_flags
&= ~B_VIEW_TRANSFORM_BIT
;
2009 fState
->archiving_flags
|= B_VIEW_TRANSFORM_BIT
;
2014 BView::RotateBy(double angleRadians
)
2016 if (fOwner
!= NULL
) {
2017 _CheckLockAndSwitchCurrent();
2019 fOwner
->fLink
->StartMessage(AS_VIEW_AFFINE_ROTATE
);
2020 fOwner
->fLink
->Attach
<double>(angleRadians
);
2022 fState
->valid_flags
&= ~B_VIEW_TRANSFORM_BIT
;
2025 fState
->archiving_flags
|= B_VIEW_TRANSFORM_BIT
;
2030 BView::SetLineMode(cap_mode lineCap
, join_mode lineJoin
, float miterLimit
)
2032 if (fState
->IsValid(B_VIEW_LINE_MODES_BIT
)
2033 && lineCap
== fState
->line_cap
&& lineJoin
== fState
->line_join
2034 && miterLimit
== fState
->miter_limit
)
2038 _CheckLockAndSwitchCurrent();
2040 ViewSetLineModeInfo info
;
2041 info
.lineJoin
= lineJoin
;
2042 info
.lineCap
= lineCap
;
2043 info
.miterLimit
= miterLimit
;
2045 fOwner
->fLink
->StartMessage(AS_VIEW_SET_LINE_MODE
);
2046 fOwner
->fLink
->Attach
<ViewSetLineModeInfo
>(info
);
2048 fState
->valid_flags
|= B_VIEW_LINE_MODES_BIT
;
2051 fState
->line_cap
= lineCap
;
2052 fState
->line_join
= lineJoin
;
2053 fState
->miter_limit
= miterLimit
;
2055 fState
->archiving_flags
|= B_VIEW_LINE_MODES_BIT
;
2060 BView::LineJoinMode() const
2062 // This will update the current state, if necessary
2063 if (!fState
->IsValid(B_VIEW_LINE_MODES_BIT
))
2066 return fState
->line_join
;
2071 BView::LineCapMode() const
2073 // This will update the current state, if necessary
2074 if (!fState
->IsValid(B_VIEW_LINE_MODES_BIT
))
2077 return fState
->line_cap
;
2082 BView::LineMiterLimit() const
2084 if (!fState
->IsValid(B_VIEW_LINE_MODES_BIT
) && fOwner
) {
2085 _CheckLockAndSwitchCurrent();
2087 fOwner
->fLink
->StartMessage(AS_VIEW_GET_LINE_MODE
);
2090 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
&& code
== B_OK
) {
2092 ViewSetLineModeInfo info
;
2093 fOwner
->fLink
->Read
<ViewSetLineModeInfo
>(&info
);
2095 fState
->line_cap
= info
.lineCap
;
2096 fState
->line_join
= info
.lineJoin
;
2097 fState
->miter_limit
= info
.miterLimit
;
2100 fState
->valid_flags
|= B_VIEW_LINE_MODES_BIT
;
2103 return fState
->miter_limit
;
2108 BView::SetFillRule(int32 fillRule
)
2110 if (fState
->IsValid(B_VIEW_FILL_RULE_BIT
) && fillRule
== fState
->fill_rule
)
2114 _CheckLockAndSwitchCurrent();
2116 fOwner
->fLink
->StartMessage(AS_VIEW_SET_FILL_RULE
);
2117 fOwner
->fLink
->Attach
<int32
>(fillRule
);
2119 fState
->valid_flags
|= B_VIEW_FILL_RULE_BIT
;
2122 fState
->fill_rule
= fillRule
;
2124 fState
->archiving_flags
|= B_VIEW_FILL_RULE_BIT
;
2129 BView::FillRule() const
2131 if (!fState
->IsValid(B_VIEW_FILL_RULE_BIT
) && fOwner
) {
2132 _CheckLockAndSwitchCurrent();
2134 fOwner
->fLink
->StartMessage(AS_VIEW_GET_FILL_RULE
);
2137 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
&& code
== B_OK
) {
2140 fOwner
->fLink
->Read
<int32
>(&fillRule
);
2142 fState
->fill_rule
= fillRule
;
2145 fState
->valid_flags
|= B_VIEW_FILL_RULE_BIT
;
2148 return fState
->fill_rule
;
2153 BView::SetDrawingMode(drawing_mode mode
)
2155 if (fState
->IsValid(B_VIEW_DRAWING_MODE_BIT
)
2156 && mode
== fState
->drawing_mode
)
2160 _CheckLockAndSwitchCurrent();
2162 fOwner
->fLink
->StartMessage(AS_VIEW_SET_DRAWING_MODE
);
2163 fOwner
->fLink
->Attach
<int8
>((int8
)mode
);
2165 fState
->valid_flags
|= B_VIEW_DRAWING_MODE_BIT
;
2168 fState
->drawing_mode
= mode
;
2169 fState
->archiving_flags
|= B_VIEW_DRAWING_MODE_BIT
;
2174 BView::DrawingMode() const
2176 if (!fState
->IsValid(B_VIEW_DRAWING_MODE_BIT
) && fOwner
) {
2177 _CheckLockAndSwitchCurrent();
2179 fOwner
->fLink
->StartMessage(AS_VIEW_GET_DRAWING_MODE
);
2182 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2185 fOwner
->fLink
->Read
<int8
>(&drawingMode
);
2187 fState
->drawing_mode
= (drawing_mode
)drawingMode
;
2188 fState
->valid_flags
|= B_VIEW_DRAWING_MODE_BIT
;
2192 return fState
->drawing_mode
;
2197 BView::SetBlendingMode(source_alpha sourceAlpha
, alpha_function alphaFunction
)
2199 if (fState
->IsValid(B_VIEW_BLENDING_BIT
)
2200 && sourceAlpha
== fState
->alpha_source_mode
2201 && alphaFunction
== fState
->alpha_function_mode
)
2205 _CheckLockAndSwitchCurrent();
2207 ViewBlendingModeInfo info
;
2208 info
.sourceAlpha
= sourceAlpha
;
2209 info
.alphaFunction
= alphaFunction
;
2211 fOwner
->fLink
->StartMessage(AS_VIEW_SET_BLENDING_MODE
);
2212 fOwner
->fLink
->Attach
<ViewBlendingModeInfo
>(info
);
2214 fState
->valid_flags
|= B_VIEW_BLENDING_BIT
;
2217 fState
->alpha_source_mode
= sourceAlpha
;
2218 fState
->alpha_function_mode
= alphaFunction
;
2220 fState
->archiving_flags
|= B_VIEW_BLENDING_BIT
;
2225 BView::GetBlendingMode(source_alpha
* _sourceAlpha
,
2226 alpha_function
* _alphaFunction
) const
2228 if (!fState
->IsValid(B_VIEW_BLENDING_BIT
) && fOwner
) {
2229 _CheckLockAndSwitchCurrent();
2231 fOwner
->fLink
->StartMessage(AS_VIEW_GET_BLENDING_MODE
);
2234 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
&& code
== B_OK
) {
2235 ViewBlendingModeInfo info
;
2236 fOwner
->fLink
->Read
<ViewBlendingModeInfo
>(&info
);
2238 fState
->alpha_source_mode
= info
.sourceAlpha
;
2239 fState
->alpha_function_mode
= info
.alphaFunction
;
2241 fState
->valid_flags
|= B_VIEW_BLENDING_BIT
;
2246 *_sourceAlpha
= fState
->alpha_source_mode
;
2249 *_alphaFunction
= fState
->alpha_function_mode
;
2254 BView::MovePenTo(BPoint point
)
2256 MovePenTo(point
.x
, point
.y
);
2261 BView::MovePenTo(float x
, float y
)
2263 if (fState
->IsValid(B_VIEW_PEN_LOCATION_BIT
)
2264 && x
== fState
->pen_location
.x
&& y
== fState
->pen_location
.y
)
2268 _CheckLockAndSwitchCurrent();
2270 fOwner
->fLink
->StartMessage(AS_VIEW_SET_PEN_LOC
);
2271 fOwner
->fLink
->Attach
<BPoint
>(BPoint(x
, y
));
2273 fState
->valid_flags
|= B_VIEW_PEN_LOCATION_BIT
;
2276 fState
->pen_location
.x
= x
;
2277 fState
->pen_location
.y
= y
;
2279 fState
->archiving_flags
|= B_VIEW_PEN_LOCATION_BIT
;
2284 BView::MovePenBy(float x
, float y
)
2286 // this will update the pen location if necessary
2287 if (!fState
->IsValid(B_VIEW_PEN_LOCATION_BIT
))
2290 MovePenTo(fState
->pen_location
.x
+ x
, fState
->pen_location
.y
+ y
);
2295 BView::PenLocation() const
2297 if (!fState
->IsValid(B_VIEW_PEN_LOCATION_BIT
) && fOwner
) {
2298 _CheckLockAndSwitchCurrent();
2300 fOwner
->fLink
->StartMessage(AS_VIEW_GET_PEN_LOC
);
2303 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2305 fOwner
->fLink
->Read
<BPoint
>(&fState
->pen_location
);
2307 fState
->valid_flags
|= B_VIEW_PEN_LOCATION_BIT
;
2311 return fState
->pen_location
;
2316 BView::SetPenSize(float size
)
2318 if (fState
->IsValid(B_VIEW_PEN_SIZE_BIT
) && size
== fState
->pen_size
)
2322 _CheckLockAndSwitchCurrent();
2324 fOwner
->fLink
->StartMessage(AS_VIEW_SET_PEN_SIZE
);
2325 fOwner
->fLink
->Attach
<float>(size
);
2327 fState
->valid_flags
|= B_VIEW_PEN_SIZE_BIT
;
2330 fState
->pen_size
= size
;
2331 fState
->archiving_flags
|= B_VIEW_PEN_SIZE_BIT
;
2336 BView::PenSize() const
2338 if (!fState
->IsValid(B_VIEW_PEN_SIZE_BIT
) && fOwner
) {
2339 _CheckLockAndSwitchCurrent();
2341 fOwner
->fLink
->StartMessage(AS_VIEW_GET_PEN_SIZE
);
2344 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2346 fOwner
->fLink
->Read
<float>(&fState
->pen_size
);
2348 fState
->valid_flags
|= B_VIEW_PEN_SIZE_BIT
;
2352 return fState
->pen_size
;
2357 BView::SetHighColor(rgb_color color
)
2359 SetHighUIColor(B_NO_COLOR
);
2361 // are we up-to-date already?
2362 if (fState
->IsValid(B_VIEW_HIGH_COLOR_BIT
)
2363 && fState
->high_color
== color
)
2367 _CheckLockAndSwitchCurrent();
2369 fOwner
->fLink
->StartMessage(AS_VIEW_SET_HIGH_COLOR
);
2370 fOwner
->fLink
->Attach
<rgb_color
>(color
);
2372 fState
->valid_flags
|= B_VIEW_HIGH_COLOR_BIT
;
2375 fState
->high_color
= color
;
2377 fState
->archiving_flags
|= B_VIEW_HIGH_COLOR_BIT
;
2382 BView::HighColor() const
2384 if (!fState
->IsValid(B_VIEW_HIGH_COLOR_BIT
) && fOwner
) {
2385 _CheckLockAndSwitchCurrent();
2387 fOwner
->fLink
->StartMessage(AS_VIEW_GET_HIGH_COLOR
);
2390 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2392 fOwner
->fLink
->Read
<rgb_color
>(&fState
->high_color
);
2394 fState
->valid_flags
|= B_VIEW_HIGH_COLOR_BIT
;
2398 return fState
->high_color
;
2403 BView::SetHighUIColor(color_which which
, float tint
)
2405 if (fState
->IsValid(B_VIEW_WHICH_HIGH_COLOR_BIT
)
2406 && fState
->which_high_color
== which
2407 && fState
->which_high_color_tint
== tint
)
2410 if (fOwner
!= NULL
) {
2411 _CheckLockAndSwitchCurrent();
2413 fOwner
->fLink
->StartMessage(AS_VIEW_SET_HIGH_UI_COLOR
);
2414 fOwner
->fLink
->Attach
<color_which
>(which
);
2415 fOwner
->fLink
->Attach
<float>(tint
);
2417 fState
->valid_flags
|= B_VIEW_WHICH_HIGH_COLOR_BIT
;
2420 fState
->which_high_color
= which
;
2421 fState
->which_high_color_tint
= tint
;
2423 if (which
!= B_NO_COLOR
) {
2424 fState
->archiving_flags
|= B_VIEW_WHICH_HIGH_COLOR_BIT
;
2425 fState
->archiving_flags
&= ~B_VIEW_HIGH_COLOR_BIT
;
2426 fState
->valid_flags
|= B_VIEW_HIGH_COLOR_BIT
;
2428 fState
->high_color
= tint_color(ui_color(which
), tint
);
2430 fState
->valid_flags
&= ~B_VIEW_HIGH_COLOR_BIT
;
2431 fState
->archiving_flags
&= ~B_VIEW_WHICH_HIGH_COLOR_BIT
;
2437 BView::HighUIColor(float* tint
) const
2439 if (!fState
->IsValid(B_VIEW_WHICH_HIGH_COLOR_BIT
)
2440 && fOwner
!= NULL
) {
2441 _CheckLockAndSwitchCurrent();
2443 fOwner
->fLink
->StartMessage(AS_VIEW_GET_HIGH_UI_COLOR
);
2446 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2448 fOwner
->fLink
->Read
<color_which
>(&fState
->which_high_color
);
2449 fOwner
->fLink
->Read
<float>(&fState
->which_high_color_tint
);
2450 fOwner
->fLink
->Read
<rgb_color
>(&fState
->high_color
);
2452 fState
->valid_flags
|= B_VIEW_WHICH_HIGH_COLOR_BIT
;
2453 fState
->valid_flags
|= B_VIEW_HIGH_COLOR_BIT
;
2458 *tint
= fState
->which_high_color_tint
;
2460 return fState
->which_high_color
;
2465 BView::SetLowColor(rgb_color color
)
2467 SetLowUIColor(B_NO_COLOR
);
2469 if (fState
->IsValid(B_VIEW_LOW_COLOR_BIT
)
2470 && fState
->low_color
== color
)
2474 _CheckLockAndSwitchCurrent();
2476 fOwner
->fLink
->StartMessage(AS_VIEW_SET_LOW_COLOR
);
2477 fOwner
->fLink
->Attach
<rgb_color
>(color
);
2479 fState
->valid_flags
|= B_VIEW_LOW_COLOR_BIT
;
2482 fState
->low_color
= color
;
2484 fState
->archiving_flags
|= B_VIEW_LOW_COLOR_BIT
;
2489 BView::LowColor() const
2491 if (!fState
->IsValid(B_VIEW_LOW_COLOR_BIT
) && fOwner
) {
2492 _CheckLockAndSwitchCurrent();
2494 fOwner
->fLink
->StartMessage(AS_VIEW_GET_LOW_COLOR
);
2497 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2499 fOwner
->fLink
->Read
<rgb_color
>(&fState
->low_color
);
2501 fState
->valid_flags
|= B_VIEW_LOW_COLOR_BIT
;
2505 return fState
->low_color
;
2510 BView::SetLowUIColor(color_which which
, float tint
)
2512 if (fState
->IsValid(B_VIEW_WHICH_LOW_COLOR_BIT
)
2513 && fState
->which_low_color
== which
2514 && fState
->which_low_color_tint
== tint
)
2517 if (fOwner
!= NULL
) {
2518 _CheckLockAndSwitchCurrent();
2520 fOwner
->fLink
->StartMessage(AS_VIEW_SET_LOW_UI_COLOR
);
2521 fOwner
->fLink
->Attach
<color_which
>(which
);
2522 fOwner
->fLink
->Attach
<float>(tint
);
2524 fState
->valid_flags
|= B_VIEW_WHICH_LOW_COLOR_BIT
;
2527 fState
->which_low_color
= which
;
2528 fState
->which_low_color_tint
= tint
;
2530 if (which
!= B_NO_COLOR
) {
2531 fState
->archiving_flags
|= B_VIEW_WHICH_LOW_COLOR_BIT
;
2532 fState
->archiving_flags
&= ~B_VIEW_LOW_COLOR_BIT
;
2533 fState
->valid_flags
|= B_VIEW_LOW_COLOR_BIT
;
2535 fState
->low_color
= tint_color(ui_color(which
), tint
);
2537 fState
->valid_flags
&= ~B_VIEW_LOW_COLOR_BIT
;
2538 fState
->archiving_flags
&= ~B_VIEW_WHICH_LOW_COLOR_BIT
;
2544 BView::LowUIColor(float* tint
) const
2546 if (!fState
->IsValid(B_VIEW_WHICH_LOW_COLOR_BIT
)
2547 && fOwner
!= NULL
) {
2548 _CheckLockAndSwitchCurrent();
2550 fOwner
->fLink
->StartMessage(AS_VIEW_GET_LOW_UI_COLOR
);
2553 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2555 fOwner
->fLink
->Read
<color_which
>(&fState
->which_low_color
);
2556 fOwner
->fLink
->Read
<float>(&fState
->which_low_color_tint
);
2557 fOwner
->fLink
->Read
<rgb_color
>(&fState
->low_color
);
2559 fState
->valid_flags
|= B_VIEW_WHICH_LOW_COLOR_BIT
;
2560 fState
->valid_flags
|= B_VIEW_LOW_COLOR_BIT
;
2565 *tint
= fState
->which_low_color_tint
;
2567 return fState
->which_low_color
;
2572 BView::HasDefaultColors() const
2574 // If we don't have any of these flags, then we have default colors
2575 uint32 testMask
= B_VIEW_VIEW_COLOR_BIT
| B_VIEW_HIGH_COLOR_BIT
2576 | B_VIEW_LOW_COLOR_BIT
| B_VIEW_WHICH_VIEW_COLOR_BIT
2577 | B_VIEW_WHICH_HIGH_COLOR_BIT
| B_VIEW_WHICH_LOW_COLOR_BIT
;
2579 return (fState
->archiving_flags
& testMask
) == 0;
2584 BView::HasSystemColors() const
2586 return fState
->which_view_color
== B_PANEL_BACKGROUND_COLOR
2587 && fState
->which_high_color
== B_PANEL_TEXT_COLOR
2588 && fState
->which_low_color
== B_PANEL_BACKGROUND_COLOR
2589 && fState
->which_view_color_tint
== B_NO_TINT
2590 && fState
->which_high_color_tint
== B_NO_TINT
2591 && fState
->which_low_color_tint
== B_NO_TINT
;
2596 BView::AdoptParentColors()
2598 AdoptViewColors(Parent());
2603 BView::AdoptSystemColors()
2605 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
2606 SetLowUIColor(B_PANEL_BACKGROUND_COLOR
);
2607 SetHighUIColor(B_PANEL_TEXT_COLOR
);
2612 BView::AdoptViewColors(BView
* view
)
2614 if (view
== NULL
|| (view
->Window() != NULL
&& !view
->LockLooper()))
2617 float tint
= B_NO_TINT
;
2618 float viewTint
= tint
;
2619 color_which viewWhich
= view
->ViewUIColor(&viewTint
);
2622 if (viewWhich
!= B_NO_COLOR
)
2623 SetViewUIColor(viewWhich
, viewTint
);
2625 SetViewColor(view
->ViewColor());
2628 color_which which
= view
->LowUIColor(&tint
);
2629 if (which
!= B_NO_COLOR
)
2630 SetLowUIColor(which
, tint
);
2631 else if (viewWhich
!= B_NO_COLOR
)
2632 SetLowUIColor(viewWhich
, viewTint
);
2634 SetLowColor(view
->LowColor());
2637 which
= view
->HighUIColor(&tint
);
2638 if (which
!= B_NO_COLOR
)
2639 SetHighUIColor(which
, tint
);
2641 SetHighColor(view
->HighColor());
2643 if (view
->Window() != NULL
)
2644 view
->UnlockLooper();
2649 BView::SetViewColor(rgb_color color
)
2651 SetViewUIColor(B_NO_COLOR
);
2653 if (fState
->IsValid(B_VIEW_VIEW_COLOR_BIT
)
2654 && fState
->view_color
== color
)
2658 _CheckLockAndSwitchCurrent();
2660 fOwner
->fLink
->StartMessage(AS_VIEW_SET_VIEW_COLOR
);
2661 fOwner
->fLink
->Attach
<rgb_color
>(color
);
2662 fOwner
->fLink
->Flush();
2664 fState
->valid_flags
|= B_VIEW_VIEW_COLOR_BIT
;
2667 fState
->view_color
= color
;
2669 fState
->archiving_flags
|= B_VIEW_VIEW_COLOR_BIT
;
2674 BView::ViewColor() const
2676 if (!fState
->IsValid(B_VIEW_VIEW_COLOR_BIT
) && fOwner
) {
2677 _CheckLockAndSwitchCurrent();
2679 fOwner
->fLink
->StartMessage(AS_VIEW_GET_VIEW_COLOR
);
2682 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2684 fOwner
->fLink
->Read
<rgb_color
>(&fState
->view_color
);
2686 fState
->valid_flags
|= B_VIEW_VIEW_COLOR_BIT
;
2690 return fState
->view_color
;
2695 BView::SetViewUIColor(color_which which
, float tint
)
2697 if (fState
->IsValid(B_VIEW_WHICH_VIEW_COLOR_BIT
)
2698 && fState
->which_view_color
== which
2699 && fState
->which_view_color_tint
== tint
)
2702 if (fOwner
!= NULL
) {
2703 _CheckLockAndSwitchCurrent();
2705 fOwner
->fLink
->StartMessage(AS_VIEW_SET_VIEW_UI_COLOR
);
2706 fOwner
->fLink
->Attach
<color_which
>(which
);
2707 fOwner
->fLink
->Attach
<float>(tint
);
2709 fState
->valid_flags
|= B_VIEW_WHICH_VIEW_COLOR_BIT
;
2712 fState
->which_view_color
= which
;
2713 fState
->which_view_color_tint
= tint
;
2715 if (which
!= B_NO_COLOR
) {
2716 fState
->archiving_flags
|= B_VIEW_WHICH_VIEW_COLOR_BIT
;
2717 fState
->archiving_flags
&= ~B_VIEW_VIEW_COLOR_BIT
;
2718 fState
->valid_flags
|= B_VIEW_VIEW_COLOR_BIT
;
2720 fState
->view_color
= tint_color(ui_color(which
), tint
);
2722 fState
->valid_flags
&= ~B_VIEW_VIEW_COLOR_BIT
;
2723 fState
->archiving_flags
&= ~B_VIEW_WHICH_VIEW_COLOR_BIT
;
2726 if (!fState
->IsValid(B_VIEW_WHICH_LOW_COLOR_BIT
))
2727 SetLowUIColor(which
, tint
);
2732 BView::ViewUIColor(float* tint
) const
2734 if (!fState
->IsValid(B_VIEW_WHICH_VIEW_COLOR_BIT
)
2735 && fOwner
!= NULL
) {
2736 _CheckLockAndSwitchCurrent();
2738 fOwner
->fLink
->StartMessage(AS_VIEW_GET_VIEW_UI_COLOR
);
2741 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2743 fOwner
->fLink
->Read
<color_which
>(&fState
->which_view_color
);
2744 fOwner
->fLink
->Read
<float>(&fState
->which_view_color_tint
);
2745 fOwner
->fLink
->Read
<rgb_color
>(&fState
->view_color
);
2747 fState
->valid_flags
|= B_VIEW_WHICH_VIEW_COLOR_BIT
;
2748 fState
->valid_flags
|= B_VIEW_VIEW_COLOR_BIT
;
2753 *tint
= fState
->which_view_color_tint
;
2755 return fState
->which_view_color
;
2760 BView::ForceFontAliasing(bool enable
)
2762 if (fState
->IsValid(B_VIEW_FONT_ALIASING_BIT
)
2763 && enable
== fState
->font_aliasing
)
2767 _CheckLockAndSwitchCurrent();
2769 fOwner
->fLink
->StartMessage(AS_VIEW_PRINT_ALIASING
);
2770 fOwner
->fLink
->Attach
<bool>(enable
);
2772 fState
->valid_flags
|= B_VIEW_FONT_ALIASING_BIT
;
2775 fState
->font_aliasing
= enable
;
2776 fState
->archiving_flags
|= B_VIEW_FONT_ALIASING_BIT
;
2781 BView::SetFont(const BFont
* font
, uint32 mask
)
2783 if (!font
|| mask
== 0)
2786 if (mask
== B_FONT_ALL
) {
2787 fState
->font
= *font
;
2789 // TODO: move this into a BFont method
2790 if (mask
& B_FONT_FAMILY_AND_STYLE
)
2791 fState
->font
.SetFamilyAndStyle(font
->FamilyAndStyle());
2793 if (mask
& B_FONT_SIZE
)
2794 fState
->font
.SetSize(font
->Size());
2796 if (mask
& B_FONT_SHEAR
)
2797 fState
->font
.SetShear(font
->Shear());
2799 if (mask
& B_FONT_ROTATION
)
2800 fState
->font
.SetRotation(font
->Rotation());
2802 if (mask
& B_FONT_FALSE_BOLD_WIDTH
)
2803 fState
->font
.SetFalseBoldWidth(font
->FalseBoldWidth());
2805 if (mask
& B_FONT_SPACING
)
2806 fState
->font
.SetSpacing(font
->Spacing());
2808 if (mask
& B_FONT_ENCODING
)
2809 fState
->font
.SetEncoding(font
->Encoding());
2811 if (mask
& B_FONT_FACE
)
2812 fState
->font
.SetFace(font
->Face());
2814 if (mask
& B_FONT_FLAGS
)
2815 fState
->font
.SetFlags(font
->Flags());
2818 fState
->font_flags
|= mask
;
2821 _CheckLockAndSwitchCurrent();
2823 fState
->UpdateServerFontState(*fOwner
->fLink
);
2824 fState
->valid_flags
|= B_VIEW_FONT_BIT
;
2827 fState
->archiving_flags
|= B_VIEW_FONT_BIT
;
2828 // TODO: InvalidateLayout() here for convenience?
2833 BView::GetFont(BFont
* font
) const
2835 if (!fState
->IsValid(B_VIEW_FONT_BIT
)) {
2836 // we don't keep graphics state information, therefor
2837 // we need to ask the server for the origin after PopState()
2838 _CheckOwnerLockAndSwitchCurrent();
2840 // TODO: add a font getter!
2841 fState
->UpdateFrom(*fOwner
->fLink
);
2844 *font
= fState
->font
;
2849 BView::GetFontHeight(font_height
* height
) const
2851 fState
->font
.GetHeight(height
);
2856 BView::SetFontSize(float size
)
2861 SetFont(&font
, B_FONT_SIZE
);
2866 BView::StringWidth(const char* string
) const
2868 return fState
->font
.StringWidth(string
);
2873 BView::StringWidth(const char* string
, int32 length
) const
2875 return fState
->font
.StringWidth(string
, length
);
2880 BView::GetStringWidths(char* stringArray
[], int32 lengthArray
[],
2881 int32 numStrings
, float widthArray
[]) const
2883 fState
->font
.GetStringWidths(const_cast<const char**>(stringArray
),
2884 const_cast<const int32
*>(lengthArray
), numStrings
, widthArray
);
2889 BView::TruncateString(BString
* string
, uint32 mode
, float width
) const
2891 fState
->font
.TruncateString(string
, mode
, width
);
2896 BView::ClipToPicture(BPicture
* picture
, BPoint where
, bool sync
)
2898 _ClipToPicture(picture
, where
, false, sync
);
2903 BView::ClipToInversePicture(BPicture
* picture
, BPoint where
, bool sync
)
2905 _ClipToPicture(picture
, where
, true, sync
);
2910 BView::GetClippingRegion(BRegion
* region
) const
2915 // NOTE: the client has no idea when the clipping in the server
2916 // changed, so it is always read from the server
2917 region
->MakeEmpty();
2921 if (fIsPrinting
&& _CheckOwnerLock()) {
2922 region
->Set(fState
->print_rect
);
2926 _CheckLockAndSwitchCurrent();
2927 fOwner
->fLink
->StartMessage(AS_VIEW_GET_CLIP_REGION
);
2930 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
2932 fOwner
->fLink
->ReadRegion(region
);
2933 fState
->valid_flags
|= B_VIEW_CLIP_REGION_BIT
;
2940 BView::ConstrainClippingRegion(BRegion
* region
)
2942 if (_CheckOwnerLockAndSwitchCurrent()) {
2943 fOwner
->fLink
->StartMessage(AS_VIEW_SET_CLIP_REGION
);
2946 int32 count
= region
->CountRects();
2947 fOwner
->fLink
->Attach
<int32
>(count
);
2949 fOwner
->fLink
->AttachRegion(*region
);
2951 fOwner
->fLink
->Attach
<int32
>(-1);
2952 // '-1' means that in the app_server, there won't be any 'local'
2953 // clipping region (it will be NULL)
2956 _FlushIfNotInTransaction();
2958 fState
->valid_flags
&= ~B_VIEW_CLIP_REGION_BIT
;
2959 fState
->archiving_flags
|= B_VIEW_CLIP_REGION_BIT
;
2965 BView::ClipToRect(BRect rect
)
2967 _ClipToRect(rect
, false);
2972 BView::ClipToInverseRect(BRect rect
)
2974 _ClipToRect(rect
, true);
2979 BView::ClipToShape(BShape
* shape
)
2981 _ClipToShape(shape
, false);
2986 BView::ClipToInverseShape(BShape
* shape
)
2988 _ClipToShape(shape
, true);
2992 // #pragma mark - Drawing Functions
2996 BView::DrawBitmapAsync(const BBitmap
* bitmap
, BRect bitmapRect
, BRect viewRect
,
2999 if (bitmap
== NULL
|| fOwner
== NULL
3000 || !bitmapRect
.IsValid() || !viewRect
.IsValid())
3003 _CheckLockAndSwitchCurrent();
3005 ViewDrawBitmapInfo info
;
3006 info
.bitmapToken
= bitmap
->_ServerToken();
3007 info
.options
= options
;
3008 info
.viewRect
= viewRect
;
3009 info
.bitmapRect
= bitmapRect
;
3011 fOwner
->fLink
->StartMessage(AS_VIEW_DRAW_BITMAP
);
3012 fOwner
->fLink
->Attach
<ViewDrawBitmapInfo
>(info
);
3014 _FlushIfNotInTransaction();
3019 BView::DrawBitmapAsync(const BBitmap
* bitmap
, BRect bitmapRect
, BRect viewRect
)
3021 DrawBitmapAsync(bitmap
, bitmapRect
, viewRect
, 0);
3026 BView::DrawBitmapAsync(const BBitmap
* bitmap
, BRect viewRect
)
3028 if (bitmap
&& fOwner
) {
3029 DrawBitmapAsync(bitmap
, bitmap
->Bounds().OffsetToCopy(B_ORIGIN
),
3036 BView::DrawBitmapAsync(const BBitmap
* bitmap
, BPoint where
)
3038 if (bitmap
== NULL
|| fOwner
== NULL
)
3041 _CheckLockAndSwitchCurrent();
3043 ViewDrawBitmapInfo info
;
3044 info
.bitmapToken
= bitmap
->_ServerToken();
3046 info
.bitmapRect
= bitmap
->Bounds().OffsetToCopy(B_ORIGIN
);
3047 info
.viewRect
= info
.bitmapRect
.OffsetToCopy(where
);
3049 fOwner
->fLink
->StartMessage(AS_VIEW_DRAW_BITMAP
);
3050 fOwner
->fLink
->Attach
<ViewDrawBitmapInfo
>(info
);
3052 _FlushIfNotInTransaction();
3057 BView::DrawBitmapAsync(const BBitmap
* bitmap
)
3059 DrawBitmapAsync(bitmap
, PenLocation());
3064 BView::DrawBitmap(const BBitmap
* bitmap
, BRect bitmapRect
, BRect viewRect
,
3068 DrawBitmapAsync(bitmap
, bitmapRect
, viewRect
, options
);
3075 BView::DrawBitmap(const BBitmap
* bitmap
, BRect bitmapRect
, BRect viewRect
)
3078 DrawBitmapAsync(bitmap
, bitmapRect
, viewRect
, 0);
3085 BView::DrawBitmap(const BBitmap
* bitmap
, BRect viewRect
)
3087 if (bitmap
&& fOwner
) {
3088 DrawBitmap(bitmap
, bitmap
->Bounds().OffsetToCopy(B_ORIGIN
), viewRect
,
3095 BView::DrawBitmap(const BBitmap
* bitmap
, BPoint where
)
3098 DrawBitmapAsync(bitmap
, where
);
3105 BView::DrawBitmap(const BBitmap
* bitmap
)
3107 DrawBitmap(bitmap
, PenLocation());
3112 BView::DrawChar(char c
)
3114 DrawString(&c
, 1, PenLocation());
3119 BView::DrawChar(char c
, BPoint location
)
3121 DrawString(&c
, 1, location
);
3126 BView::DrawString(const char* string
, escapement_delta
* delta
)
3131 DrawString(string
, strlen(string
), PenLocation(), delta
);
3136 BView::DrawString(const char* string
, BPoint location
, escapement_delta
* delta
)
3141 DrawString(string
, strlen(string
), location
, delta
);
3146 BView::DrawString(const char* string
, int32 length
, escapement_delta
* delta
)
3148 DrawString(string
, length
, PenLocation(), delta
);
3153 BView::DrawString(const char* string
, int32 length
, BPoint location
,
3154 escapement_delta
* delta
)
3156 if (fOwner
== NULL
|| string
== NULL
|| length
< 1)
3159 _CheckLockAndSwitchCurrent();
3161 ViewDrawStringInfo info
;
3162 info
.stringLength
= length
;
3163 info
.location
= location
;
3165 info
.delta
= *delta
;
3167 // quite often delta will be NULL
3169 fOwner
->fLink
->StartMessage(AS_DRAW_STRING_WITH_DELTA
);
3171 fOwner
->fLink
->StartMessage(AS_DRAW_STRING
);
3173 fOwner
->fLink
->Attach
<ViewDrawStringInfo
>(info
);
3174 fOwner
->fLink
->Attach(string
, length
);
3176 _FlushIfNotInTransaction();
3178 // this modifies our pen location, so we invalidate the flag.
3179 fState
->valid_flags
&= ~B_VIEW_PEN_LOCATION_BIT
;
3184 BView::DrawString(const char* string
, const BPoint
* locations
,
3185 int32 locationCount
)
3190 DrawString(string
, strlen(string
), locations
, locationCount
);
3195 BView::DrawString(const char* string
, int32 length
, const BPoint
* locations
,
3196 int32 locationCount
)
3198 if (fOwner
== NULL
|| string
== NULL
|| length
< 1 || locations
== NULL
)
3201 _CheckLockAndSwitchCurrent();
3203 fOwner
->fLink
->StartMessage(AS_DRAW_STRING_WITH_OFFSETS
);
3205 fOwner
->fLink
->Attach
<int32
>(length
);
3206 fOwner
->fLink
->Attach
<int32
>(locationCount
);
3207 fOwner
->fLink
->Attach(string
, length
);
3208 fOwner
->fLink
->Attach(locations
, locationCount
* sizeof(BPoint
));
3210 _FlushIfNotInTransaction();
3212 // this modifies our pen location, so we invalidate the flag.
3213 fState
->valid_flags
&= ~B_VIEW_PEN_LOCATION_BIT
;
3218 BView::StrokeEllipse(BPoint center
, float xRadius
, float yRadius
,
3221 StrokeEllipse(BRect(center
.x
- xRadius
, center
.y
- yRadius
,
3222 center
.x
+ xRadius
, center
.y
+ yRadius
), pattern
);
3227 BView::StrokeEllipse(BRect rect
, ::pattern pattern
)
3232 _CheckLockAndSwitchCurrent();
3233 _UpdatePattern(pattern
);
3235 fOwner
->fLink
->StartMessage(AS_STROKE_ELLIPSE
);
3236 fOwner
->fLink
->Attach
<BRect
>(rect
);
3238 _FlushIfNotInTransaction();
3243 BView::FillEllipse(BPoint center
, float xRadius
, float yRadius
,
3246 FillEllipse(BRect(center
.x
- xRadius
, center
.y
- yRadius
,
3247 center
.x
+ xRadius
, center
.y
+ yRadius
), pattern
);
3252 BView::FillEllipse(BPoint center
, float xRadius
, float yRadius
,
3253 const BGradient
& gradient
)
3255 FillEllipse(BRect(center
.x
- xRadius
, center
.y
- yRadius
,
3256 center
.x
+ xRadius
, center
.y
+ yRadius
), gradient
);
3261 BView::FillEllipse(BRect rect
, ::pattern pattern
)
3266 _CheckLockAndSwitchCurrent();
3267 _UpdatePattern(pattern
);
3269 fOwner
->fLink
->StartMessage(AS_FILL_ELLIPSE
);
3270 fOwner
->fLink
->Attach
<BRect
>(rect
);
3272 _FlushIfNotInTransaction();
3277 BView::FillEllipse(BRect rect
, const BGradient
& gradient
)
3282 _CheckLockAndSwitchCurrent();
3284 fOwner
->fLink
->StartMessage(AS_FILL_ELLIPSE_GRADIENT
);
3285 fOwner
->fLink
->Attach
<BRect
>(rect
);
3286 fOwner
->fLink
->AttachGradient(gradient
);
3288 _FlushIfNotInTransaction();
3293 BView::StrokeArc(BPoint center
, float xRadius
, float yRadius
, float startAngle
,
3294 float arcAngle
, ::pattern pattern
)
3296 StrokeArc(BRect(center
.x
- xRadius
, center
.y
- yRadius
, center
.x
+ xRadius
,
3297 center
.y
+ yRadius
), startAngle
, arcAngle
, pattern
);
3302 BView::StrokeArc(BRect rect
, float startAngle
, float arcAngle
,
3308 _CheckLockAndSwitchCurrent();
3309 _UpdatePattern(pattern
);
3311 fOwner
->fLink
->StartMessage(AS_STROKE_ARC
);
3312 fOwner
->fLink
->Attach
<BRect
>(rect
);
3313 fOwner
->fLink
->Attach
<float>(startAngle
);
3314 fOwner
->fLink
->Attach
<float>(arcAngle
);
3316 _FlushIfNotInTransaction();
3321 BView::FillArc(BPoint center
,float xRadius
, float yRadius
, float startAngle
,
3322 float arcAngle
, ::pattern pattern
)
3324 FillArc(BRect(center
.x
- xRadius
, center
.y
- yRadius
, center
.x
+ xRadius
,
3325 center
.y
+ yRadius
), startAngle
, arcAngle
, pattern
);
3330 BView::FillArc(BPoint center
,float xRadius
, float yRadius
, float startAngle
,
3331 float arcAngle
, const BGradient
& gradient
)
3333 FillArc(BRect(center
.x
- xRadius
, center
.y
- yRadius
, center
.x
+ xRadius
,
3334 center
.y
+ yRadius
), startAngle
, arcAngle
, gradient
);
3339 BView::FillArc(BRect rect
, float startAngle
, float arcAngle
,
3345 _CheckLockAndSwitchCurrent();
3346 _UpdatePattern(pattern
);
3348 fOwner
->fLink
->StartMessage(AS_FILL_ARC
);
3349 fOwner
->fLink
->Attach
<BRect
>(rect
);
3350 fOwner
->fLink
->Attach
<float>(startAngle
);
3351 fOwner
->fLink
->Attach
<float>(arcAngle
);
3353 _FlushIfNotInTransaction();
3358 BView::FillArc(BRect rect
, float startAngle
, float arcAngle
,
3359 const BGradient
& gradient
)
3364 _CheckLockAndSwitchCurrent();
3366 fOwner
->fLink
->StartMessage(AS_FILL_ARC_GRADIENT
);
3367 fOwner
->fLink
->Attach
<BRect
>(rect
);
3368 fOwner
->fLink
->Attach
<float>(startAngle
);
3369 fOwner
->fLink
->Attach
<float>(arcAngle
);
3370 fOwner
->fLink
->AttachGradient(gradient
);
3372 _FlushIfNotInTransaction();
3377 BView::StrokeBezier(BPoint
* controlPoints
, ::pattern pattern
)
3382 _CheckLockAndSwitchCurrent();
3383 _UpdatePattern(pattern
);
3385 fOwner
->fLink
->StartMessage(AS_STROKE_BEZIER
);
3386 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[0]);
3387 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[1]);
3388 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[2]);
3389 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[3]);
3391 _FlushIfNotInTransaction();
3396 BView::FillBezier(BPoint
* controlPoints
, ::pattern pattern
)
3401 _CheckLockAndSwitchCurrent();
3402 _UpdatePattern(pattern
);
3404 fOwner
->fLink
->StartMessage(AS_FILL_BEZIER
);
3405 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[0]);
3406 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[1]);
3407 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[2]);
3408 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[3]);
3410 _FlushIfNotInTransaction();
3415 BView::FillBezier(BPoint
* controlPoints
, const BGradient
& gradient
)
3420 _CheckLockAndSwitchCurrent();
3422 fOwner
->fLink
->StartMessage(AS_FILL_BEZIER_GRADIENT
);
3423 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[0]);
3424 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[1]);
3425 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[2]);
3426 fOwner
->fLink
->Attach
<BPoint
>(controlPoints
[3]);
3427 fOwner
->fLink
->AttachGradient(gradient
);
3429 _FlushIfNotInTransaction();
3434 BView::StrokePolygon(const BPolygon
* polygon
, bool closed
, ::pattern pattern
)
3436 if (polygon
== NULL
)
3439 StrokePolygon(polygon
->fPoints
, polygon
->fCount
, polygon
->Frame(), closed
,
3445 BView::StrokePolygon(const BPoint
* pointArray
, int32 numPoints
, bool closed
,
3448 BPolygon
polygon(pointArray
, numPoints
);
3450 StrokePolygon(polygon
.fPoints
, polygon
.fCount
, polygon
.Frame(), closed
,
3456 BView::StrokePolygon(const BPoint
* pointArray
, int32 numPoints
, BRect bounds
,
3457 bool closed
, ::pattern pattern
)
3459 if (pointArray
== NULL
3464 _CheckLockAndSwitchCurrent();
3465 _UpdatePattern(pattern
);
3467 BPolygon
polygon(pointArray
, numPoints
);
3468 polygon
.MapTo(polygon
.Frame(), bounds
);
3470 if (fOwner
->fLink
->StartMessage(AS_STROKE_POLYGON
,
3471 polygon
.fCount
* sizeof(BPoint
) + sizeof(BRect
) + sizeof(bool)
3472 + sizeof(int32
)) == B_OK
) {
3473 fOwner
->fLink
->Attach
<BRect
>(polygon
.Frame());
3474 fOwner
->fLink
->Attach
<bool>(closed
);
3475 fOwner
->fLink
->Attach
<int32
>(polygon
.fCount
);
3476 fOwner
->fLink
->Attach(polygon
.fPoints
, polygon
.fCount
* sizeof(BPoint
));
3478 _FlushIfNotInTransaction();
3480 fprintf(stderr
, "ERROR: Can't send polygon to app_server!\n");
3486 BView::FillPolygon(const BPolygon
* polygon
, ::pattern pattern
)
3489 || polygon
->fCount
<= 2
3493 _CheckLockAndSwitchCurrent();
3494 _UpdatePattern(pattern
);
3496 if (fOwner
->fLink
->StartMessage(AS_FILL_POLYGON
,
3497 polygon
->fCount
* sizeof(BPoint
) + sizeof(BRect
) + sizeof(int32
))
3499 fOwner
->fLink
->Attach
<BRect
>(polygon
->Frame());
3500 fOwner
->fLink
->Attach
<int32
>(polygon
->fCount
);
3501 fOwner
->fLink
->Attach(polygon
->fPoints
,
3502 polygon
->fCount
* sizeof(BPoint
));
3504 _FlushIfNotInTransaction();
3506 fprintf(stderr
, "ERROR: Can't send polygon to app_server!\n");
3512 BView::FillPolygon(const BPolygon
* polygon
, const BGradient
& gradient
)
3515 || polygon
->fCount
<= 2
3519 _CheckLockAndSwitchCurrent();
3521 if (fOwner
->fLink
->StartMessage(AS_FILL_POLYGON_GRADIENT
,
3522 polygon
->fCount
* sizeof(BPoint
) + sizeof(BRect
) + sizeof(int32
))
3524 fOwner
->fLink
->Attach
<BRect
>(polygon
->Frame());
3525 fOwner
->fLink
->Attach
<int32
>(polygon
->fCount
);
3526 fOwner
->fLink
->Attach(polygon
->fPoints
,
3527 polygon
->fCount
* sizeof(BPoint
));
3528 fOwner
->fLink
->AttachGradient(gradient
);
3530 _FlushIfNotInTransaction();
3532 fprintf(stderr
, "ERROR: Can't send polygon to app_server!\n");
3538 BView::FillPolygon(const BPoint
* pointArray
, int32 numPoints
, ::pattern pattern
)
3540 if (pointArray
== NULL
)
3543 BPolygon
polygon(pointArray
, numPoints
);
3544 FillPolygon(&polygon
, pattern
);
3549 BView::FillPolygon(const BPoint
* pointArray
, int32 numPoints
,
3550 const BGradient
& gradient
)
3552 if (pointArray
== NULL
)
3555 BPolygon
polygon(pointArray
, numPoints
);
3556 FillPolygon(&polygon
, gradient
);
3561 BView::FillPolygon(const BPoint
* pointArray
, int32 numPoints
, BRect bounds
,
3564 if (pointArray
== NULL
)
3567 BPolygon
polygon(pointArray
, numPoints
);
3569 polygon
.MapTo(polygon
.Frame(), bounds
);
3570 FillPolygon(&polygon
, pattern
);
3575 BView::FillPolygon(const BPoint
* pointArray
, int32 numPoints
, BRect bounds
,
3576 const BGradient
& gradient
)
3578 if (pointArray
== NULL
)
3581 BPolygon
polygon(pointArray
, numPoints
);
3583 polygon
.MapTo(polygon
.Frame(), bounds
);
3584 FillPolygon(&polygon
, gradient
);
3589 BView::StrokeRect(BRect rect
, ::pattern pattern
)
3594 _CheckLockAndSwitchCurrent();
3595 _UpdatePattern(pattern
);
3597 fOwner
->fLink
->StartMessage(AS_STROKE_RECT
);
3598 fOwner
->fLink
->Attach
<BRect
>(rect
);
3600 _FlushIfNotInTransaction();
3605 BView::FillRect(BRect rect
, ::pattern pattern
)
3610 // NOTE: ensuring compatibility with R5,
3611 // invalid rects are not filled, they are stroked though!
3612 if (!rect
.IsValid())
3615 _CheckLockAndSwitchCurrent();
3616 _UpdatePattern(pattern
);
3618 fOwner
->fLink
->StartMessage(AS_FILL_RECT
);
3619 fOwner
->fLink
->Attach
<BRect
>(rect
);
3621 _FlushIfNotInTransaction();
3626 BView::FillRect(BRect rect
, const BGradient
& gradient
)
3631 // NOTE: ensuring compatibility with R5,
3632 // invalid rects are not filled, they are stroked though!
3633 if (!rect
.IsValid())
3636 _CheckLockAndSwitchCurrent();
3638 fOwner
->fLink
->StartMessage(AS_FILL_RECT_GRADIENT
);
3639 fOwner
->fLink
->Attach
<BRect
>(rect
);
3640 fOwner
->fLink
->AttachGradient(gradient
);
3642 _FlushIfNotInTransaction();
3647 BView::StrokeRoundRect(BRect rect
, float xRadius
, float yRadius
,
3653 _CheckLockAndSwitchCurrent();
3654 _UpdatePattern(pattern
);
3656 fOwner
->fLink
->StartMessage(AS_STROKE_ROUNDRECT
);
3657 fOwner
->fLink
->Attach
<BRect
>(rect
);
3658 fOwner
->fLink
->Attach
<float>(xRadius
);
3659 fOwner
->fLink
->Attach
<float>(yRadius
);
3661 _FlushIfNotInTransaction();
3666 BView::FillRoundRect(BRect rect
, float xRadius
, float yRadius
,
3672 _CheckLockAndSwitchCurrent();
3674 _UpdatePattern(pattern
);
3676 fOwner
->fLink
->StartMessage(AS_FILL_ROUNDRECT
);
3677 fOwner
->fLink
->Attach
<BRect
>(rect
);
3678 fOwner
->fLink
->Attach
<float>(xRadius
);
3679 fOwner
->fLink
->Attach
<float>(yRadius
);
3681 _FlushIfNotInTransaction();
3686 BView::FillRoundRect(BRect rect
, float xRadius
, float yRadius
,
3687 const BGradient
& gradient
)
3692 _CheckLockAndSwitchCurrent();
3694 fOwner
->fLink
->StartMessage(AS_FILL_ROUNDRECT_GRADIENT
);
3695 fOwner
->fLink
->Attach
<BRect
>(rect
);
3696 fOwner
->fLink
->Attach
<float>(xRadius
);
3697 fOwner
->fLink
->Attach
<float>(yRadius
);
3698 fOwner
->fLink
->AttachGradient(gradient
);
3700 _FlushIfNotInTransaction();
3705 BView::FillRegion(BRegion
* region
, ::pattern pattern
)
3707 if (region
== NULL
|| fOwner
== NULL
)
3710 _CheckLockAndSwitchCurrent();
3712 _UpdatePattern(pattern
);
3714 fOwner
->fLink
->StartMessage(AS_FILL_REGION
);
3715 fOwner
->fLink
->AttachRegion(*region
);
3717 _FlushIfNotInTransaction();
3722 BView::FillRegion(BRegion
* region
, const BGradient
& gradient
)
3724 if (region
== NULL
|| fOwner
== NULL
)
3727 _CheckLockAndSwitchCurrent();
3729 fOwner
->fLink
->StartMessage(AS_FILL_REGION_GRADIENT
);
3730 fOwner
->fLink
->AttachRegion(*region
);
3731 fOwner
->fLink
->AttachGradient(gradient
);
3733 _FlushIfNotInTransaction();
3738 BView::StrokeTriangle(BPoint point1
, BPoint point2
, BPoint point3
, BRect bounds
,
3744 _CheckLockAndSwitchCurrent();
3746 _UpdatePattern(pattern
);
3748 fOwner
->fLink
->StartMessage(AS_STROKE_TRIANGLE
);
3749 fOwner
->fLink
->Attach
<BPoint
>(point1
);
3750 fOwner
->fLink
->Attach
<BPoint
>(point2
);
3751 fOwner
->fLink
->Attach
<BPoint
>(point3
);
3752 fOwner
->fLink
->Attach
<BRect
>(bounds
);
3754 _FlushIfNotInTransaction();
3759 BView::StrokeTriangle(BPoint point1
, BPoint point2
, BPoint point3
,
3763 // we construct the smallest rectangle that contains the 3 points
3764 // for the 1st point
3765 BRect
bounds(point1
, point1
);
3767 // for the 2nd point
3768 if (point2
.x
< bounds
.left
)
3769 bounds
.left
= point2
.x
;
3771 if (point2
.y
< bounds
.top
)
3772 bounds
.top
= point2
.y
;
3774 if (point2
.x
> bounds
.right
)
3775 bounds
.right
= point2
.x
;
3777 if (point2
.y
> bounds
.bottom
)
3778 bounds
.bottom
= point2
.y
;
3780 // for the 3rd point
3781 if (point3
.x
< bounds
.left
)
3782 bounds
.left
= point3
.x
;
3784 if (point3
.y
< bounds
.top
)
3785 bounds
.top
= point3
.y
;
3787 if (point3
.x
> bounds
.right
)
3788 bounds
.right
= point3
.x
;
3790 if (point3
.y
> bounds
.bottom
)
3791 bounds
.bottom
= point3
.y
;
3793 StrokeTriangle(point1
, point2
, point3
, bounds
, pattern
);
3799 BView::FillTriangle(BPoint point1
, BPoint point2
, BPoint point3
,
3803 // we construct the smallest rectangle that contains the 3 points
3804 // for the 1st point
3805 BRect
bounds(point1
, point1
);
3807 // for the 2nd point
3808 if (point2
.x
< bounds
.left
)
3809 bounds
.left
= point2
.x
;
3811 if (point2
.y
< bounds
.top
)
3812 bounds
.top
= point2
.y
;
3814 if (point2
.x
> bounds
.right
)
3815 bounds
.right
= point2
.x
;
3817 if (point2
.y
> bounds
.bottom
)
3818 bounds
.bottom
= point2
.y
;
3820 // for the 3rd point
3821 if (point3
.x
< bounds
.left
)
3822 bounds
.left
= point3
.x
;
3824 if (point3
.y
< bounds
.top
)
3825 bounds
.top
= point3
.y
;
3827 if (point3
.x
> bounds
.right
)
3828 bounds
.right
= point3
.x
;
3830 if (point3
.y
> bounds
.bottom
)
3831 bounds
.bottom
= point3
.y
;
3833 FillTriangle(point1
, point2
, point3
, bounds
, pattern
);
3839 BView::FillTriangle(BPoint point1
, BPoint point2
, BPoint point3
,
3840 const BGradient
& gradient
)
3843 // we construct the smallest rectangle that contains the 3 points
3844 // for the 1st point
3845 BRect
bounds(point1
, point1
);
3847 // for the 2nd point
3848 if (point2
.x
< bounds
.left
)
3849 bounds
.left
= point2
.x
;
3851 if (point2
.y
< bounds
.top
)
3852 bounds
.top
= point2
.y
;
3854 if (point2
.x
> bounds
.right
)
3855 bounds
.right
= point2
.x
;
3857 if (point2
.y
> bounds
.bottom
)
3858 bounds
.bottom
= point2
.y
;
3860 // for the 3rd point
3861 if (point3
.x
< bounds
.left
)
3862 bounds
.left
= point3
.x
;
3864 if (point3
.y
< bounds
.top
)
3865 bounds
.top
= point3
.y
;
3867 if (point3
.x
> bounds
.right
)
3868 bounds
.right
= point3
.x
;
3870 if (point3
.y
> bounds
.bottom
)
3871 bounds
.bottom
= point3
.y
;
3873 FillTriangle(point1
, point2
, point3
, bounds
, gradient
);
3879 BView::FillTriangle(BPoint point1
, BPoint point2
, BPoint point3
,
3880 BRect bounds
, ::pattern pattern
)
3885 _CheckLockAndSwitchCurrent();
3886 _UpdatePattern(pattern
);
3888 fOwner
->fLink
->StartMessage(AS_FILL_TRIANGLE
);
3889 fOwner
->fLink
->Attach
<BPoint
>(point1
);
3890 fOwner
->fLink
->Attach
<BPoint
>(point2
);
3891 fOwner
->fLink
->Attach
<BPoint
>(point3
);
3892 fOwner
->fLink
->Attach
<BRect
>(bounds
);
3894 _FlushIfNotInTransaction();
3899 BView::FillTriangle(BPoint point1
, BPoint point2
, BPoint point3
, BRect bounds
,
3900 const BGradient
& gradient
)
3905 _CheckLockAndSwitchCurrent();
3906 fOwner
->fLink
->StartMessage(AS_FILL_TRIANGLE_GRADIENT
);
3907 fOwner
->fLink
->Attach
<BPoint
>(point1
);
3908 fOwner
->fLink
->Attach
<BPoint
>(point2
);
3909 fOwner
->fLink
->Attach
<BPoint
>(point3
);
3910 fOwner
->fLink
->Attach
<BRect
>(bounds
);
3911 fOwner
->fLink
->AttachGradient(gradient
);
3913 _FlushIfNotInTransaction();
3918 BView::StrokeLine(BPoint toPoint
, ::pattern pattern
)
3920 StrokeLine(PenLocation(), toPoint
, pattern
);
3925 BView::StrokeLine(BPoint start
, BPoint end
, ::pattern pattern
)
3930 _CheckLockAndSwitchCurrent();
3931 _UpdatePattern(pattern
);
3933 ViewStrokeLineInfo info
;
3934 info
.startPoint
= start
;
3935 info
.endPoint
= end
;
3937 fOwner
->fLink
->StartMessage(AS_STROKE_LINE
);
3938 fOwner
->fLink
->Attach
<ViewStrokeLineInfo
>(info
);
3940 _FlushIfNotInTransaction();
3942 // this modifies our pen location, so we invalidate the flag.
3943 fState
->valid_flags
&= ~B_VIEW_PEN_LOCATION_BIT
;
3948 BView::StrokeShape(BShape
* shape
, ::pattern pattern
)
3950 if (shape
== NULL
|| fOwner
== NULL
)
3953 shape_data
* sd
= (shape_data
*)shape
->fPrivateData
;
3954 if (sd
->opCount
== 0 || sd
->ptCount
== 0)
3957 _CheckLockAndSwitchCurrent();
3958 _UpdatePattern(pattern
);
3960 fOwner
->fLink
->StartMessage(AS_STROKE_SHAPE
);
3961 fOwner
->fLink
->Attach
<BRect
>(shape
->Bounds());
3962 fOwner
->fLink
->Attach
<int32
>(sd
->opCount
);
3963 fOwner
->fLink
->Attach
<int32
>(sd
->ptCount
);
3964 fOwner
->fLink
->Attach(sd
->opList
, sd
->opCount
* sizeof(uint32
));
3965 fOwner
->fLink
->Attach(sd
->ptList
, sd
->ptCount
* sizeof(BPoint
));
3967 _FlushIfNotInTransaction();
3972 BView::FillShape(BShape
* shape
, ::pattern pattern
)
3974 if (shape
== NULL
|| fOwner
== NULL
)
3977 shape_data
* sd
= (shape_data
*)(shape
->fPrivateData
);
3978 if (sd
->opCount
== 0 || sd
->ptCount
== 0)
3981 _CheckLockAndSwitchCurrent();
3982 _UpdatePattern(pattern
);
3984 fOwner
->fLink
->StartMessage(AS_FILL_SHAPE
);
3985 fOwner
->fLink
->Attach
<BRect
>(shape
->Bounds());
3986 fOwner
->fLink
->Attach
<int32
>(sd
->opCount
);
3987 fOwner
->fLink
->Attach
<int32
>(sd
->ptCount
);
3988 fOwner
->fLink
->Attach(sd
->opList
, sd
->opCount
* sizeof(int32
));
3989 fOwner
->fLink
->Attach(sd
->ptList
, sd
->ptCount
* sizeof(BPoint
));
3991 _FlushIfNotInTransaction();
3996 BView::FillShape(BShape
* shape
, const BGradient
& gradient
)
3998 if (shape
== NULL
|| fOwner
== NULL
)
4001 shape_data
* sd
= (shape_data
*)(shape
->fPrivateData
);
4002 if (sd
->opCount
== 0 || sd
->ptCount
== 0)
4005 _CheckLockAndSwitchCurrent();
4007 fOwner
->fLink
->StartMessage(AS_FILL_SHAPE_GRADIENT
);
4008 fOwner
->fLink
->Attach
<BRect
>(shape
->Bounds());
4009 fOwner
->fLink
->Attach
<int32
>(sd
->opCount
);
4010 fOwner
->fLink
->Attach
<int32
>(sd
->ptCount
);
4011 fOwner
->fLink
->Attach(sd
->opList
, sd
->opCount
* sizeof(int32
));
4012 fOwner
->fLink
->Attach(sd
->ptList
, sd
->ptCount
* sizeof(BPoint
));
4013 fOwner
->fLink
->AttachGradient(gradient
);
4015 _FlushIfNotInTransaction();
4020 BView::BeginLineArray(int32 count
)
4026 debugger("Calling BeginLineArray with a count <= 0");
4031 debugger("Can't nest BeginLineArray calls");
4032 // not fatal, but it helps during
4033 // development of your app and is in
4035 delete[] fCommArray
->array
;
4039 // TODO: since this method cannot return failure, and further AddLine()
4040 // calls with a NULL fCommArray would drop into the debugger anyway,
4041 // we allow the possible std::bad_alloc exceptions here...
4042 fCommArray
= new _array_data_
;
4043 fCommArray
->count
= 0;
4045 // Make sure the fCommArray is initialized to reasonable values in cases of
4046 // bad_alloc. At least the exception can be caught and EndLineArray won't
4048 fCommArray
->array
= NULL
;
4049 fCommArray
->maxCount
= 0;
4051 fCommArray
->array
= new ViewLineArrayInfo
[count
];
4052 fCommArray
->maxCount
= count
;
4057 BView::AddLine(BPoint start
, BPoint end
, rgb_color color
)
4063 debugger("BeginLineArray must be called before using AddLine");
4067 const uint32
&arrayCount
= fCommArray
->count
;
4068 if (arrayCount
< fCommArray
->maxCount
) {
4069 fCommArray
->array
[arrayCount
].startPoint
= start
;
4070 fCommArray
->array
[arrayCount
].endPoint
= end
;
4071 fCommArray
->array
[arrayCount
].color
= color
;
4073 fCommArray
->count
++;
4079 BView::EndLineArray()
4084 if (fCommArray
== NULL
)
4085 debugger("Can't call EndLineArray before BeginLineArray");
4087 _CheckLockAndSwitchCurrent();
4089 fOwner
->fLink
->StartMessage(AS_STROKE_LINEARRAY
);
4090 fOwner
->fLink
->Attach
<int32
>(fCommArray
->count
);
4091 fOwner
->fLink
->Attach(fCommArray
->array
,
4092 fCommArray
->count
* sizeof(ViewLineArrayInfo
));
4094 _FlushIfNotInTransaction();
4101 BView::SetDiskMode(char* filename
, long offset
)
4104 // One BeBook version has this to say about SetDiskMode():
4106 // "Begins recording a picture to the file with the given filename
4107 // at the given offset. Subsequent drawing commands sent to the view
4108 // will be written to the file until EndPicture() is called. The
4109 // stored commands may be played from the file with DrawPicture()."
4114 BView::BeginPicture(BPicture
* picture
)
4116 if (_CheckOwnerLockAndSwitchCurrent()
4117 && picture
&& picture
->fUsurped
== NULL
) {
4118 picture
->Usurp(fCurrentPicture
);
4119 fCurrentPicture
= picture
;
4121 fOwner
->fLink
->StartMessage(AS_VIEW_BEGIN_PICTURE
);
4127 BView::AppendToPicture(BPicture
* picture
)
4129 _CheckLockAndSwitchCurrent();
4131 if (picture
&& picture
->fUsurped
== NULL
) {
4132 int32 token
= picture
->Token();
4135 BeginPicture(picture
);
4137 picture
->SetToken(-1);
4138 picture
->Usurp(fCurrentPicture
);
4139 fCurrentPicture
= picture
;
4140 fOwner
->fLink
->StartMessage(AS_VIEW_APPEND_TO_PICTURE
);
4141 fOwner
->fLink
->Attach
<int32
>(token
);
4150 if (_CheckOwnerLockAndSwitchCurrent() && fCurrentPicture
) {
4153 fOwner
->fLink
->StartMessage(AS_VIEW_END_PICTURE
);
4156 if (fOwner
->fLink
->FlushWithReply(code
) == B_OK
4158 && fOwner
->fLink
->Read
<int32
>(&token
) == B_OK
) {
4159 BPicture
* picture
= fCurrentPicture
;
4160 fCurrentPicture
= picture
->StepDown();
4161 picture
->SetToken(token
);
4163 // TODO do this more efficient e.g. use a shared area and let the
4164 // client write into it
4165 picture
->_Download();
4175 BView::SetViewBitmap(const BBitmap
* bitmap
, BRect srcRect
, BRect dstRect
,
4176 uint32 followFlags
, uint32 options
)
4178 _SetViewBitmap(bitmap
, srcRect
, dstRect
, followFlags
, options
);
4183 BView::SetViewBitmap(const BBitmap
* bitmap
, uint32 followFlags
, uint32 options
)
4187 rect
= bitmap
->Bounds();
4189 rect
.OffsetTo(B_ORIGIN
);
4191 _SetViewBitmap(bitmap
, rect
, rect
, followFlags
, options
);
4196 BView::ClearViewBitmap()
4198 _SetViewBitmap(NULL
, BRect(), BRect(), 0, 0);
4203 BView::SetViewOverlay(const BBitmap
* overlay
, BRect srcRect
, BRect dstRect
,
4204 rgb_color
* colorKey
, uint32 followFlags
, uint32 options
)
4206 if (overlay
== NULL
|| (overlay
->fFlags
& B_BITMAP_WILL_OVERLAY
) == 0)
4209 status_t status
= _SetViewBitmap(overlay
, srcRect
, dstRect
, followFlags
,
4210 options
| AS_REQUEST_COLOR_KEY
);
4211 if (status
== B_OK
) {
4212 // read the color that will be treated as transparent
4213 fOwner
->fLink
->Read
<rgb_color
>(colorKey
);
4221 BView::SetViewOverlay(const BBitmap
* overlay
, rgb_color
* colorKey
,
4222 uint32 followFlags
, uint32 options
)
4224 if (overlay
== NULL
)
4227 BRect rect
= overlay
->Bounds();
4228 rect
.OffsetTo(B_ORIGIN
);
4230 return SetViewOverlay(overlay
, rect
, rect
, colorKey
, followFlags
, options
);
4235 BView::ClearViewOverlay()
4237 _SetViewBitmap(NULL
, BRect(), BRect(), 0, 0);
4242 BView::CopyBits(BRect src
, BRect dst
)
4247 if (!src
.IsValid() || !dst
.IsValid())
4250 _CheckLockAndSwitchCurrent();
4252 fOwner
->fLink
->StartMessage(AS_VIEW_COPY_BITS
);
4253 fOwner
->fLink
->Attach
<BRect
>(src
);
4254 fOwner
->fLink
->Attach
<BRect
>(dst
);
4256 _FlushIfNotInTransaction();
4261 BView::DrawPicture(const BPicture
* picture
)
4263 if (picture
== NULL
)
4266 DrawPictureAsync(picture
, PenLocation());
4272 BView::DrawPicture(const BPicture
* picture
, BPoint where
)
4274 if (picture
== NULL
)
4277 DrawPictureAsync(picture
, where
);
4283 BView::DrawPicture(const char* filename
, long offset
, BPoint where
)
4288 DrawPictureAsync(filename
, offset
, where
);
4294 BView::DrawPictureAsync(const BPicture
* picture
)
4296 if (picture
== NULL
)
4299 DrawPictureAsync(picture
, PenLocation());
4304 BView::DrawPictureAsync(const BPicture
* picture
, BPoint where
)
4306 if (picture
== NULL
)
4309 if (_CheckOwnerLockAndSwitchCurrent() && picture
->Token() > 0) {
4310 fOwner
->fLink
->StartMessage(AS_VIEW_DRAW_PICTURE
);
4311 fOwner
->fLink
->Attach
<int32
>(picture
->Token());
4312 fOwner
->fLink
->Attach
<BPoint
>(where
);
4314 _FlushIfNotInTransaction();
4320 BView::DrawPictureAsync(const char* filename
, long offset
, BPoint where
)
4326 BFile
file(filename
, B_READ_ONLY
);
4327 if (file
.InitCheck() < B_OK
)
4330 file
.Seek(offset
, SEEK_SET
);
4333 if (picture
.Unflatten(&file
) < B_OK
)
4336 DrawPictureAsync(&picture
, where
);
4341 BView::BeginLayer(uint8 opacity
)
4343 if (_CheckOwnerLockAndSwitchCurrent()) {
4344 fOwner
->fLink
->StartMessage(AS_VIEW_BEGIN_LAYER
);
4345 fOwner
->fLink
->Attach
<uint8
>(opacity
);
4346 _FlushIfNotInTransaction();
4354 if (_CheckOwnerLockAndSwitchCurrent()) {
4355 fOwner
->fLink
->StartMessage(AS_VIEW_END_LAYER
);
4356 _FlushIfNotInTransaction();
4362 BView::Invalidate(BRect invalRect
)
4367 // NOTE: This rounding of the invalid rect is to stay compatible with BeOS.
4368 // On the server side, the invalid rect will be converted to a BRegion,
4369 // which rounds in a different manner, so that it really includes the
4370 // fractional coordinates of a BRect (ie ceilf(rect.right) &
4371 // ceilf(rect.bottom)), which is also what BeOS does. So we have to do the
4372 // different rounding here to stay compatible in both ways.
4373 invalRect
.left
= (int)invalRect
.left
;
4374 invalRect
.top
= (int)invalRect
.top
;
4375 invalRect
.right
= (int)invalRect
.right
;
4376 invalRect
.bottom
= (int)invalRect
.bottom
;
4377 if (!invalRect
.IsValid())
4380 _CheckLockAndSwitchCurrent();
4382 fOwner
->fLink
->StartMessage(AS_VIEW_INVALIDATE_RECT
);
4383 fOwner
->fLink
->Attach
<BRect
>(invalRect
);
4385 // TODO: determine why this check isn't working correctly.
4387 if (!fOwner
->fUpdateRequested
) {
4388 fOwner
->fLink
->Flush();
4389 fOwner
->fUpdateRequested
= true;
4392 fOwner
->fLink
->Flush();
4398 BView::Invalidate(const BRegion
* region
)
4400 if (region
== NULL
|| fOwner
== NULL
)
4403 _CheckLockAndSwitchCurrent();
4405 fOwner
->fLink
->StartMessage(AS_VIEW_INVALIDATE_REGION
);
4406 fOwner
->fLink
->AttachRegion(*region
);
4410 if (!fOwner
->fUpdateRequested
) {
4411 fOwner
->fLink
->Flush();
4412 fOwner
->fUpdateRequested
= true;
4415 fOwner
->fLink
->Flush();
4423 Invalidate(Bounds());
4428 BView::DelayedInvalidate(bigtime_t delay
)
4430 DelayedInvalidate(delay
, Bounds());
4435 BView::DelayedInvalidate(bigtime_t delay
, BRect invalRect
)
4440 invalRect
.left
= (int)invalRect
.left
;
4441 invalRect
.top
= (int)invalRect
.top
;
4442 invalRect
.right
= (int)invalRect
.right
;
4443 invalRect
.bottom
= (int)invalRect
.bottom
;
4444 if (!invalRect
.IsValid())
4447 _CheckLockAndSwitchCurrent();
4449 fOwner
->fLink
->StartMessage(AS_VIEW_DELAYED_INVALIDATE_RECT
);
4450 fOwner
->fLink
->Attach
<bigtime_t
>(system_time() + delay
);
4451 fOwner
->fLink
->Attach
<BRect
>(invalRect
);
4452 fOwner
->fLink
->Flush();
4457 BView::InvertRect(BRect rect
)
4460 _CheckLockAndSwitchCurrent();
4462 fOwner
->fLink
->StartMessage(AS_VIEW_INVERT_RECT
);
4463 fOwner
->fLink
->Attach
<BRect
>(rect
);
4465 _FlushIfNotInTransaction();
4470 // #pragma mark - View Hierarchy Functions
4474 BView::AddChild(BView
* child
, BView
* before
)
4476 STRACE(("BView(%s)::AddChild(child '%s', before '%s')\n",
4478 child
!= NULL
&& child
->Name() ? child
->Name() : "NULL",
4479 before
!= NULL
&& before
->Name() ? before
->Name() : "NULL"));
4481 if (!_AddChild(child
, before
))
4484 if (fLayoutData
->fLayout
)
4485 fLayoutData
->fLayout
->AddView(child
);
4490 BView::AddChild(BLayoutItem
* child
)
4492 if (!fLayoutData
->fLayout
)
4494 return fLayoutData
->fLayout
->AddItem(child
);
4499 BView::_AddChild(BView
* child
, BView
* before
)
4504 if (child
->fParent
!= NULL
) {
4505 debugger("AddChild failed - the view already has a parent.");
4509 if (child
== this) {
4510 debugger("AddChild failed - cannot add a view to itself.");
4514 bool lockedOwner
= false;
4515 if (fOwner
&& !fOwner
->IsLocked()) {
4520 if (!_AddChildToList(child
, before
)) {
4521 debugger("AddChild failed!");
4528 _CheckLockAndSwitchCurrent();
4530 child
->_SetOwner(fOwner
);
4531 child
->_CreateSelf();
4545 BView::RemoveChild(BView
* child
)
4547 STRACE(("BView(%s)::RemoveChild(%s)\n", Name(), child
->Name()));
4552 if (child
->fParent
!= this)
4555 return child
->RemoveSelf();
4560 BView::CountChildren() const
4565 BView
* child
= fFirstChild
;
4567 while (child
!= NULL
) {
4569 child
= child
->fNextSibling
;
4577 BView::ChildAt(int32 index
) const
4581 BView
* child
= fFirstChild
;
4582 while (child
!= NULL
&& index
-- > 0) {
4583 child
= child
->fNextSibling
;
4591 BView::NextSibling() const
4593 return fNextSibling
;
4598 BView::PreviousSibling() const
4600 return fPreviousSibling
;
4607 _RemoveLayoutItemsFromLayout(false);
4609 return _RemoveSelf();
4614 BView::_RemoveSelf()
4616 STRACE(("BView(%s)::_RemoveSelf()\n", Name()));
4618 // Remove this child from its parent
4620 BWindow
* owner
= fOwner
;
4623 if (owner
!= NULL
) {
4624 _UpdateStateForRemove();
4628 BView
* parent
= fParent
;
4629 if (!parent
|| !parent
->_RemoveChildFromList(this))
4632 if (owner
!= NULL
&& !fTopLevelView
) {
4633 // the top level view is deleted by the app_server automatically
4634 owner
->fLink
->StartMessage(AS_VIEW_DELETE
);
4635 owner
->fLink
->Attach
<int32
>(_get_object_token_(this));
4638 parent
->InvalidateLayout();
4640 STRACE(("DONE: BView(%s)::_RemoveSelf()\n", Name()));
4647 BView::_RemoveLayoutItemsFromLayout(bool deleteItems
)
4649 if (fParent
== NULL
|| fParent
->fLayoutData
->fLayout
== NULL
)
4652 int32 index
= fLayoutData
->fLayoutItems
.CountItems();
4653 while (index
-- > 0) {
4654 BLayoutItem
* item
= fLayoutData
->fLayoutItems
.ItemAt(index
);
4656 // Removes item from fLayoutItems list
4664 BView::Parent() const
4666 if (fParent
&& fParent
->fTopLevelView
)
4674 BView::FindView(const char* name
) const
4679 if (Name() != NULL
&& !strcmp(Name(), name
))
4680 return const_cast<BView
*>(this);
4682 BView
* child
= fFirstChild
;
4683 while (child
!= NULL
) {
4684 BView
* view
= child
->FindView(name
);
4688 child
= child
->fNextSibling
;
4696 BView::MoveBy(float deltaX
, float deltaY
)
4698 MoveTo(fParentOffset
.x
+ roundf(deltaX
), fParentOffset
.y
+ roundf(deltaY
));
4703 BView::MoveTo(BPoint where
)
4705 MoveTo(where
.x
, where
.y
);
4710 BView::MoveTo(float x
, float y
)
4712 if (x
== fParentOffset
.x
&& y
== fParentOffset
.y
)
4715 // BeBook says we should do this. And it makes sense.
4720 _CheckLockAndSwitchCurrent();
4721 fOwner
->fLink
->StartMessage(AS_VIEW_MOVE_TO
);
4722 fOwner
->fLink
->Attach
<float>(x
);
4723 fOwner
->fLink
->Attach
<float>(y
);
4725 // fState->valid_flags |= B_VIEW_FRAME_BIT;
4727 _FlushIfNotInTransaction();
4730 _MoveTo((int32
)x
, (int32
)y
);
4735 BView::ResizeBy(float deltaWidth
, float deltaHeight
)
4737 // BeBook says we should do this. And it makes sense.
4738 deltaWidth
= roundf(deltaWidth
);
4739 deltaHeight
= roundf(deltaHeight
);
4741 if (deltaWidth
== 0 && deltaHeight
== 0)
4745 _CheckLockAndSwitchCurrent();
4746 fOwner
->fLink
->StartMessage(AS_VIEW_RESIZE_TO
);
4748 fOwner
->fLink
->Attach
<float>(fBounds
.Width() + deltaWidth
);
4749 fOwner
->fLink
->Attach
<float>(fBounds
.Height() + deltaHeight
);
4751 // fState->valid_flags |= B_VIEW_FRAME_BIT;
4753 _FlushIfNotInTransaction();
4756 _ResizeBy((int32
)deltaWidth
, (int32
)deltaHeight
);
4761 BView::ResizeTo(float width
, float height
)
4763 ResizeBy(width
- fBounds
.Width(), height
- fBounds
.Height());
4768 BView::ResizeTo(BSize size
)
4770 ResizeBy(size
.width
- fBounds
.Width(), size
.height
- fBounds
.Height());
4774 // #pragma mark - Inherited Methods (from BHandler)
4778 BView::GetSupportedSuites(BMessage
* data
)
4783 status_t status
= data
->AddString("suites", "suite/vnd.Be-view");
4784 BPropertyInfo
propertyInfo(sViewPropInfo
);
4786 status
= data
->AddFlat("messages", &propertyInfo
);
4788 return BHandler::GetSupportedSuites(data
);
4794 BView::ResolveSpecifier(BMessage
* message
, int32 index
, BMessage
* specifier
,
4795 int32 what
, const char* property
)
4797 if (message
->what
== B_WINDOW_MOVE_BY
4798 || message
->what
== B_WINDOW_MOVE_TO
) {
4802 BPropertyInfo
propertyInfo(sViewPropInfo
);
4803 status_t err
= B_BAD_SCRIPT_SYNTAX
;
4804 BMessage
replyMsg(B_REPLY
);
4806 switch (propertyInfo
.FindMatch(message
, index
, specifier
, what
, property
)) {
4814 message
->PopSpecifier();
4818 err
= B_NAME_NOT_FOUND
;
4819 replyMsg
.AddString("message", "This window doesn't have a shelf");
4825 err
= B_NAME_NOT_FOUND
;
4826 replyMsg
.AddString("message", "This window doesn't have "
4830 BView
* child
= NULL
;
4832 case B_INDEX_SPECIFIER
:
4835 err
= specifier
->FindInt32("index", &index
);
4837 child
= ChildAt(index
);
4840 case B_REVERSE_INDEX_SPECIFIER
:
4843 err
= specifier
->FindInt32("index", &rindex
);
4845 child
= ChildAt(CountChildren() - rindex
);
4848 case B_NAME_SPECIFIER
:
4851 err
= specifier
->FindString("name", &name
);
4853 child
= FindView(name
);
4858 if (child
!= NULL
) {
4859 message
->PopSpecifier();
4866 replyMsg
.AddString("message",
4867 "Cannot find view at/with specified index/name.");
4872 return BHandler::ResolveSpecifier(message
, index
, specifier
, what
,
4877 replyMsg
.what
= B_MESSAGE_NOT_UNDERSTOOD
;
4879 if (err
== B_BAD_SCRIPT_SYNTAX
)
4880 replyMsg
.AddString("message", "Didn't understand the specifier(s)");
4882 replyMsg
.AddString("message", strerror(err
));
4885 replyMsg
.AddInt32("error", err
);
4886 message
->SendReply(&replyMsg
);
4892 BView::MessageReceived(BMessage
* message
)
4894 if (!message
->HasSpecifiers()) {
4895 switch (message
->what
) {
4896 case B_VIEW_RESIZED
:
4897 FrameResized(message
->GetInt32("width", 0),
4898 message
->GetInt32("height", 0));
4902 FrameMoved(fParentOffset
);
4908 if (message
->FindPoint("be:view_where", &where
) != B_OK
)
4912 if (GetToolTipAt(where
, &tip
))
4915 BHandler::MessageReceived(message
);
4919 case B_MOUSE_WHEEL_CHANGED
:
4921 BScrollBar
* horizontal
= ScrollBar(B_HORIZONTAL
);
4922 BScrollBar
* vertical
= ScrollBar(B_VERTICAL
);
4923 if (horizontal
== NULL
&& vertical
== NULL
) {
4924 // Pass the message to the next handler
4925 BHandler::MessageReceived(message
);
4929 float deltaX
= 0.0f
;
4930 float deltaY
= 0.0f
;
4932 if (horizontal
!= NULL
)
4933 message
->FindFloat("be:wheel_delta_x", &deltaX
);
4935 if (vertical
!= NULL
)
4936 message
->FindFloat("be:wheel_delta_y", &deltaY
);
4938 if (deltaX
== 0.0f
&& deltaY
== 0.0f
)
4941 if ((modifiers() & B_CONTROL_KEY
) != 0)
4942 std::swap(horizontal
, vertical
);
4944 if (horizontal
!= NULL
&& deltaX
!= 0.0f
)
4945 ScrollWithMouseWheelDelta(horizontal
, deltaX
);
4947 if (vertical
!= NULL
&& deltaY
!= 0.0f
)
4948 ScrollWithMouseWheelDelta(vertical
, deltaY
);
4953 // prevent message repeats
4954 case B_COLORS_UPDATED
:
4955 case B_FONTS_UPDATED
:
4958 case B_SCREEN_CHANGED
:
4960 // propegate message to child views
4961 int32 childCount
= CountChildren();
4962 for (int32 i
= 0; i
< childCount
; i
++) {
4963 BView
* view
= ChildAt(i
);
4965 view
->MessageReceived(message
);
4971 BHandler::MessageReceived(message
);
4978 // Scripting message
4980 BMessage
replyMsg(B_REPLY
);
4981 status_t err
= B_BAD_SCRIPT_SYNTAX
;
4985 const char* property
;
4987 if (message
->GetCurrentSpecifier(&index
, &specifier
, &what
, &property
)
4989 return BHandler::MessageReceived(message
);
4992 BPropertyInfo
propertyInfo(sViewPropInfo
);
4993 switch (propertyInfo
.FindMatch(message
, index
, &specifier
, what
,
4996 if (message
->what
== B_GET_PROPERTY
) {
4997 err
= replyMsg
.AddRect("result", Frame());
4998 } else if (message
->what
== B_SET_PROPERTY
) {
5000 err
= message
->FindRect("data", &newFrame
);
5002 MoveTo(newFrame
.LeftTop());
5003 ResizeTo(newFrame
.Width(), newFrame
.Height());
5008 if (message
->what
== B_GET_PROPERTY
) {
5009 err
= replyMsg
.AddBool("result", IsHidden());
5010 } else if (message
->what
== B_SET_PROPERTY
) {
5011 bool newHiddenState
;
5012 err
= message
->FindBool("data", &newHiddenState
);
5014 if (newHiddenState
== true)
5022 err
= replyMsg
.AddInt32("result", CountChildren());
5025 return BHandler::MessageReceived(message
);
5029 replyMsg
.what
= B_MESSAGE_NOT_UNDERSTOOD
;
5031 if (err
== B_BAD_SCRIPT_SYNTAX
)
5032 replyMsg
.AddString("message", "Didn't understand the specifier(s)");
5034 replyMsg
.AddString("message", strerror(err
));
5036 replyMsg
.AddInt32("error", err
);
5039 message
->SendReply(&replyMsg
);
5044 BView::Perform(perform_code code
, void* _data
)
5047 case PERFORM_CODE_MIN_SIZE
:
5048 ((perform_data_min_size
*)_data
)->return_value
5051 case PERFORM_CODE_MAX_SIZE
:
5052 ((perform_data_max_size
*)_data
)->return_value
5055 case PERFORM_CODE_PREFERRED_SIZE
:
5056 ((perform_data_preferred_size
*)_data
)->return_value
5057 = BView::PreferredSize();
5059 case PERFORM_CODE_LAYOUT_ALIGNMENT
:
5060 ((perform_data_layout_alignment
*)_data
)->return_value
5061 = BView::LayoutAlignment();
5063 case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH
:
5064 ((perform_data_has_height_for_width
*)_data
)->return_value
5065 = BView::HasHeightForWidth();
5067 case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH
:
5069 perform_data_get_height_for_width
* data
5070 = (perform_data_get_height_for_width
*)_data
;
5071 BView::GetHeightForWidth(data
->width
, &data
->min
, &data
->max
,
5075 case PERFORM_CODE_SET_LAYOUT
:
5077 perform_data_set_layout
* data
= (perform_data_set_layout
*)_data
;
5078 BView::SetLayout(data
->layout
);
5081 case PERFORM_CODE_LAYOUT_INVALIDATED
:
5083 perform_data_layout_invalidated
* data
5084 = (perform_data_layout_invalidated
*)_data
;
5085 BView::LayoutInvalidated(data
->descendants
);
5088 case PERFORM_CODE_DO_LAYOUT
:
5093 case PERFORM_CODE_LAYOUT_CHANGED
:
5095 BView::LayoutChanged();
5098 case PERFORM_CODE_GET_TOOL_TIP_AT
:
5100 perform_data_get_tool_tip_at
* data
5101 = (perform_data_get_tool_tip_at
*)_data
;
5103 = BView::GetToolTipAt(data
->point
, data
->tool_tip
);
5106 case PERFORM_CODE_ALL_UNARCHIVED
:
5108 perform_data_all_unarchived
* data
=
5109 (perform_data_all_unarchived
*)_data
;
5111 data
->return_value
= BView::AllUnarchived(data
->archive
);
5114 case PERFORM_CODE_ALL_ARCHIVED
:
5116 perform_data_all_archived
* data
=
5117 (perform_data_all_archived
*)_data
;
5119 data
->return_value
= BView::AllArchived(data
->archive
);
5124 return BHandler::Perform(code
, _data
);
5128 // #pragma mark - Layout Functions
5134 // TODO: make sure this works correctly when some methods are overridden
5135 float width
, height
;
5136 GetPreferredSize(&width
, &height
);
5138 return BLayoutUtils::ComposeSize(fLayoutData
->fMinSize
,
5139 (fLayoutData
->fLayout
? fLayoutData
->fLayout
->MinSize()
5140 : BSize(width
, height
)));
5147 return BLayoutUtils::ComposeSize(fLayoutData
->fMaxSize
,
5148 (fLayoutData
->fLayout
? fLayoutData
->fLayout
->MaxSize()
5149 : BSize(B_SIZE_UNLIMITED
, B_SIZE_UNLIMITED
)));
5154 BView::PreferredSize()
5156 // TODO: make sure this works correctly when some methods are overridden
5157 float width
, height
;
5158 GetPreferredSize(&width
, &height
);
5160 return BLayoutUtils::ComposeSize(fLayoutData
->fPreferredSize
,
5161 (fLayoutData
->fLayout
? fLayoutData
->fLayout
->PreferredSize()
5162 : BSize(width
, height
)));
5167 BView::LayoutAlignment()
5169 return BLayoutUtils::ComposeAlignment(fLayoutData
->fAlignment
,
5170 (fLayoutData
->fLayout
? fLayoutData
->fLayout
->Alignment()
5171 : BAlignment(B_ALIGN_HORIZONTAL_CENTER
, B_ALIGN_VERTICAL_CENTER
)));
5176 BView::SetExplicitMinSize(BSize size
)
5178 fLayoutData
->fMinSize
= size
;
5184 BView::SetExplicitMaxSize(BSize size
)
5186 fLayoutData
->fMaxSize
= size
;
5192 BView::SetExplicitPreferredSize(BSize size
)
5194 fLayoutData
->fPreferredSize
= size
;
5200 BView::SetExplicitSize(BSize size
)
5202 fLayoutData
->fMinSize
= size
;
5203 fLayoutData
->fMaxSize
= size
;
5204 fLayoutData
->fPreferredSize
= size
;
5210 BView::SetExplicitAlignment(BAlignment alignment
)
5212 fLayoutData
->fAlignment
= alignment
;
5218 BView::ExplicitMinSize() const
5220 return fLayoutData
->fMinSize
;
5225 BView::ExplicitMaxSize() const
5227 return fLayoutData
->fMaxSize
;
5232 BView::ExplicitPreferredSize() const
5234 return fLayoutData
->fPreferredSize
;
5239 BView::ExplicitAlignment() const
5241 return fLayoutData
->fAlignment
;
5246 BView::HasHeightForWidth()
5248 return (fLayoutData
->fLayout
5249 ? fLayoutData
->fLayout
->HasHeightForWidth() : false);
5254 BView::GetHeightForWidth(float width
, float* min
, float* max
, float* preferred
)
5256 if (fLayoutData
->fLayout
)
5257 fLayoutData
->fLayout
->GetHeightForWidth(width
, min
, max
, preferred
);
5262 BView::SetLayout(BLayout
* layout
)
5264 if (layout
== fLayoutData
->fLayout
)
5267 if (layout
&& layout
->Layout())
5268 debugger("BView::SetLayout() failed, layout is already in use.");
5270 fFlags
|= B_SUPPORTS_LAYOUT
;
5272 // unset and delete the old layout
5273 if (fLayoutData
->fLayout
) {
5274 fLayoutData
->fLayout
->RemoveSelf();
5275 fLayoutData
->fLayout
->SetOwner(NULL
);
5276 delete fLayoutData
->fLayout
;
5279 fLayoutData
->fLayout
= layout
;
5281 if (fLayoutData
->fLayout
) {
5282 fLayoutData
->fLayout
->SetOwner(this);
5285 int count
= CountChildren();
5286 for (int i
= 0; i
< count
; i
++)
5287 fLayoutData
->fLayout
->AddView(ChildAt(i
));
5295 BView::GetLayout() const
5297 return fLayoutData
->fLayout
;
5302 BView::InvalidateLayout(bool descendants
)
5304 // printf("BView(%p)::InvalidateLayout(%i), valid: %i, inProgress: %i\n",
5305 // this, descendants, fLayoutData->fLayoutValid,
5306 // fLayoutData->fLayoutInProgress);
5308 if (!fLayoutData
->fMinMaxValid
|| fLayoutData
->fLayoutInProgress
5309 || fLayoutData
->fLayoutInvalidationDisabled
> 0) {
5312 fLayoutData
->fLayoutValid
= false;
5313 fLayoutData
->fMinMaxValid
= false;
5314 LayoutInvalidated(descendants
);
5317 for (BView
* child
= fFirstChild
;
5318 child
; child
= child
->fNextSibling
) {
5319 child
->InvalidateLayout(descendants
);
5323 if (fLayoutData
->fLayout
)
5324 fLayoutData
->fLayout
->InvalidateLayout(descendants
);
5326 _InvalidateParentLayout();
5330 fOwner
->PostMessage(B_LAYOUT_WINDOW
);
5335 BView::EnableLayoutInvalidation()
5337 if (fLayoutData
->fLayoutInvalidationDisabled
> 0)
5338 fLayoutData
->fLayoutInvalidationDisabled
--;
5343 BView::DisableLayoutInvalidation()
5345 fLayoutData
->fLayoutInvalidationDisabled
++;
5350 BView::IsLayoutInvalidationDisabled()
5352 if (fLayoutData
->fLayoutInvalidationDisabled
> 0)
5359 BView::IsLayoutValid() const
5361 return fLayoutData
->fLayoutValid
;
5366 BView::ResetLayoutInvalidation()
5368 fLayoutData
->fMinMaxValid
= true;
5373 BView::LayoutContext() const
5375 return fLayoutData
->fLayoutContext
;
5380 BView::Layout(bool force
)
5382 BLayoutContext context
;
5383 _Layout(force
, &context
);
5390 if (fLayoutData
->fLayoutValid
&& !fLayoutData
->fLayoutInProgress
) {
5391 fLayoutData
->fNeedsRelayout
= true;
5392 if (fLayoutData
->fLayout
)
5393 fLayoutData
->fLayout
->RequireLayout();
5395 // Layout() is recursive, that is if the parent view is currently laid
5396 // out, we don't call layout() on this view, but wait for the parent's
5397 // Layout() to do that for us.
5398 if (!fParent
|| !fParent
->fLayoutData
->fLayoutInProgress
)
5405 BView::LayoutInvalidated(bool descendants
)
5414 if (fLayoutData
->fLayout
)
5415 fLayoutData
->fLayout
->_LayoutWithinContext(false, LayoutContext());
5420 BView::SetToolTip(const char* text
)
5422 if (text
== NULL
|| text
[0] == '\0') {
5423 SetToolTip((BToolTip
*)NULL
);
5427 if (BTextToolTip
* tip
= dynamic_cast<BTextToolTip
*>(fToolTip
))
5430 SetToolTip(new BTextToolTip(text
));
5435 BView::SetToolTip(BToolTip
* tip
)
5437 if (fToolTip
== tip
)
5439 else if (tip
== NULL
)
5442 if (fToolTip
!= NULL
)
5443 fToolTip
->ReleaseReference();
5447 if (fToolTip
!= NULL
)
5448 fToolTip
->AcquireReference();
5453 BView::ToolTip() const
5460 BView::ShowToolTip(BToolTip
* tip
)
5466 GetMouse(&where
, NULL
, false);
5468 BToolTipManager::Manager()->ShowTip(tip
, ConvertToScreen(where
), this);
5473 BView::HideToolTip()
5475 BToolTipManager::Manager()->HideTip();
5480 BView::GetToolTipAt(BPoint point
, BToolTip
** _tip
)
5482 if (fToolTip
!= NULL
) {
5493 BView::LayoutChanged()
5500 BView::_Layout(bool force
, BLayoutContext
* context
)
5502 //printf("%p->BView::_Layout(%d, %p)\n", this, force, context);
5503 //printf(" fNeedsRelayout: %d, fLayoutValid: %d, fLayoutInProgress: %d\n",
5504 //fLayoutData->fNeedsRelayout, fLayoutData->fLayoutValid,
5505 //fLayoutData->fLayoutInProgress);
5506 if (fLayoutData
->fNeedsRelayout
|| !fLayoutData
->fLayoutValid
|| force
) {
5507 fLayoutData
->fLayoutValid
= false;
5509 if (fLayoutData
->fLayoutInProgress
)
5512 BLayoutContext
* oldContext
= fLayoutData
->fLayoutContext
;
5513 fLayoutData
->fLayoutContext
= context
;
5515 fLayoutData
->fLayoutInProgress
= true;
5517 fLayoutData
->fLayoutInProgress
= false;
5519 fLayoutData
->fLayoutValid
= true;
5520 fLayoutData
->fMinMaxValid
= true;
5521 fLayoutData
->fNeedsRelayout
= false;
5524 for(BView
* child
= fFirstChild
; child
; child
= child
->fNextSibling
) {
5525 if (!child
->IsHidden(child
))
5526 child
->_Layout(force
, context
);
5531 fLayoutData
->fLayoutContext
= oldContext
;
5533 // invalidate the drawn content, if requested
5534 if (fFlags
& B_INVALIDATE_AFTER_LAYOUT
)
5541 BView::_LayoutLeft(BLayout
* deleted
)
5543 // If our layout is added to another layout (via BLayout::AddItem())
5544 // then we share ownership of our layout. In the event that our layout gets
5545 // deleted by the layout it has been added to, this method is called so
5546 // that we don't double-delete our layout.
5547 if (fLayoutData
->fLayout
== deleted
)
5548 fLayoutData
->fLayout
= NULL
;
5554 BView::_InvalidateParentLayout()
5559 BLayout
* layout
= fLayoutData
->fLayout
;
5560 BLayout
* layoutParent
= layout
? layout
->Layout() : NULL
;
5562 layoutParent
->InvalidateLayout();
5563 } else if (fLayoutData
->fLayoutItems
.CountItems() > 0) {
5564 int32 count
= fLayoutData
->fLayoutItems
.CountItems();
5565 for (int32 i
= 0; i
< count
; i
++) {
5566 fLayoutData
->fLayoutItems
.ItemAt(i
)->Layout()->InvalidateLayout();
5569 fParent
->InvalidateLayout();
5574 // #pragma mark - Private Functions
5578 BView::_InitData(BRect frame
, const char* name
, uint32 resizingMode
,
5581 // Info: The name of the view is set by BHandler constructor
5583 STRACE(("BView::_InitData: enter\n"));
5585 // initialize members
5586 if ((resizingMode
& ~_RESIZE_MASK_
) || (flags
& _RESIZE_MASK_
))
5587 printf("%s BView::_InitData(): resizing mode or flags swapped\n", name
);
5589 // There are applications that swap the resize mask and the flags in the
5590 // BView constructor. This does not cause problems under BeOS as it just
5591 // ors the two fields to one 32bit flag.
5592 // For now we do the same but print the above warning message.
5593 // TODO: this should be removed at some point and the original
5594 // version restored:
5595 // fFlags = (resizingMode & _RESIZE_MASK_) | (flags & ~_RESIZE_MASK_);
5596 fFlags
= resizingMode
| flags
;
5599 frame
.left
= roundf(frame
.left
);
5600 frame
.top
= roundf(frame
.top
);
5601 frame
.right
= roundf(frame
.right
);
5602 frame
.bottom
= roundf(frame
.bottom
);
5604 fParentOffset
.Set(frame
.left
, frame
.top
);
5608 fNextSibling
= NULL
;
5609 fPreviousSibling
= NULL
;
5613 fTopLevelView
= false;
5615 fCurrentPicture
= NULL
;
5618 fVerScroller
= NULL
;
5619 fHorScroller
= NULL
;
5621 fIsPrinting
= false;
5624 // TODO: Since we cannot communicate failure, we don't use std::nothrow here
5625 // TODO: Maybe we could auto-delete those views on AddChild() instead?
5626 fState
= new BPrivate::ViewState
;
5628 fBounds
= frame
.OffsetToCopy(B_ORIGIN
);
5633 fMouseEventOptions
= 0;
5635 fLayoutData
= new LayoutData
;
5639 if ((flags
& B_SUPPORTS_LAYOUT
) != 0) {
5640 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
5641 SetLowUIColor(ViewUIColor());
5642 SetHighUIColor(B_PANEL_TEXT_COLOR
);
5648 BView::_RemoveCommArray()
5651 delete [] fCommArray
->array
;
5659 BView::_SetOwner(BWindow
* newOwner
)
5664 if (fOwner
!= newOwner
&& fOwner
) {
5665 if (fOwner
->fFocus
== this)
5668 if (fOwner
->fLastMouseMovedView
== this)
5669 fOwner
->fLastMouseMovedView
= NULL
;
5671 fOwner
->RemoveHandler(this);
5673 fOwner
->RemoveHandler(fShelf
);
5676 if (newOwner
&& newOwner
!= fOwner
) {
5677 newOwner
->AddHandler(this);
5679 newOwner
->AddHandler(fShelf
);
5682 SetNextHandler(newOwner
);
5684 SetNextHandler(fParent
);
5689 for (BView
* child
= fFirstChild
; child
!= NULL
; child
= child
->fNextSibling
)
5690 child
->_SetOwner(newOwner
);
5695 BView::_ClipToPicture(BPicture
* picture
, BPoint where
, bool invert
, bool sync
)
5697 if (!_CheckOwnerLockAndSwitchCurrent())
5700 if (picture
== NULL
) {
5701 fOwner
->fLink
->StartMessage(AS_VIEW_CLIP_TO_PICTURE
);
5702 fOwner
->fLink
->Attach
<int32
>(-1);
5704 // NOTE: No need to sync here, since the -1 token cannot
5705 // become invalid on the server.
5707 fOwner
->fLink
->StartMessage(AS_VIEW_CLIP_TO_PICTURE
);
5708 fOwner
->fLink
->Attach
<int32
>(picture
->Token());
5709 fOwner
->fLink
->Attach
<BPoint
>(where
);
5710 fOwner
->fLink
->Attach
<bool>(invert
);
5712 // NOTE: "sync" defaults to true in public methods. If you know what
5713 // you are doing, i.e. if you know your BPicture stays valid, you
5714 // can avoid the performance impact of syncing. In a use-case where
5715 // the client creates BPictures on the stack, these BPictures may
5716 // have issued a AS_DELETE_PICTURE command to the ServerApp when Draw()
5717 // goes out of scope, and the command is processed earlier in the
5718 // ServerApp thread than the AS_VIEW_CLIP_TO_PICTURE command in the
5719 // ServerWindow thread, which will then have the result that no
5720 // ServerPicture is found of the token.
5728 BView::_ClipToRect(BRect rect
, bool inverse
)
5730 if (_CheckOwnerLockAndSwitchCurrent()) {
5731 fOwner
->fLink
->StartMessage(AS_VIEW_CLIP_TO_RECT
);
5732 fOwner
->fLink
->Attach
<bool>(inverse
);
5733 fOwner
->fLink
->Attach
<BRect
>(rect
);
5734 _FlushIfNotInTransaction();
5740 BView::_ClipToShape(BShape
* shape
, bool inverse
)
5745 shape_data
* sd
= (shape_data
*)shape
->fPrivateData
;
5746 if (sd
->opCount
== 0 || sd
->ptCount
== 0)
5749 if (_CheckOwnerLockAndSwitchCurrent()) {
5750 fOwner
->fLink
->StartMessage(AS_VIEW_CLIP_TO_SHAPE
);
5751 fOwner
->fLink
->Attach
<bool>(inverse
);
5752 fOwner
->fLink
->Attach
<int32
>(sd
->opCount
);
5753 fOwner
->fLink
->Attach
<int32
>(sd
->ptCount
);
5754 fOwner
->fLink
->Attach(sd
->opList
, sd
->opCount
* sizeof(uint32
));
5755 fOwner
->fLink
->Attach(sd
->ptList
, sd
->ptCount
* sizeof(BPoint
));
5756 _FlushIfNotInTransaction();
5762 BView::_RemoveChildFromList(BView
* child
)
5764 if (child
->fParent
!= this)
5767 if (fFirstChild
== child
) {
5768 // it's the first view in the list
5769 fFirstChild
= child
->fNextSibling
;
5771 // there must be a previous sibling
5772 child
->fPreviousSibling
->fNextSibling
= child
->fNextSibling
;
5775 if (child
->fNextSibling
)
5776 child
->fNextSibling
->fPreviousSibling
= child
->fPreviousSibling
;
5778 child
->fParent
= NULL
;
5779 child
->fNextSibling
= NULL
;
5780 child
->fPreviousSibling
= NULL
;
5787 BView::_AddChildToList(BView
* child
, BView
* before
)
5791 if (child
->fParent
!= NULL
) {
5792 debugger("View already belongs to someone else");
5795 if (before
!= NULL
&& before
->fParent
!= this) {
5796 debugger("Invalid before view");
5800 if (before
!= NULL
) {
5801 // add view before this one
5802 child
->fNextSibling
= before
;
5803 child
->fPreviousSibling
= before
->fPreviousSibling
;
5804 if (child
->fPreviousSibling
!= NULL
)
5805 child
->fPreviousSibling
->fNextSibling
= child
;
5807 before
->fPreviousSibling
= child
;
5808 if (fFirstChild
== before
)
5809 fFirstChild
= child
;
5811 // add view to the end of the list
5812 BView
* last
= fFirstChild
;
5813 while (last
!= NULL
&& last
->fNextSibling
!= NULL
) {
5814 last
= last
->fNextSibling
;
5818 last
->fNextSibling
= child
;
5819 child
->fPreviousSibling
= last
;
5821 fFirstChild
= child
;
5822 child
->fPreviousSibling
= NULL
;
5825 child
->fNextSibling
= NULL
;
5828 child
->fParent
= this;
5833 /*! \brief Creates the server counterpart of this view.
5834 This is only done for views that are part of the view hierarchy, ie. when
5835 they are attached to a window.
5836 RemoveSelf() deletes the server object again.
5839 BView::_CreateSelf()
5841 // AS_VIEW_CREATE & AS_VIEW_CREATE_ROOT do not use the
5842 // current view mechanism via _CheckLockAndSwitchCurrent() - the token
5843 // of the view and its parent are both send to the server.
5846 fOwner
->fLink
->StartMessage(AS_VIEW_CREATE_ROOT
);
5848 fOwner
->fLink
->StartMessage(AS_VIEW_CREATE
);
5850 fOwner
->fLink
->Attach
<int32
>(_get_object_token_(this));
5851 fOwner
->fLink
->AttachString(Name());
5852 fOwner
->fLink
->Attach
<BRect
>(Frame());
5853 fOwner
->fLink
->Attach
<BPoint
>(LeftTop());
5854 fOwner
->fLink
->Attach
<uint32
>(ResizingMode());
5855 fOwner
->fLink
->Attach
<uint32
>(fEventMask
);
5856 fOwner
->fLink
->Attach
<uint32
>(fEventOptions
);
5857 fOwner
->fLink
->Attach
<uint32
>(Flags());
5858 fOwner
->fLink
->Attach
<bool>(IsHidden(this));
5859 fOwner
->fLink
->Attach
<rgb_color
>(fState
->view_color
);
5861 fOwner
->fLink
->Attach
<int32
>(B_NULL_TOKEN
);
5863 fOwner
->fLink
->Attach
<int32
>(_get_object_token_(fParent
));
5864 fOwner
->fLink
->Flush();
5866 _CheckOwnerLockAndSwitchCurrent();
5867 fState
->UpdateServerState(*fOwner
->fLink
);
5869 // we create all its children, too
5871 for (BView
* child
= fFirstChild
; child
!= NULL
;
5872 child
= child
->fNextSibling
) {
5873 child
->_CreateSelf();
5876 fOwner
->fLink
->Flush();
5881 /*! Sets the new view position.
5882 It doesn't contact the server, though - the only case where this
5883 is called outside of MoveTo() is as reaction of moving a view
5884 in the server (a.k.a. B_WINDOW_RESIZED).
5885 It also calls the BView's FrameMoved() hook.
5888 BView::_MoveTo(int32 x
, int32 y
)
5890 fParentOffset
.Set(x
, y
);
5892 if (Window() != NULL
&& fFlags
& B_FRAME_EVENTS
) {
5893 BMessage
moved(B_VIEW_MOVED
);
5894 moved
.AddInt64("when", system_time());
5895 moved
.AddPoint("where", BPoint(x
, y
));
5897 BMessenger
target(this);
5898 target
.SendMessage(&moved
);
5903 /*! Computes the actual new frame size and recalculates the size of
5904 the children as well.
5905 It doesn't contact the server, though - the only case where this
5906 is called outside of ResizeBy() is as reaction of resizing a view
5907 in the server (a.k.a. B_WINDOW_RESIZED).
5908 It also calls the BView's FrameResized() hook.
5911 BView::_ResizeBy(int32 deltaWidth
, int32 deltaHeight
)
5913 fBounds
.right
+= deltaWidth
;
5914 fBounds
.bottom
+= deltaHeight
;
5916 if (Window() == NULL
) {
5917 // we're not supposed to exercise the resizing code in case
5918 // we haven't been attached to a window yet
5922 // layout the children
5923 if ((fFlags
& B_SUPPORTS_LAYOUT
) != 0) {
5926 for (BView
* child
= fFirstChild
; child
; child
= child
->fNextSibling
)
5927 child
->_ParentResizedBy(deltaWidth
, deltaHeight
);
5930 if (fFlags
& B_FRAME_EVENTS
) {
5931 BMessage
resized(B_VIEW_RESIZED
);
5932 resized
.AddInt64("when", system_time());
5933 resized
.AddInt32("width", fBounds
.IntegerWidth());
5934 resized
.AddInt32("height", fBounds
.IntegerHeight());
5936 BMessenger
target(this);
5937 target
.SendMessage(&resized
);
5942 /*! Relayouts the view according to its resizing mode. */
5944 BView::_ParentResizedBy(int32 x
, int32 y
)
5946 uint32 resizingMode
= fFlags
& _RESIZE_MASK_
;
5947 BRect newFrame
= Frame();
5949 // follow with left side
5950 if ((resizingMode
& 0x0F00U
) == _VIEW_RIGHT_
<< 8)
5952 else if ((resizingMode
& 0x0F00U
) == _VIEW_CENTER_
<< 8)
5953 newFrame
.left
+= x
/ 2;
5955 // follow with right side
5956 if ((resizingMode
& 0x000FU
) == _VIEW_RIGHT_
)
5957 newFrame
.right
+= x
;
5958 else if ((resizingMode
& 0x000FU
) == _VIEW_CENTER_
)
5959 newFrame
.right
+= x
/ 2;
5961 // follow with top side
5962 if ((resizingMode
& 0xF000U
) == _VIEW_BOTTOM_
<< 12)
5964 else if ((resizingMode
& 0xF000U
) == _VIEW_CENTER_
<< 12)
5965 newFrame
.top
+= y
/ 2;
5967 // follow with bottom side
5968 if ((resizingMode
& 0x00F0U
) == _VIEW_BOTTOM_
<< 4)
5969 newFrame
.bottom
+= y
;
5970 else if ((resizingMode
& 0x00F0U
) == _VIEW_CENTER_
<< 4)
5971 newFrame
.bottom
+= y
/ 2;
5973 if (newFrame
.LeftTop() != fParentOffset
) {
5975 _MoveTo((int32
)roundf(newFrame
.left
), (int32
)roundf(newFrame
.top
));
5978 if (newFrame
!= Frame()) {
5980 int32 widthDiff
= (int32
)(newFrame
.Width() - fBounds
.Width());
5981 int32 heightDiff
= (int32
)(newFrame
.Height() - fBounds
.Height());
5982 _ResizeBy(widthDiff
, heightDiff
);
5988 BView::_Activate(bool active
)
5990 WindowActivated(active
);
5992 for (BView
* child
= fFirstChild
; child
!= NULL
;
5993 child
= child
->fNextSibling
) {
5994 child
->_Activate(active
);
6002 if (fOwner
!= NULL
) {
6003 // unmask state flags to force [re]syncing with the app_server
6004 fState
->valid_flags
&= ~(B_VIEW_WHICH_VIEW_COLOR_BIT
6005 | B_VIEW_WHICH_LOW_COLOR_BIT
| B_VIEW_WHICH_HIGH_COLOR_BIT
);
6007 if (fState
->which_view_color
!= B_NO_COLOR
)
6008 SetViewUIColor(fState
->which_view_color
,
6009 fState
->which_view_color_tint
);
6011 if (fState
->which_high_color
!= B_NO_COLOR
)
6012 SetHighUIColor(fState
->which_high_color
,
6013 fState
->which_high_color_tint
);
6015 if (fState
->which_low_color
!= B_NO_COLOR
)
6016 SetLowUIColor(fState
->which_low_color
,
6017 fState
->which_low_color_tint
);
6024 // after giving the view a chance to do this itself,
6025 // check for the B_PULSE_NEEDED flag and make sure the
6026 // window set's up the pulse messaging
6028 if (fFlags
& B_PULSE_NEEDED
) {
6030 if (fOwner
->fPulseRunner
== NULL
)
6031 fOwner
->SetPulseRate(fOwner
->PulseRate());
6034 if (!fOwner
->IsHidden())
6038 for (BView
* child
= fFirstChild
; child
!= NULL
;
6039 child
= child
->fNextSibling
) {
6040 // we need to check for fAttached as new views could have been
6041 // added in AttachedToWindow() - and those are already attached
6042 if (!child
->fAttached
)
6051 BView::_ColorsUpdated(BMessage
* message
)
6054 && fLayoutData
->fLayout
!= NULL
6055 && !fState
->IsValid(B_VIEW_WHICH_VIEW_COLOR_BIT
)) {
6056 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
6057 SetHighUIColor(B_PANEL_TEXT_COLOR
);
6062 const char* colorName
= ui_color_name(fState
->which_view_color
);
6063 if (colorName
!= NULL
&& message
->FindColor(colorName
, &color
) == B_OK
) {
6064 fState
->view_color
= tint_color(color
, fState
->which_view_color_tint
);
6065 fState
->valid_flags
|= B_VIEW_VIEW_COLOR_BIT
;
6068 colorName
= ui_color_name(fState
->which_low_color
);
6069 if (colorName
!= NULL
&& message
->FindColor(colorName
, &color
) == B_OK
) {
6070 fState
->low_color
= tint_color(color
, fState
->which_low_color_tint
);
6071 fState
->valid_flags
|= B_VIEW_LOW_COLOR_BIT
;
6074 colorName
= ui_color_name(fState
->which_high_color
);
6075 if (colorName
!= NULL
&& message
->FindColor(colorName
, &color
) == B_OK
) {
6076 fState
->high_color
= tint_color(color
, fState
->which_high_color_tint
);
6077 fState
->valid_flags
|= B_VIEW_HIGH_COLOR_BIT
;
6080 MessageReceived(message
);
6082 for (BView
* child
= fFirstChild
; child
!= NULL
;
6083 child
= child
->fNextSibling
)
6084 child
->_ColorsUpdated(message
);
6093 DetachedFromWindow();
6096 for (BView
* child
= fFirstChild
; child
!= NULL
;
6097 child
= child
->fNextSibling
) {
6106 if (!fOwner
->IsHidden())
6109 // make sure our owner doesn't need us anymore
6111 if (fOwner
->CurrentFocus() == this) {
6113 // MakeFocus() is virtual and might not be
6114 // passing through to the BView version,
6115 // but we need to make sure at this point
6116 // that we are not the focus view anymore.
6117 if (fOwner
->CurrentFocus() == this)
6118 fOwner
->_SetFocus(NULL
, true);
6121 if (fOwner
->fDefaultButton
== this)
6122 fOwner
->SetDefaultButton(NULL
);
6124 if (fOwner
->fKeyMenuBar
== this)
6125 fOwner
->fKeyMenuBar
= NULL
;
6127 if (fOwner
->fLastMouseMovedView
== this)
6128 fOwner
->fLastMouseMovedView
= NULL
;
6130 if (fOwner
->fLastViewToken
== _get_object_token_(this))
6131 fOwner
->fLastViewToken
= B_NULL_TOKEN
;
6139 BView::_Draw(BRect updateRect
)
6141 if (IsHidden(this) || !(Flags() & B_WILL_DRAW
))
6144 // NOTE: if ViewColor() == B_TRANSPARENT_COLOR and no B_WILL_DRAW
6145 // -> View is simply not drawn at all
6147 _SwitchServerCurrentView();
6149 ConvertFromScreen(&updateRect
);
6151 // TODO: make states robust (the hook implementation could
6152 // mess things up if it uses non-matching Push- and PopState(),
6153 // we would not be guaranteed to still have the same state on
6154 // the stack after having called Draw())
6163 BView::_DrawAfterChildren(BRect updateRect
)
6165 if (IsHidden(this) || !(Flags() & B_WILL_DRAW
)
6166 || !(Flags() & B_DRAW_ON_CHILDREN
))
6169 _SwitchServerCurrentView();
6171 ConvertFromScreen(&updateRect
);
6173 // TODO: make states robust (see above)
6175 DrawAfterChildren(updateRect
);
6182 BView::_FontsUpdated(BMessage
* message
)
6184 MessageReceived(message
);
6186 for (BView
* child
= fFirstChild
; child
!= NULL
;
6187 child
= child
->fNextSibling
) {
6188 child
->_FontsUpdated(message
);
6196 if ((Flags() & B_PULSE_NEEDED
) != 0)
6199 for (BView
* child
= fFirstChild
; child
!= NULL
;
6200 child
= child
->fNextSibling
) {
6207 BView::_UpdateStateForRemove()
6209 // TODO: _CheckLockAndSwitchCurrent() would be good enough, no?
6210 if (!_CheckOwnerLockAndSwitchCurrent())
6213 fState
->UpdateFrom(*fOwner
->fLink
);
6214 // if (!fState->IsValid(B_VIEW_FRAME_BIT)) {
6215 // fOwner->fLink->StartMessage(AS_VIEW_GET_COORD);
6218 // if (fOwner->fLink->FlushWithReply(code) == B_OK
6219 // && code == B_OK) {
6220 // fOwner->fLink->Read<BPoint>(&fParentOffset);
6221 // fOwner->fLink->Read<BRect>(&fBounds);
6222 // fState->valid_flags |= B_VIEW_FRAME_BIT;
6226 // update children as well
6228 for (BView
* child
= fFirstChild
; child
!= NULL
;
6229 child
= child
->fNextSibling
) {
6231 child
->_UpdateStateForRemove();
6237 BView::_UpdatePattern(::pattern pattern
)
6239 if (fState
->IsValid(B_VIEW_PATTERN_BIT
) && pattern
== fState
->pattern
)
6243 _CheckLockAndSwitchCurrent();
6245 fOwner
->fLink
->StartMessage(AS_VIEW_SET_PATTERN
);
6246 fOwner
->fLink
->Attach
< ::pattern
>(pattern
);
6248 fState
->valid_flags
|= B_VIEW_PATTERN_BIT
;
6251 fState
->pattern
= pattern
;
6256 BView::_FlushIfNotInTransaction()
6258 if (!fOwner
->fInTransaction
) {
6265 BView::_Shelf() const
6272 BView::_SetShelf(BShelf
* shelf
)
6274 if (fShelf
!= NULL
&& fOwner
!= NULL
)
6275 fOwner
->RemoveHandler(fShelf
);
6279 if (fShelf
!= NULL
&& fOwner
!= NULL
)
6280 fOwner
->AddHandler(fShelf
);
6285 BView::_SetViewBitmap(const BBitmap
* bitmap
, BRect srcRect
, BRect dstRect
,
6286 uint32 followFlags
, uint32 options
)
6288 if (!_CheckOwnerLockAndSwitchCurrent())
6291 int32 serverToken
= bitmap
? bitmap
->_ServerToken() : -1;
6293 fOwner
->fLink
->StartMessage(AS_VIEW_SET_VIEW_BITMAP
);
6294 fOwner
->fLink
->Attach
<int32
>(serverToken
);
6295 fOwner
->fLink
->Attach
<BRect
>(srcRect
);
6296 fOwner
->fLink
->Attach
<BRect
>(dstRect
);
6297 fOwner
->fLink
->Attach
<int32
>(followFlags
);
6298 fOwner
->fLink
->Attach
<int32
>(options
);
6300 status_t status
= B_ERROR
;
6301 fOwner
->fLink
->FlushWithReply(status
);
6308 BView::_CheckOwnerLockAndSwitchCurrent() const
6310 STRACE(("BView(%s)::_CheckOwnerLockAndSwitchCurrent()\n", Name()));
6312 if (fOwner
== NULL
) {
6313 debugger("View method requires owner and doesn't have one.");
6317 _CheckLockAndSwitchCurrent();
6324 BView::_CheckOwnerLock() const
6327 fOwner
->check_lock();
6330 debugger("View method requires owner and doesn't have one.");
6337 BView::_CheckLockAndSwitchCurrent() const
6339 STRACE(("BView(%s)::_CheckLockAndSwitchCurrent()\n", Name()));
6344 fOwner
->check_lock();
6346 _SwitchServerCurrentView();
6351 BView::_CheckLock() const
6354 fOwner
->check_lock();
6359 BView::_SwitchServerCurrentView() const
6361 int32 serverToken
= _get_object_token_(this);
6363 if (fOwner
->fLastViewToken
!= serverToken
) {
6364 STRACE(("contacting app_server... sending token: %" B_PRId32
"\n",
6366 fOwner
->fLink
->StartMessage(AS_SET_CURRENT_VIEW
);
6367 fOwner
->fLink
->Attach
<int32
>(serverToken
);
6369 fOwner
->fLastViewToken
= serverToken
;
6375 BView::ScrollWithMouseWheelDelta(BScrollBar
* scrollBar
, float delta
)
6377 if (scrollBar
== NULL
|| delta
== 0.0f
)
6382 scrollBar
->GetSteps(&smallStep
, &largeStep
);
6384 // pressing the shift key scrolls faster (following the pseudo-standard set
6385 // by other desktop environments).
6386 if ((modifiers() & B_SHIFT_KEY
) != 0)
6389 delta
*= smallStep
* 3;
6391 scrollBar
->SetValue(scrollBar
->Value() + delta
);
6401 _ReservedView1__5BView(BView
* view
, BRect rect
)
6403 view
->BView::DrawAfterChildren(rect
);
6408 _ReservedView2__5BView(BView
* view
)
6411 perform_data_min_size data
;
6412 view
->Perform(PERFORM_CODE_MIN_SIZE
, &data
);
6417 _ReservedView3__5BView(BView
* view
)
6420 perform_data_max_size data
;
6421 view
->Perform(PERFORM_CODE_MAX_SIZE
, &data
);
6426 _ReservedView4__5BView(BView
* view
)
6429 perform_data_preferred_size data
;
6430 view
->Perform(PERFORM_CODE_PREFERRED_SIZE
, &data
);
6431 return data
.return_value
;
6435 extern "C" BAlignment
6436 _ReservedView5__5BView(BView
* view
)
6438 // LayoutAlignment()
6439 perform_data_layout_alignment data
;
6440 view
->Perform(PERFORM_CODE_LAYOUT_ALIGNMENT
, &data
);
6441 return data
.return_value
;
6446 _ReservedView6__5BView(BView
* view
)
6448 // HasHeightForWidth()
6449 perform_data_has_height_for_width data
;
6450 view
->Perform(PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH
, &data
);
6451 return data
.return_value
;
6456 _ReservedView7__5BView(BView
* view
, float width
, float* min
, float* max
,
6459 // GetHeightForWidth()
6460 perform_data_get_height_for_width data
;
6462 view
->Perform(PERFORM_CODE_GET_HEIGHT_FOR_WIDTH
, &data
);
6467 if (preferred
!= NULL
)
6468 *preferred
= data
.preferred
;
6473 _ReservedView8__5BView(BView
* view
, BLayout
* layout
)
6476 perform_data_set_layout data
;
6477 data
.layout
= layout
;
6478 view
->Perform(PERFORM_CODE_SET_LAYOUT
, &data
);
6483 _ReservedView9__5BView(BView
* view
, bool descendants
)
6485 // LayoutInvalidated()
6486 perform_data_layout_invalidated data
;
6487 data
.descendants
= descendants
;
6488 view
->Perform(PERFORM_CODE_LAYOUT_INVALIDATED
, &data
);
6493 _ReservedView10__5BView(BView
* view
)
6496 view
->Perform(PERFORM_CODE_DO_LAYOUT
, NULL
);
6500 #endif // __GNUC__ == 2
6504 B_IF_GCC_2(_ReservedView11__5BView
, _ZN5BView15_ReservedView11Ev
)(
6505 BView
* view
, BPoint point
, BToolTip
** _toolTip
)
6508 perform_data_get_tool_tip_at data
;
6510 data
.tool_tip
= _toolTip
;
6511 view
->Perform(PERFORM_CODE_GET_TOOL_TIP_AT
, &data
);
6512 return data
.return_value
;
6517 B_IF_GCC_2(_ReservedView12__5BView
, _ZN5BView15_ReservedView12Ev
)(
6521 view
->Perform(PERFORM_CODE_LAYOUT_CHANGED
, NULL
);
6525 void BView::_ReservedView13() {}
6526 void BView::_ReservedView14() {}
6527 void BView::_ReservedView15() {}
6528 void BView::_ReservedView16() {}
6531 BView::BView(const BView
& other
)
6535 // this is private and not functional, but exported
6540 BView::operator=(const BView
& other
)
6542 // this is private and not functional, but exported
6548 BView::_PrintToStream()
6550 printf("BView::_PrintToStream()\n");
6551 printf("\tName: %s\n"
6553 "\tFirstChild: %s\n"
6554 "\tNextSibling: %s\n"
6555 "\tPrevSibling: %s\n"
6556 "\tOwner(Window): %s\n"
6557 "\tToken: %" B_PRId32
"\n"
6558 "\tFlags: %" B_PRId32
"\n"
6559 "\tView origin: (%f,%f)\n"
6560 "\tView Bounds rectangle: (%f,%f,%f,%f)\n"
6561 "\tShow level: %d\n"
6564 "\tVertical Scrollbar %s\n"
6565 "\tHorizontal Scrollbar %s\n"
6566 "\tIs Printing?: %s\n"
6568 "\tEventMask: %" B_PRId32
"\n"
6569 "\tEventOptions: %" B_PRId32
"\n",
6571 fParent
? fParent
->Name() : "NULL",
6572 fFirstChild
? fFirstChild
->Name() : "NULL",
6573 fNextSibling
? fNextSibling
->Name() : "NULL",
6574 fPreviousSibling
? fPreviousSibling
->Name() : "NULL",
6575 fOwner
? fOwner
->Name() : "NULL",
6576 _get_object_token_(this),
6578 fParentOffset
.x
, fParentOffset
.y
,
6579 fBounds
.left
, fBounds
.top
, fBounds
.right
, fBounds
.bottom
,
6581 fTopLevelView
? "YES" : "NO",
6582 fCurrentPicture
? "YES" : "NULL",
6583 fVerScroller
? "YES" : "NULL",
6584 fHorScroller
? "YES" : "NULL",
6585 fIsPrinting
? "YES" : "NO",
6586 fShelf
? "YES" : "NO",
6590 printf("\tState status:\n"
6591 "\t\tLocalCoordianteSystem: (%f,%f)\n"
6592 "\t\tPenLocation: (%f,%f)\n"
6594 "\t\tHighColor: [%d,%d,%d,%d]\n"
6595 "\t\tLowColor: [%d,%d,%d,%d]\n"
6596 "\t\tViewColor: [%d,%d,%d,%d]\n"
6597 "\t\tPattern: %" B_PRIx64
"\n"
6598 "\t\tDrawingMode: %d\n"
6599 "\t\tLineJoinMode: %d\n"
6600 "\t\tLineCapMode: %d\n"
6601 "\t\tMiterLimit: %f\n"
6602 "\t\tAlphaSource: %d\n"
6603 "\t\tAlphaFuntion: %d\n"
6605 "\t\t(Print)FontAliasing: %s\n"
6607 fState
->origin
.x
, fState
->origin
.y
,
6608 fState
->pen_location
.x
, fState
->pen_location
.y
,
6610 fState
->high_color
.red
, fState
->high_color
.blue
, fState
->high_color
.green
, fState
->high_color
.alpha
,
6611 fState
->low_color
.red
, fState
->low_color
.blue
, fState
->low_color
.green
, fState
->low_color
.alpha
,
6612 fState
->view_color
.red
, fState
->view_color
.blue
, fState
->view_color
.green
, fState
->view_color
.alpha
,
6613 *((uint64
*)&(fState
->pattern
)),
6614 fState
->drawing_mode
,
6617 fState
->miter_limit
,
6618 fState
->alpha_source_mode
,
6619 fState
->alpha_function_mode
,
6621 fState
->font_aliasing
? "YES" : "NO");
6623 fState
->font
.PrintToStream();
6625 // TODO: also print the line array.
6633 BView
* c
= fFirstChild
; //c = short for: current
6634 printf( "'%s'\n", Name() );
6639 for (int i
= 0; i
< spaces
; i
++)
6642 printf( "'%s'\n", c
->Name() );
6646 if (c
->fFirstChild
) {
6651 if (c
->fNextSibling
) {
6652 c
= c
->fNextSibling
;
6655 while (!c
->fParent
->fNextSibling
&& c
->fParent
!= this) {
6660 // that enough! We've reached this view.
6661 if (c
->fParent
== this)
6664 c
= c
->fParent
->fNextSibling
;
6677 BView::Private::LayoutItemAt(int32 index
)
6679 return fView
->fLayoutData
->fLayoutItems
.ItemAt(index
);
6684 BView::Private::CountLayoutItems()
6686 return fView
->fLayoutData
->fLayoutItems
.CountItems();
6691 BView::Private::RegisterLayoutItem(BLayoutItem
* item
)
6693 fView
->fLayoutData
->fLayoutItems
.AddItem(item
);
6698 BView::Private::DeregisterLayoutItem(BLayoutItem
* item
)
6700 fView
->fLayoutData
->fLayoutItems
.RemoveItem(item
);
6705 BView::Private::MinMaxValid()
6707 return fView
->fLayoutData
->fMinMaxValid
;
6712 BView::Private::WillLayout()
6714 BView::LayoutData
* data
= fView
->fLayoutData
;
6715 if (data
->fLayoutInProgress
)
6717 if (data
->fNeedsRelayout
|| !data
->fLayoutValid
|| !data
->fMinMaxValid
)