1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * frameworkelement.cpp:
5 * Copyright 2007 Novell, Inc. (http://www.novell.com)
7 * See the LICENSE file included with the distribution for details.
17 #include "application.h"
19 #include "namescope.h"
20 #include "frameworkelement.h"
22 #include "thickness.h"
23 #include "collection.h"
25 #include "validators.h"
27 #define MAX_LAYOUT_PASSES 250
29 FrameworkElementProvider::FrameworkElementProvider (DependencyObject
*obj
, PropertyPrecedence precedence
) : PropertyValueProvider (obj
, precedence
)
31 actual_height_value
= NULL
;
32 actual_width_value
= NULL
;
33 last
= Size (-INFINITY
, -INFINITY
);
36 FrameworkElementProvider::~FrameworkElementProvider ()
38 delete actual_height_value
;
39 delete actual_width_value
;
43 FrameworkElementProvider::GetPropertyValue (DependencyProperty
*property
)
45 if (property
->GetId () != FrameworkElement::ActualHeightProperty
&&
46 property
->GetId () != FrameworkElement::ActualWidthProperty
)
49 FrameworkElement
*element
= (FrameworkElement
*) obj
;
51 Size actual
= last
.IsEmpty () ? Size () : last
;
52 Surface
*surface
= obj
->GetSurface ();
54 if (!LayoutInformation::GetPreviousConstraint (obj
) || (surface
&& surface
->IsTopLevel (element
) && obj
->Is (Type::PANEL
)))
55 actual
= element
->ComputeActualSize ();
60 if (actual_height_value
)
61 delete actual_height_value
;
63 if (actual_width_value
)
64 delete actual_width_value
;
66 actual_height_value
= new Value (actual
.height
);
67 actual_width_value
= new Value (actual
.width
);
70 if (property
->GetId () == FrameworkElement::ActualHeightProperty
) {
71 return actual_height_value
;
73 return actual_width_value
;
77 FrameworkElement::FrameworkElement ()
79 SetObjectType (Type::FRAMEWORKELEMENT
);
81 default_style_applied
= false;
84 bounds_with_children
= Rect ();
85 logical_parent
= NULL
;
87 providers
[PropertyPrecedence_LocalStyle
] = new StylePropertyValueProvider (this, PropertyPrecedence_LocalStyle
);
88 providers
[PropertyPrecedence_DefaultStyle
] = new StylePropertyValueProvider (this, PropertyPrecedence_DefaultStyle
);
89 providers
[PropertyPrecedence_DynamicValue
] = new FrameworkElementProvider (this, PropertyPrecedence_DynamicValue
);
92 FrameworkElement::~FrameworkElement ()
97 FrameworkElement::RenderLayoutClip (cairo_t
*cr
)
99 Geometry
*geom
= LayoutInformation::GetClip (this);
111 FrameworkElement::GetTransformOrigin ()
113 Point
*user_xform_origin
= GetRenderTransformOrigin ();
115 double width
= GetActualWidth ();
116 double height
= GetActualHeight ();
118 return Point (width
* user_xform_origin
->x
,
119 height
* user_xform_origin
->y
);
123 FrameworkElement::SetLogicalParent (DependencyObject
*logical_parent
, MoonError
*error
)
125 if (logical_parent
&& this->logical_parent
&& this->logical_parent
!= logical_parent
) {
126 MoonError::FillIn (error
, MoonError::INVALID_OPERATION
, "Element is a child of another element");
130 this->logical_parent
= logical_parent
;
134 FrameworkElement::ElementAdded (UIElement
*item
)
136 UIElement::ElementAdded (item
);
138 //item->UpdateLayout ();
140 if (IsLayoutContainer () && item->Is (Type::FRAMEWORKELEMENT)) {
141 FrameworkElement *fe = (FrameworkElement *)item;
142 fe->SetActualWidth (0.0);
143 fe->SetActualHeight (0.0);
149 FrameworkElement::OnPropertyChanged (PropertyChangedEventArgs
*args
, MoonError
*error
)
151 if (args
->GetProperty ()->GetOwnerType() != Type::FRAMEWORKELEMENT
) {
152 UIElement::OnPropertyChanged (args
, error
);
156 if (args
->GetId () == FrameworkElement::WidthProperty
||
157 args
->GetId () == FrameworkElement::MaxWidthProperty
||
158 args
->GetId () == FrameworkElement::MinWidthProperty
||
159 args
->GetId () == FrameworkElement::MaxHeightProperty
||
160 args
->GetId () == FrameworkElement::MinHeightProperty
||
161 args
->GetId () == FrameworkElement::HeightProperty
||
162 args
->GetId () == FrameworkElement::MarginProperty
) {
164 Point
*p
= GetRenderTransformOrigin ();
166 /* normally we'd only update the bounds of this
167 element on a width/height change, but if the render
168 transform is someplace other than (0,0), the
169 transform needs to be updated as well. */
170 FullInvalidate (p
->x
!= 0.0 || p
->y
!= 0.0);
172 FrameworkElement
*visual_parent
= (FrameworkElement
*)GetVisualParent ();
174 if (visual_parent
->Is (Type::CANVAS
)) {
175 if (!IsLayoutContainer ()) {
176 ClearValue (FrameworkElement::ActualHeightProperty
);
177 ClearValue (FrameworkElement::ActualWidthProperty
);
179 InvalidateMeasure ();
180 InvalidateArrange ();
182 visual_parent
->InvalidateMeasure ();
183 InvalidateMeasure ();
184 InvalidateArrange ();
187 InvalidateMeasure ();
188 InvalidateArrange ();
192 else if (args
->GetId () == FrameworkElement::StyleProperty
) {
193 if (args
->GetNewValue()) {
194 Style
*s
= args
->GetNewValue()->AsStyle ();
196 // this has a side effect of calling
197 // ProviderValueChanged on all values
198 // in the style, so we might end up
199 // with lots of property notifications
200 // here (reentrancy ok?)
202 Application::GetCurrent()->ApplyStyle (this, s
);
204 ((StylePropertyValueProvider
*)providers
[PropertyPrecedence_LocalStyle
])->SealStyle (s
);
208 else if (args
->GetId () == FrameworkElement::HorizontalAlignmentProperty
||
209 args
->GetId () == FrameworkElement::VerticalAlignmentProperty
) {
210 InvalidateArrange ();
211 FullInvalidate (true);
214 NotifyListenersOfPropertyChange (args
, error
);
218 FrameworkElement::ApplySizeConstraints (const Size
&size
)
220 Size
specified (GetWidth (), GetHeight ());
221 Size
constrained (GetMinWidth (), GetMinHeight ());
223 constrained
= constrained
.Max (size
);
225 if (!isnan (specified
.width
))
226 constrained
.width
= specified
.width
;
228 if (!isnan (specified
.height
))
229 constrained
.height
= specified
.height
;
231 constrained
= constrained
.Min (GetMaxWidth (), GetMaxHeight ());
232 constrained
= constrained
.Max (GetMinWidth (), GetMinHeight ());
238 FrameworkElement::ComputeBounds ()
240 Size
size (GetActualWidth (), GetActualHeight ());
241 size
= ApplySizeConstraints (size
);
243 extents
= Rect (0, 0, size
.width
, size
.height
);
245 bounds
= IntersectBoundsWithClipPath (extents
, false).Transform (&absolute_xform
);
246 bounds_with_children
= bounds
;
248 VisualTreeWalker walker
= VisualTreeWalker (this);
249 while (UIElement
*item
= walker
.Step ()) {
250 if (!item
->GetRenderVisible ())
253 bounds_with_children
= bounds_with_children
.Union (item
->GetSubtreeBounds ());
258 FrameworkElement::GetSubtreeBounds ()
260 VisualTreeWalker walker
= VisualTreeWalker (this);
261 if (GetSubtreeObject () != NULL
)
262 return bounds_with_children
;
268 FrameworkElement::ComputeActualSize ()
270 UIElement
*parent
= GetVisualParent ();
272 if ((parent
&& !parent
->Is (Type::CANVAS
)) || (!Is (Type::CANVAS
) && IsLayoutContainer ()))
273 return GetDesiredSize ();
277 actual
= ApplySizeConstraints (actual
);
283 FrameworkElement::InsideObject (cairo_t
*cr
, double x
, double y
)
285 double width
= GetActualWidth ();
286 double height
= GetActualHeight ();
287 double nx
= x
, ny
= y
;
289 TransformPoint (&nx
, &ny
);
290 if (nx
< 0 || ny
< 0 || nx
> width
|| ny
> height
)
293 Geometry
*layout_clip
= LayoutInformation::GetLayoutClip (this);
294 if (layout_clip
&& !layout_clip
->GetBounds ().PointInside (nx
, ny
))
297 return UIElement::InsideObject (cr
, x
, y
);
301 FrameworkElement::HitTest (cairo_t
*cr
, Point p
, List
*uielement_list
)
303 if (!GetRenderVisible ())
306 if (!GetHitTestVisible ())
309 // first a quick bounds check
310 if (!GetSubtreeBounds().PointInside (p
.x
, p
.y
))
313 if (!InsideClip (cr
, p
.x
, p
.y
))
316 /* create our node and stick it on front */
317 List::Node
*us
= uielement_list
->Prepend (new UIElementNode (this));
320 VisualTreeWalker walker
= VisualTreeWalker (this, ZReverse
);
321 while (UIElement
*child
= walker
.Step ()) {
322 child
->HitTest (cr
, p
, uielement_list
);
324 if (us
!= uielement_list
->First ()) {
330 if (!hit
&& !InsideObject (cr
, p
.x
, p
.y
))
331 uielement_list
->Remove (us
);
335 FrameworkElement::FindElementsInHostCoordinates (cairo_t
*cr
, Point host
, List
*uielement_list
)
337 if (!GetRenderVisible ())
340 if (!GetHitTestVisible ())
343 if (bounds_with_children
.height
<= 0)
350 RenderClipPath (cr
, true);
352 cairo_identity_matrix (cr
);
353 bool res
= cairo_in_fill (cr
, host
.x
, host
.y
);
361 /* create our node and stick it on front */
362 List::Node
*us
= uielement_list
->Prepend (new UIElementNode (this));
364 VisualTreeWalker walker
= VisualTreeWalker (this, ZForward
);
365 while (UIElement
*child
= walker
.Step ())
366 child
->FindElementsInHostCoordinates (cr
, host
, uielement_list
);
368 if (us
== uielement_list
->First ()) {
371 cairo_set_matrix (cr
, &absolute_xform
);
372 Render (cr
, &all
, true);
373 cairo_identity_matrix (cr
);
375 if (!CanFindElement () ||
376 !(cairo_in_fill (cr
, host
.x
, host
.y
) || cairo_in_stroke (cr
, host
.x
, host
.y
)))
377 uielement_list
->Remove (us
);
382 // FIXME: This is not the fastest way of implementing this, decomposing the rectangle into
383 // a series of points is probably going to be quite slow. It's a good first effort.
385 FrameworkElement::FindElementsInHostCoordinates (cairo_t
*cr
, Rect r
, List
*uielement_list
)
388 if (!GetRenderVisible ())
391 if (!GetHitTestVisible ())
394 if (bounds_with_children
.height
<= 0)
397 if (!bounds_with_children
.IntersectsWith (r
))
404 RenderClipPath (cr
, true);
406 cairo_identity_matrix (cr
);
408 for (int i
=r
.x
; i
< r
.x
+ r
.width
&& !res
; i
++)
409 for (int j
=r
.y
; j
< r
.y
+ r
.height
&& !res
; j
++)
410 res
= cairo_in_fill (cr
, i
, j
);
419 /* create our node and stick it on front */
420 List::Node
*us
= uielement_list
->Prepend (new UIElementNode (this));
422 VisualTreeWalker walker
= VisualTreeWalker (this, ZForward
);
423 while (UIElement
*child
= walker
.Step ())
424 child
->FindElementsInHostCoordinates (cr
, r
, uielement_list
);
426 if (us
== uielement_list
->First ()) {
429 cairo_set_matrix (cr
, &absolute_xform
);
430 Render (cr
, &all
, true);
431 cairo_identity_matrix (cr
);
434 if (CanFindElement ()) {
435 for (int i
= r
.x
; i
< (r
.x
+ r
.width
) && !res
; i
++)
436 for (int j
= r
.y
; j
< (r
.y
+ r
.height
) && !res
; j
++)
437 res
= cairo_in_fill (cr
, i
, j
) || cairo_in_stroke (cr
, i
, j
);
441 uielement_list
->Remove (us
);
447 FrameworkElement::GetSizeForBrush (cairo_t
*cr
, double *width
, double *height
)
449 *width
= GetActualWidth ();
450 *height
= GetActualHeight ();
454 FrameworkElement::Measure (Size availableSize
)
456 //LOG_LAYOUT ("measuring %p %s %g,%g\n", this, GetTypeName (), availableSize.width, availableSize.height);
457 if (Is(Type::CONTROL
)) {
458 Control
*control
= (Control
*)this;
459 control
->ApplyTemplate();
462 if (!IsLayoutContainer ()) {
463 UIElement
*parent
= GetVisualParent ();
465 if (!parent
|| parent
->Is (Type::CANVAS
)) {
466 InvalidateArrange ();
468 dirty_flags
&= ~DirtyMeasure
;
473 Size
*last
= LayoutInformation::GetPreviousConstraint (this);
474 bool domeasure
= (this->dirty_flags
& DirtyMeasure
) > 0;
476 domeasure
|= !last
|| last
->width
!= availableSize
.width
|| last
->height
!= availableSize
.height
;
478 if (GetVisibility () == VisibilityCollapsed
) {
479 SetDesiredSize (Size (0,0));
486 LayoutInformation::SetPreviousConstraint (this, &availableSize
);
488 InvalidateArrange ();
491 dirty_flags
&= ~DirtyMeasure
;
493 Thickness margin
= *GetMargin ();
494 Size size
= availableSize
.GrowBy (-margin
);
496 size
= ApplySizeConstraints (size
);
499 size
= (*measure_cb
)(size
);
501 size
= MeasureOverride (size
);
503 // postcondition the results
504 size
= ApplySizeConstraints (size
);
506 size
= size
.GrowBy (margin
);
507 size
= size
.Min (availableSize
);
509 if (GetUseLayoutRounding ()) {
510 size
.width
= floor (size
.width
);
511 size
.height
= floor (size
.height
);
514 SetDesiredSize (size
);
518 FrameworkElement::MeasureOverride (Size availableSize
)
520 Size desired
= Size (0,0);
522 if (!IsLayoutContainer ())
525 availableSize
= ApplySizeConstraints (availableSize
);
527 VisualTreeWalker walker
= VisualTreeWalker (this);
528 while (UIElement
*child
= walker
.Step ()) {
529 if (child
->GetVisibility () != VisibilityVisible
)
532 child
->Measure (availableSize
);
533 desired
= child
->GetDesiredSize ();
536 desired
= ApplySizeConstraints (desired
);
542 // not sure about the disconnect between these two methods.. I would
543 // imagine both should take Rects and ArrangeOverride would return a
544 // rectangle as well..
546 FrameworkElement::Arrange (Rect finalRect
)
548 //LOG_LAYOUT ("arranging %p %s %g,%g,%g,%g\n", this, GetTypeName (), finalRect.x, finalRect.y, finalRect.width, finalRect.height);
549 Rect
*slot
= LayoutInformation::GetLayoutSlot (this);
550 bool doarrange
= this->dirty_flags
& DirtyArrange
;
552 doarrange
|= slot
? *slot
!= finalRect
: true;
554 if (finalRect
.width
< 0 || finalRect
.height
< 0
555 || isinf (finalRect
.width
) || isinf (finalRect
.height
)
556 || isnan (finalRect
.width
) || isnan (finalRect
.height
)) {
557 Size desired
= GetDesiredSize ();
558 g_warning ("invalid arguments to Arrange (%g,%g,%g,%g) Desired = (%g,%g)", finalRect
.x
, finalRect
.y
, finalRect
.width
, finalRect
.height
, desired
.width
, desired
.height
);
562 if (GetVisibility () == VisibilityCollapsed
) {
563 SetRenderSize (Size(0,0));
571 * FIXME I'm not happy with doing this here but until I come
572 * up with a better plan make sure that layout elements have
573 * been measured at least once
575 if (IsContainer () && !LayoutInformation::GetPreviousConstraint (this))
576 Measure (Size (finalRect
.width
, finalRect
.height
));
578 LayoutInformation::SetLayoutSlot (this, &finalRect
);
579 ClearValue (LayoutInformation::LayoutClipProperty
);
580 //LayoutInformation::SetLayoutClip (this, NULL);
582 this->dirty_flags
&= ~DirtyArrange
;
584 Thickness margin
= *GetMargin ();
585 Rect child_rect
= finalRect
.GrowBy (-margin
);
587 cairo_matrix_init_translate (&layout_xform
, child_rect
.x
, child_rect
.y
);
590 this->dirty_flags
&= ~DirtyArrange
;
592 Size
offer (child_rect
.width
, child_rect
.height
);
594 Size desired
= GetDesiredSize ().GrowBy (-margin
);
596 HorizontalAlignment horiz
= GetHorizontalAlignment ();
597 VerticalAlignment vert
= GetVerticalAlignment ();
599 if (horiz
!= HorizontalAlignmentStretch
)
600 offer
.width
= MIN (offer
.width
, desired
.width
);
602 if (vert
!= VerticalAlignmentStretch
)
603 offer
.height
= MIN (offer
.height
, desired
.height
);
605 offer
= ApplySizeConstraints (offer
);
608 response
= (*arrange_cb
)(offer
);
610 response
= ArrangeOverride (offer
);
612 /* XXX FIXME horrible hack */
613 UIElement
*parent
= GetVisualParent ();
614 bool in_layout
= IsLayoutContainer ();
617 if (!parent
|| parent
->Is (Type::CANVAS
))
620 Size old_size
= GetRenderSize ();
621 //Point *old_offset = LayoutInformation::GetVisualOffset (this);
622 ClearValue (LayoutInformation::VisualOffsetProperty
);
624 if (in_layout
&& GetUseLayoutRounding ()) {
625 response
.width
= floor (response
.width
);
626 response
.height
= floor (response
.height
);
629 SetActualWidth (response
.width
);
630 SetActualHeight (response
.height
);
632 response
= ApplySizeConstraints (response
);
633 Point
visual_offset (child_rect
.x
, child_rect
.y
);
635 if (GetVisualParent ()) {
637 case HorizontalAlignmentLeft
:
639 case HorizontalAlignmentRight
:
640 visual_offset
.x
+= child_rect
.width
- response
.width
;
642 case HorizontalAlignmentCenter
:
643 visual_offset
.x
+= (child_rect
.width
- response
.width
) * .5;
646 visual_offset
.x
+= MAX ((child_rect
.width
- response
.width
) * .5, 0);
651 case VerticalAlignmentTop
:
653 case VerticalAlignmentBottom
:
654 visual_offset
.y
+= child_rect
.height
- response
.height
;
656 case VerticalAlignmentCenter
:
657 visual_offset
.y
+= (child_rect
.height
- response
.height
) * .5;
660 visual_offset
.y
+= MAX ((child_rect
.height
- response
.height
) * .5, 0);
666 cairo_matrix_init_translate (&layout_xform
, visual_offset
.x
, visual_offset
.y
);
667 LayoutInformation::SetVisualOffset (this, &visual_offset
);
668 SetRenderSize (response
);
670 Rect layout_clip
= finalRect
;
671 layout_clip
.x
-= visual_offset
.x
;
672 layout_clip
.y
-= visual_offset
.y
;
674 layout_clip
= layout_clip
.GrowBy (-margin
);
675 RectangleGeometry
*rectangle
= new RectangleGeometry ();
676 rectangle
->SetRect (&layout_clip
);
677 LayoutInformation::SetLayoutClip (this, rectangle
);
680 if (old_size
!= response
) { // || (old_offset && *old_offset != visual_offset)) {
681 if (!LayoutInformation::GetLastRenderSize (this))
682 LayoutInformation::SetLastRenderSize (this, &old_size
);
684 // XXX what do we do with finalRect.x and y?
689 FrameworkElement::ArrangeOverride (Size finalSize
)
691 finalSize
= ApplySizeConstraints (finalSize
);
693 if (!IsLayoutContainer ())
696 Size arranged
= finalSize
;
698 VisualTreeWalker walker
= VisualTreeWalker (this);
699 while (UIElement
*child
= walker
.Step ()) {
700 if (child
->GetVisibility () != VisibilityVisible
)
703 Rect
childRect (0,0,finalSize
.width
,finalSize
.height
);
705 child
->Arrange (childRect
);
706 arranged
= child
->GetRenderSize ();
708 arranged
= arranged
.Max (finalSize
);
711 arranged
= arranged
.Max (finalSize
);
717 FrameworkElement::UpdateLayout ()
719 UIElement
*element
= this;
720 UIElement
*parent
= NULL
;
723 while ((parent
= element
->GetVisualParent ())) {
724 if (parent
->Is (Type::CANVAS
))
730 Surface
*surface
= element
->GetSurface ();
732 LOG_LAYOUT ("\nFrameworkElement::UpdateLayout: ");
733 List
*measure_list
= new List ();
734 List
*arrange_list
= new List ();
735 List
*updated_list
= new List ();
736 List
*size_list
= new List ();
737 bool updated
= false;
739 while (i
< MAX_LAYOUT_PASSES
) {
740 LOG_LAYOUT ("\u267c");
742 measure_list
->Clear (true);
743 arrange_list
->Clear (true);
744 updated_list
->Clear (true);
745 size_list
->Clear (true);
748 DeepTreeWalker
measure_walker (element
);
749 while (FrameworkElement
*child
= (FrameworkElement
*)measure_walker
.Step ()) {
750 FrameworkElement
*parent
= (FrameworkElement
*)child
->GetVisualParent ();
752 if (parent
&& parent
->IsLoaded () && !child
->IsLoaded ()) {
753 LOG_LAYOUT ("FrameworkElement::UpdateLayout: element (%p) not yet loaded\n", child
);
755 List
*load_list
= child
->WalkTreeForLoaded (false);
756 child
->EmitSubtreeLoad (load_list
);
760 if ((child
->flags
& UIElement::RENDER_VISIBLE
) == 0) {
761 measure_walker
.SkipBranch ();
765 if (child
->dirty_flags
& DirtyMeasure
) {
766 UIElement
*parent
= child
->GetVisualParent ();
767 if ((parent
&& !parent
->Is (Type::CANVAS
)) || child
->IsContainer ()) {
768 measure_list
->Append (new UIElementNode (child
));
769 //g_warning ("adding %p, %s", child, child->GetTypeName ());
770 } else if (!measure_list
->IsEmpty ()) {
771 measure_walker
.SkipBranch ();
775 if (!measure_list
->IsEmpty ())
778 if (child
->dirty_flags
& DirtyArrange
)
779 arrange_list
->Append (new UIElementNode (child
));
781 if (!arrange_list
->IsEmpty ())
784 if (child
->ReadLocalValue (LayoutInformation::LastRenderSizeProperty
))
785 size_list
->Append (new UIElementNode (child
));
787 if (!size_list
->IsEmpty ())
791 updated_list
->Append (new UIElementNode (child
));
794 if (!measure_list
->IsEmpty ()) {
796 surface
->needs_measure
= false;
797 while (UIElementNode
* node
= (UIElementNode
*)measure_list
->First ()) {
798 measure_list
->Unlink (node
);
800 node
->uielement
->DoMeasure ();
801 //if (node->uielement->GetVisuaParent ()->dirty_flags & dirty_measure)
802 // node->Prepend (new UIElementNode (parent));
807 } else if (!arrange_list
->IsEmpty ()) {
809 surface
->needs_arrange
= false;
810 while (UIElementNode
*node
= (UIElementNode
*)arrange_list
->First ()) {
811 arrange_list
->Unlink (node
);
813 if (surface
&& surface
->needs_measure
) {
818 node
->uielement
->DoArrange ();
819 //if (node->uielement->GetVisuaParent ()->dirty_flags & dirty_arrange)
820 // node->Prepend (new UIElementNode (parent));
825 } else if (!size_list
->IsEmpty ()) {
826 while (UIElementNode
*node
= (UIElementNode
*)size_list
->First ()) {
827 if (surface
&& (surface
->needs_measure
|| surface
->needs_arrange
)) {
828 surface
->needs_measure
= surface
->needs_arrange
= false;
832 size_list
->Unlink (node
);
833 FrameworkElement
*fe
= (FrameworkElement
*) node
->uielement
;
836 Size
*last
= LayoutInformation::GetLastRenderSize (fe
);
838 SizeChangedEventArgs
*args
= new SizeChangedEventArgs (*last
, fe
->GetRenderSize ());
839 fe
->ClearValue (LayoutInformation::LastRenderSizeProperty
, false);
840 fe
->Emit (FrameworkElement::SizeChangedEvent
, args
);
844 } else if (!updated_list
->IsEmpty ()) {
846 while (UIElementNode
*node
= (UIElementNode
*)updated_list
->First ()) {
847 updated_list
->Unlink (node
);
848 FrameworkElement
*fe
= (FrameworkElement
*)node
->uielement
;
850 fe
->Emit (LayoutUpdatedEvent
);
862 if (i
>= MAX_LAYOUT_PASSES
) {
863 LOG_LAYOUT ("\n************** UpdateLayout Bailing Out after %d Passes *******************\n", i
);
865 LOG_LAYOUT (" (%d)\n", i
);
870 FrameworkElement::RegisterManagedOverrides (MeasureOverrideCallback measure_cb
, ArrangeOverrideCallback arrange_cb
)
872 this->measure_cb
= measure_cb
;
873 this->arrange_cb
= arrange_cb
;
877 FrameworkElement::SetDefaultStyle (Style
*style
)
880 Application::GetCurrent()->ApplyStyle (this, style
);
881 default_style_applied
= true;
882 ((StylePropertyValueProvider
*)providers
[PropertyPrecedence_DefaultStyle
])->SealStyle (style
);