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::SetValueWithErrorImpl (DependencyProperty
*property
, Value
*value
, MoonError
*error
)
151 return UIElement::SetValueWithErrorImpl (property
, value
, error
);
155 FrameworkElement::OnPropertyChanged (PropertyChangedEventArgs
*args
, MoonError
*error
)
157 if (args
->GetProperty ()->GetOwnerType() != Type::FRAMEWORKELEMENT
) {
158 UIElement::OnPropertyChanged (args
, error
);
162 if (args
->GetId () == FrameworkElement::WidthProperty
||
163 args
->GetId () == FrameworkElement::MaxWidthProperty
||
164 args
->GetId () == FrameworkElement::MinWidthProperty
||
165 args
->GetId () == FrameworkElement::MaxHeightProperty
||
166 args
->GetId () == FrameworkElement::MinHeightProperty
||
167 args
->GetId () == FrameworkElement::HeightProperty
||
168 args
->GetId () == FrameworkElement::MarginProperty
) {
170 Point
*p
= GetRenderTransformOrigin ();
172 /* normally we'd only update the bounds of this
173 element on a width/height change, but if the render
174 transform is someplace other than (0,0), the
175 transform needs to be updated as well. */
176 FullInvalidate (p
->x
!= 0.0 || p
->y
!= 0.0);
178 FrameworkElement
*visual_parent
= (FrameworkElement
*)GetVisualParent ();
180 if (visual_parent
->Is (Type::CANVAS
)) {
181 if (!IsLayoutContainer ()) {
182 ClearValue (FrameworkElement::ActualHeightProperty
);
183 ClearValue (FrameworkElement::ActualWidthProperty
);
185 InvalidateMeasure ();
186 InvalidateArrange ();
188 visual_parent
->InvalidateMeasure ();
189 InvalidateMeasure ();
190 InvalidateArrange ();
193 InvalidateMeasure ();
194 InvalidateArrange ();
198 else if (args
->GetId () == FrameworkElement::StyleProperty
) {
199 if (args
->GetNewValue()) {
200 Style
*s
= args
->GetNewValue()->AsStyle ();
202 // this has a side effect of calling
203 // ProviderValueChanged on all values
204 // in the style, so we might end up
205 // with lots of property notifications
206 // here (reentrancy ok?)
208 Application::GetCurrent()->ApplyStyle (this, s
);
210 ((StylePropertyValueProvider
*)providers
[PropertyPrecedence_LocalStyle
])->SealStyle (s
);
214 else if (args
->GetId () == FrameworkElement::HorizontalAlignmentProperty
||
215 args
->GetId () == FrameworkElement::VerticalAlignmentProperty
) {
216 InvalidateArrange ();
217 FullInvalidate (true);
220 NotifyListenersOfPropertyChange (args
, error
);
224 FrameworkElement::ApplySizeConstraints (const Size
&size
)
226 Size
specified (GetWidth (), GetHeight ());
227 Size
constrained (GetMinWidth (), GetMinHeight ());
229 constrained
= constrained
.Max (size
);
231 if (!isnan (specified
.width
))
232 constrained
.width
= specified
.width
;
234 if (!isnan (specified
.height
))
235 constrained
.height
= specified
.height
;
237 constrained
= constrained
.Min (GetMaxWidth (), GetMaxHeight ());
238 constrained
= constrained
.Max (GetMinWidth (), GetMinHeight ());
244 FrameworkElement::ComputeBounds ()
246 Size
size (GetActualWidth (), GetActualHeight ());
247 size
= ApplySizeConstraints (size
);
249 extents
= Rect (0, 0, size
.width
, size
.height
);
251 bounds
= IntersectBoundsWithClipPath (extents
, false).Transform (&absolute_xform
);
252 bounds_with_children
= bounds
;
254 VisualTreeWalker walker
= VisualTreeWalker (this);
255 while (UIElement
*item
= walker
.Step ()) {
256 if (!item
->GetRenderVisible ())
259 bounds_with_children
= bounds_with_children
.Union (item
->GetSubtreeBounds ());
264 FrameworkElement::GetSubtreeBounds ()
266 VisualTreeWalker walker
= VisualTreeWalker (this);
267 if (GetSubtreeObject () != NULL
)
268 return bounds_with_children
;
274 FrameworkElement::ComputeActualSize ()
276 UIElement
*parent
= GetVisualParent ();
278 if ((parent
&& !parent
->Is (Type::CANVAS
)) || (!Is (Type::CANVAS
) && IsLayoutContainer ()))
279 return GetDesiredSize ();
283 actual
= ApplySizeConstraints (actual
);
289 FrameworkElement::InsideObject (cairo_t
*cr
, double x
, double y
)
291 double width
= GetActualWidth ();
292 double height
= GetActualHeight ();
293 double nx
= x
, ny
= y
;
295 TransformPoint (&nx
, &ny
);
296 if (nx
< 0 || ny
< 0 || nx
> width
|| ny
> height
)
299 Geometry
*layout_clip
= LayoutInformation::GetLayoutClip (this);
300 if (layout_clip
&& !layout_clip
->GetBounds ().PointInside (nx
, ny
))
303 return UIElement::InsideObject (cr
, x
, y
);
307 FrameworkElement::HitTest (cairo_t
*cr
, Point p
, List
*uielement_list
)
309 if (!GetRenderVisible ())
312 if (!GetHitTestVisible ())
315 // first a quick bounds check
316 if (!GetSubtreeBounds().PointInside (p
.x
, p
.y
))
319 if (!InsideClip (cr
, p
.x
, p
.y
))
322 /* create our node and stick it on front */
323 List::Node
*us
= uielement_list
->Prepend (new UIElementNode (this));
326 VisualTreeWalker walker
= VisualTreeWalker (this, ZReverse
);
327 while (UIElement
*child
= walker
.Step ()) {
328 child
->HitTest (cr
, p
, uielement_list
);
330 if (us
!= uielement_list
->First ()) {
336 if (!hit
&& !InsideObject (cr
, p
.x
, p
.y
))
337 uielement_list
->Remove (us
);
341 FrameworkElement::FindElementsInHostCoordinates (cairo_t
*cr
, Point host
, List
*uielement_list
)
343 if (!GetRenderVisible ())
346 if (!GetHitTestVisible ())
349 if (bounds_with_children
.height
<= 0)
356 RenderClipPath (cr
, true);
358 cairo_identity_matrix (cr
);
359 bool res
= cairo_in_fill (cr
, host
.x
, host
.y
);
367 /* create our node and stick it on front */
368 List::Node
*us
= uielement_list
->Prepend (new UIElementNode (this));
370 VisualTreeWalker walker
= VisualTreeWalker (this, ZForward
);
371 while (UIElement
*child
= walker
.Step ())
372 child
->FindElementsInHostCoordinates (cr
, host
, uielement_list
);
374 if (us
== uielement_list
->First ()) {
377 cairo_set_matrix (cr
, &absolute_xform
);
378 Render (cr
, &all
, true);
379 cairo_identity_matrix (cr
);
381 if (!CanFindElement () ||
382 !(cairo_in_fill (cr
, host
.x
, host
.y
) || cairo_in_stroke (cr
, host
.x
, host
.y
)))
383 uielement_list
->Remove (us
);
388 // FIXME: This is not the fastest way of implementing this, decomposing the rectangle into
389 // a series of points is probably going to be quite slow. It's a good first effort.
391 FrameworkElement::FindElementsInHostCoordinates (cairo_t
*cr
, Rect r
, List
*uielement_list
)
394 if (!GetRenderVisible ())
397 if (!GetHitTestVisible ())
400 if (bounds_with_children
.height
<= 0)
403 if (!bounds_with_children
.IntersectsWith (r
))
410 RenderClipPath (cr
, true);
412 cairo_identity_matrix (cr
);
414 for (int i
=r
.x
; i
< r
.x
+ r
.width
&& !res
; i
++)
415 for (int j
=r
.y
; j
< r
.y
+ r
.height
&& !res
; j
++)
416 res
= cairo_in_fill (cr
, i
, j
);
425 /* create our node and stick it on front */
426 List::Node
*us
= uielement_list
->Prepend (new UIElementNode (this));
428 VisualTreeWalker walker
= VisualTreeWalker (this, ZForward
);
429 while (UIElement
*child
= walker
.Step ())
430 child
->FindElementsInHostCoordinates (cr
, r
, uielement_list
);
432 if (us
== uielement_list
->First ()) {
435 cairo_set_matrix (cr
, &absolute_xform
);
436 Render (cr
, &all
, true);
437 cairo_identity_matrix (cr
);
440 if (CanFindElement ()) {
441 for (int i
= r
.x
; i
< (r
.x
+ r
.width
) && !res
; i
++)
442 for (int j
= r
.y
; j
< (r
.y
+ r
.height
) && !res
; j
++)
443 res
= cairo_in_fill (cr
, i
, j
) || cairo_in_stroke (cr
, i
, j
);
447 uielement_list
->Remove (us
);
453 FrameworkElement::GetSizeForBrush (cairo_t
*cr
, double *width
, double *height
)
455 *width
= GetActualWidth ();
456 *height
= GetActualHeight ();
460 FrameworkElement::Measure (Size availableSize
)
462 //LOG_LAYOUT ("measuring %p %s %g,%g\n", this, GetTypeName (), availableSize.width, availableSize.height);
463 if (Is(Type::CONTROL
)) {
464 Control
*control
= (Control
*)this;
465 control
->ApplyTemplate();
468 if (!IsLayoutContainer ()) {
469 UIElement
*parent
= GetVisualParent ();
471 if (!parent
|| parent
->Is (Type::CANVAS
)) {
472 InvalidateArrange ();
474 dirty_flags
&= ~DirtyMeasure
;
479 Size
*last
= LayoutInformation::GetPreviousConstraint (this);
480 bool domeasure
= (this->dirty_flags
& DirtyMeasure
) > 0;
482 domeasure
|= !last
|| last
->width
!= availableSize
.width
|| last
->height
!= availableSize
.height
;
484 if (GetVisibility () == VisibilityCollapsed
) {
485 SetDesiredSize (Size (0,0));
492 LayoutInformation::SetPreviousConstraint (this, &availableSize
);
494 InvalidateArrange ();
497 dirty_flags
&= ~DirtyMeasure
;
499 Thickness margin
= *GetMargin ();
500 Size size
= availableSize
.GrowBy (-margin
);
502 size
= ApplySizeConstraints (size
);
505 size
= (*measure_cb
)(size
);
507 size
= MeasureOverride (size
);
509 // postcondition the results
510 size
= ApplySizeConstraints (size
);
512 size
= size
.GrowBy (margin
);
513 size
= size
.Min (availableSize
);
515 if (GetUseLayoutRounding ()) {
516 size
.width
= floor (size
.width
);
517 size
.height
= floor (size
.height
);
520 SetDesiredSize (size
);
524 FrameworkElement::MeasureOverride (Size availableSize
)
526 Size desired
= Size (0,0);
528 if (!IsLayoutContainer ())
531 availableSize
= ApplySizeConstraints (availableSize
);
533 VisualTreeWalker walker
= VisualTreeWalker (this);
534 while (UIElement
*child
= walker
.Step ()) {
535 if (child
->GetVisibility () != VisibilityVisible
)
538 child
->Measure (availableSize
);
539 desired
= child
->GetDesiredSize ();
542 desired
= ApplySizeConstraints (desired
);
548 // not sure about the disconnect between these two methods.. I would
549 // imagine both should take Rects and ArrangeOverride would return a
550 // rectangle as well..
552 FrameworkElement::Arrange (Rect finalRect
)
554 //LOG_LAYOUT ("arranging %p %s %g,%g,%g,%g\n", this, GetTypeName (), finalRect.x, finalRect.y, finalRect.width, finalRect.height);
555 Rect
*slot
= LayoutInformation::GetLayoutSlot (this);
556 bool doarrange
= this->dirty_flags
& DirtyArrange
;
558 doarrange
|= slot
? *slot
!= finalRect
: true;
560 if (finalRect
.width
< 0 || finalRect
.height
< 0
561 || isinf (finalRect
.width
) || isinf (finalRect
.height
)
562 || isnan (finalRect
.width
) || isnan (finalRect
.height
)) {
563 Size desired
= GetDesiredSize ();
564 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
);
568 if (GetVisibility () == VisibilityCollapsed
) {
569 SetRenderSize (Size(0,0));
577 * FIXME I'm not happy with doing this here but until I come
578 * up with a better plan make sure that layout elements have
579 * been measured at least once
581 if (IsContainer () && !LayoutInformation::GetPreviousConstraint (this))
582 Measure (Size (finalRect
.width
, finalRect
.height
));
584 LayoutInformation::SetLayoutSlot (this, &finalRect
);
585 ClearValue (LayoutInformation::LayoutClipProperty
);
586 //LayoutInformation::SetLayoutClip (this, NULL);
588 this->dirty_flags
&= ~DirtyArrange
;
590 Thickness margin
= *GetMargin ();
591 Rect child_rect
= finalRect
.GrowBy (-margin
);
593 cairo_matrix_init_translate (&layout_xform
, child_rect
.x
, child_rect
.y
);
596 this->dirty_flags
&= ~DirtyArrange
;
598 Size
offer (child_rect
.width
, child_rect
.height
);
600 Size desired
= GetDesiredSize ().GrowBy (-margin
);
602 HorizontalAlignment horiz
= GetHorizontalAlignment ();
603 VerticalAlignment vert
= GetVerticalAlignment ();
605 if (horiz
!= HorizontalAlignmentStretch
)
606 offer
.width
= MIN (offer
.width
, desired
.width
);
608 if (vert
!= VerticalAlignmentStretch
)
609 offer
.height
= MIN (offer
.height
, desired
.height
);
611 offer
= ApplySizeConstraints (offer
);
614 response
= (*arrange_cb
)(offer
);
616 response
= ArrangeOverride (offer
);
618 /* XXX FIXME horrible hack */
619 UIElement
*parent
= GetVisualParent ();
620 bool in_layout
= IsLayoutContainer ();
623 if (!parent
|| parent
->Is (Type::CANVAS
))
626 Size old_size
= GetRenderSize ();
627 //Point *old_offset = LayoutInformation::GetVisualOffset (this);
628 ClearValue (LayoutInformation::VisualOffsetProperty
);
630 if (in_layout
&& GetUseLayoutRounding ()) {
631 response
.width
= floor (response
.width
);
632 response
.height
= floor (response
.height
);
635 SetActualWidth (response
.width
);
636 SetActualHeight (response
.height
);
638 response
= ApplySizeConstraints (response
);
639 Point
visual_offset (child_rect
.x
, child_rect
.y
);
641 if (GetVisualParent ()) {
643 case HorizontalAlignmentLeft
:
645 case HorizontalAlignmentRight
:
646 visual_offset
.x
+= child_rect
.width
- response
.width
;
648 case HorizontalAlignmentCenter
:
649 visual_offset
.x
+= (child_rect
.width
- response
.width
) * .5;
652 visual_offset
.x
+= MAX ((child_rect
.width
- response
.width
) * .5, 0);
657 case VerticalAlignmentTop
:
659 case VerticalAlignmentBottom
:
660 visual_offset
.y
+= child_rect
.height
- response
.height
;
662 case VerticalAlignmentCenter
:
663 visual_offset
.y
+= (child_rect
.height
- response
.height
) * .5;
666 visual_offset
.y
+= MAX ((child_rect
.height
- response
.height
) * .5, 0);
672 cairo_matrix_init_translate (&layout_xform
, visual_offset
.x
, visual_offset
.y
);
673 LayoutInformation::SetVisualOffset (this, &visual_offset
);
674 SetRenderSize (response
);
676 Rect layout_clip
= finalRect
;
677 layout_clip
.x
-= visual_offset
.x
;
678 layout_clip
.y
-= visual_offset
.y
;
680 layout_clip
= layout_clip
.GrowBy (-margin
);
681 RectangleGeometry
*rectangle
= new RectangleGeometry ();
682 rectangle
->SetRect (&layout_clip
);
683 LayoutInformation::SetLayoutClip (this, rectangle
);
686 if (old_size
!= response
) { // || (old_offset && *old_offset != visual_offset)) {
687 if (!LayoutInformation::GetLastRenderSize (this))
688 LayoutInformation::SetLastRenderSize (this, &old_size
);
690 // XXX what do we do with finalRect.x and y?
695 FrameworkElement::ArrangeOverride (Size finalSize
)
697 finalSize
= ApplySizeConstraints (finalSize
);
699 if (!IsLayoutContainer ())
702 Size arranged
= finalSize
;
704 VisualTreeWalker walker
= VisualTreeWalker (this);
705 while (UIElement
*child
= walker
.Step ()) {
706 if (child
->GetVisibility () != VisibilityVisible
)
709 Rect
childRect (0,0,finalSize
.width
,finalSize
.height
);
711 child
->Arrange (childRect
);
712 arranged
= child
->GetRenderSize ();
714 arranged
= arranged
.Max (finalSize
);
717 arranged
= arranged
.Max (finalSize
);
723 FrameworkElement::UpdateLayout ()
725 UIElement
*element
= this;
726 UIElement
*parent
= NULL
;
729 while ((parent
= element
->GetVisualParent ())) {
730 if (parent
->Is (Type::CANVAS
))
736 Surface
*surface
= element
->GetSurface ();
738 LOG_LAYOUT ("\nFrameworkElement::UpdateLayout: ");
739 List
*measure_list
= new List ();
740 List
*arrange_list
= new List ();
741 List
*updated_list
= new List ();
742 List
*size_list
= new List ();
743 bool updated
= false;
745 while (i
< MAX_LAYOUT_PASSES
) {
746 LOG_LAYOUT ("\u267c");
748 measure_list
->Clear (true);
749 arrange_list
->Clear (true);
750 updated_list
->Clear (true);
751 size_list
->Clear (true);
754 DeepTreeWalker
measure_walker (element
);
755 while (FrameworkElement
*child
= (FrameworkElement
*)measure_walker
.Step ()) {
756 FrameworkElement
*parent
= (FrameworkElement
*)child
->GetVisualParent ();
758 if (parent
&& parent
->IsLoaded () && !child
->IsLoaded ()) {
759 LOG_LAYOUT ("FrameworkElement::UpdateLayout: element (%p) not yet loaded\n", child
);
761 List
*load_list
= child
->WalkTreeForLoaded (false);
762 child
->EmitSubtreeLoad (load_list
);
766 if ((child
->flags
& UIElement::RENDER_VISIBLE
) == 0) {
767 measure_walker
.SkipBranch ();
771 if (child
->dirty_flags
& DirtyMeasure
) {
772 UIElement
*parent
= child
->GetVisualParent ();
773 if ((parent
&& !parent
->Is (Type::CANVAS
)) || child
->IsContainer ()) {
774 measure_list
->Append (new UIElementNode (child
));
775 //g_warning ("adding %p, %s", child, child->GetTypeName ());
776 } else if (!measure_list
->IsEmpty ()) {
777 measure_walker
.SkipBranch ();
781 if (!measure_list
->IsEmpty ())
784 if (child
->dirty_flags
& DirtyArrange
)
785 arrange_list
->Append (new UIElementNode (child
));
787 if (!arrange_list
->IsEmpty ())
790 if (child
->ReadLocalValue (LayoutInformation::LastRenderSizeProperty
))
791 size_list
->Append (new UIElementNode (child
));
793 if (!size_list
->IsEmpty ())
797 updated_list
->Append (new UIElementNode (child
));
800 if (!measure_list
->IsEmpty ()) {
802 surface
->needs_measure
= false;
803 while (UIElementNode
* node
= (UIElementNode
*)measure_list
->First ()) {
804 measure_list
->Unlink (node
);
806 node
->uielement
->DoMeasure ();
807 //if (node->uielement->GetVisuaParent ()->dirty_flags & dirty_measure)
808 // node->Prepend (new UIElementNode (parent));
813 } else if (!arrange_list
->IsEmpty ()) {
815 surface
->needs_arrange
= false;
816 while (UIElementNode
*node
= (UIElementNode
*)arrange_list
->First ()) {
817 arrange_list
->Unlink (node
);
819 if (surface
&& surface
->needs_measure
) {
824 node
->uielement
->DoArrange ();
825 //if (node->uielement->GetVisuaParent ()->dirty_flags & dirty_arrange)
826 // node->Prepend (new UIElementNode (parent));
831 } else if (!size_list
->IsEmpty ()) {
832 while (UIElementNode
*node
= (UIElementNode
*)size_list
->First ()) {
833 if (surface
&& (surface
->needs_measure
|| surface
->needs_arrange
)) {
834 surface
->needs_measure
= surface
->needs_arrange
= false;
838 size_list
->Unlink (node
);
839 FrameworkElement
*fe
= (FrameworkElement
*) node
->uielement
;
842 Size
*last
= LayoutInformation::GetLastRenderSize (fe
);
844 SizeChangedEventArgs
*args
= new SizeChangedEventArgs (*last
, fe
->GetRenderSize ());
845 fe
->ClearValue (LayoutInformation::LastRenderSizeProperty
, false);
846 fe
->Emit (FrameworkElement::SizeChangedEvent
, args
);
850 } else if (!updated_list
->IsEmpty ()) {
852 while (UIElementNode
*node
= (UIElementNode
*)updated_list
->First ()) {
853 updated_list
->Unlink (node
);
854 FrameworkElement
*fe
= (FrameworkElement
*)node
->uielement
;
856 fe
->Emit (LayoutUpdatedEvent
);
868 if (i
>= MAX_LAYOUT_PASSES
) {
869 LOG_LAYOUT ("\n************** UpdateLayout Bailing Out after %d Passes *******************\n", i
);
871 LOG_LAYOUT (" (%d)\n", i
);
876 FrameworkElement::RegisterManagedOverrides (MeasureOverrideCallback measure_cb
, ArrangeOverrideCallback arrange_cb
)
878 this->measure_cb
= measure_cb
;
879 this->arrange_cb
= arrange_cb
;
883 FrameworkElement::SetDefaultStyle (Style
*style
)
886 Application::GetCurrent()->ApplyStyle (this, style
);
887 default_style_applied
= true;
888 ((StylePropertyValueProvider
*)providers
[PropertyPrecedence_DefaultStyle
])->SealStyle (style
);