1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5 * Copyright 2007 Novell, Inc. (http://www.novell.com)
7 * See the LICENSE file included with the distribution for details.
18 #include "collection.h"
23 SetObjectType (Type::PANEL
);
26 SetSubtreeObject (GetChildren());
33 #define DEBUG_BOUNDS 0
37 static void space (int n
)
39 for (int i
= 0; i
< n
; i
++)
42 static int levelb
= 0;
46 Panel::ComputeBounds ()
51 printf ("Panel: Enter ComputeBounds (%s)\n", GetName());
54 // Clear the previous values
55 extents
= bounds
= bounds_with_children
= Rect ();
57 VisualTreeWalker walker
= VisualTreeWalker (this);
58 while (UIElement
*item
= walker
.Step ()) {
60 // if the item isn't drawn, skip it
61 if (!item
->GetRenderVisible ())
64 Rect r
= item
->GetSubtreeBounds ();
65 r
= IntersectBoundsWithClipPath (r
, true);
69 printf ("Item (%s, %s) bounds %g %g %g %g\n", item
->GetName (), item
->GetTypeName (),
70 r
.x
, r
.y
, r
.width
, r
.height
);
72 bounds_with_children
= bounds_with_children
.Union (r
);
75 Brush
*bg
= GetBackground();
77 extents
= Rect (0,0,GetActualWidth (),GetActualHeight ());
78 bounds
= IntersectBoundsWithClipPath (extents
, false).Transform (&absolute_xform
);
79 bounds_with_children
= bounds_with_children
.Union (bounds
);
84 printf ("Panel: Leave ComputeBounds (%g %g %g %g)\n",
85 bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
);
87 printf ("Panel: Leave ComputeBounds (%g %g %g %g)\n",
88 bounds_with_children
.x
, bounds_with_children
.y
, bounds_with_children
.width
, bounds_with_children
.height
);
94 Panel::ShiftPosition (Point p
)
96 double dx
= p
.x
- bounds
.x
;
97 double dy
= p
.y
- bounds
.y
;
99 // need to do this after computing the delta
100 FrameworkElement::ShiftPosition (p
);
102 bounds_with_children
.x
+= dx
;
103 bounds_with_children
.y
+= dy
;
106 //#define DEBUG_INVALIDATE 1
109 Panel::Render (cairo_t
*cr
, Region
*region
, bool path_only
)
111 Brush
*background
= GetBackground ();
113 cairo_set_matrix (cr
, &absolute_xform
);
115 Rect area
= Rect (0.0, 0.0, GetActualWidth (), GetActualHeight ());
119 if (background
&& area
.width
> 0 && area
.height
> 0 && !path_only
) {
120 background
->SetupBrush (cr
, area
);
121 background
->Fill (cr
);
126 Panel::GetCoverageBounds ()
128 Brush
*background
= GetBackground ();
130 if (background
&& background
->IsOpaque ())
137 Panel::InsideObject (cairo_t
*cr
, double x
, double y
)
139 if (GetBackground ())
140 return FrameworkElement::InsideObject (cr
, x
, y
);
146 Panel::EmptyBackground ()
148 return GetBackground () == NULL
;
152 Panel::MeasureOverride (Size availableSize
)
154 Size result
= Size (0,0);
159 Panel::OnPropertyChanged (PropertyChangedEventArgs
*args
, MoonError
*error
)
161 if (args
->GetProperty ()->GetOwnerType() != Type::PANEL
) {
162 FrameworkElement::OnPropertyChanged (args
, error
);
166 if (args
->GetId () == Panel::BackgroundProperty
)
169 if (args
->GetId () == Panel::ChildrenProperty
) {
170 Collection
*collection
;
172 if (args
->GetOldValue()) {
173 collection
= args
->GetOldValue()->AsCollection ();
174 for (int i
= 0; i
< collection
->GetCount (); i
++)
175 ElementRemoved (collection
->GetValueAt (i
)->AsUIElement());
178 if (args
->GetNewValue()) {
179 collection
= args
->GetNewValue()->AsCollection ();
180 for (int i
= 0; i
< collection
->GetCount (); i
++)
181 ElementAdded (collection
->GetValueAt (i
)->AsUIElement ());
184 SetSubtreeObject (args
->GetNewValue() ? args
->GetNewValue()->AsCollection() : NULL
);
189 NotifyListenersOfPropertyChange (args
, error
);
193 Panel::OnSubPropertyChanged (DependencyProperty
*prop
, DependencyObject
*obj
, PropertyChangedEventArgs
*subobj_args
)
195 if (prop
&& prop
->GetId () == Panel::BackgroundProperty
) {
198 FrameworkElement::OnSubPropertyChanged (prop
, obj
, subobj_args
);
203 Panel::OnCollectionChanged (Collection
*col
, CollectionChangedEventArgs
*args
)
205 if (col
== GetChildren ()) {
208 switch (args
->GetChangedAction()) {
209 case CollectionChangedActionReplace
:
210 if (args
->GetOldItem()->Is(Type::FRAMEWORKELEMENT
))
211 args
->GetOldItem()->AsFrameworkElement()->SetLogicalParent (NULL
, &error
/* XXX unused */);
212 ElementRemoved (args
->GetOldItem()->AsUIElement ());
213 // now fall thru to Add
214 case CollectionChangedActionAdd
:
215 ElementAdded (args
->GetNewItem()->AsUIElement ());
216 if (args
->GetNewItem()->Is(Type::FRAMEWORKELEMENT
))
217 args
->GetNewItem()->AsFrameworkElement()->SetLogicalParent (this, &error
/* XXX unused */);
219 case CollectionChangedActionRemove
:
220 if (args
->GetOldItem()->Is(Type::FRAMEWORKELEMENT
))
221 args
->GetOldItem()->AsFrameworkElement()->SetLogicalParent (NULL
, &error
/* XXX unused */);
222 ElementRemoved (args
->GetOldItem()->AsUIElement ());
224 case CollectionChangedActionClearing
:
225 for (int i
= 0; i
< col
->GetCount (); i
++) {
226 UIElement
*ui
= col
->GetValueAt (i
)->AsUIElement ();
227 if (ui
->Is(Type::FRAMEWORKELEMENT
))
228 ((FrameworkElement
*)ui
)->SetLogicalParent (NULL
, &error
/* XXX unused */);
232 case CollectionChangedActionCleared
:
233 // nothing needed here.
237 FrameworkElement::OnCollectionChanged (col
, args
);
245 FrameworkElement::OnLoaded ();
248 // queue a resort based on ZIndex
249 GetSurface ()->AddDirtyElement (this, DirtyChildrenZIndices
);
254 Panel::ElementAdded (UIElement
*item
)
256 FrameworkElement::ElementAdded (item
);
259 // queue a resort based on ZIndex
260 GetSurface ()->AddDirtyElement (this, DirtyChildrenZIndices
);
265 Panel::ElementRemoved (UIElement
*item
)
267 FrameworkElement::ElementRemoved (item
);
270 // queue a resort based on ZIndex
271 GetSurface ()->AddDirtyElement (this, DirtyChildrenZIndices
);
277 Panel::OnCollectionItemChanged (Collection
*col
, DependencyObject
*obj
, PropertyChangedEventArgs
*args
)
279 if (col
== GetChildren()) {
280 // if a child changes its ZIndex property we need to resort our Children
281 if (args
->GetId () == Canvas::ZIndexProperty
) {
282 ((UIElement
*) obj
)->Invalidate ();
284 // queue a resort based on ZIndex
285 GetSurface ()->AddDirtyElement (this, DirtyChildrenZIndices
);
291 FrameworkElement::OnCollectionItemChanged (col
, obj
, args
);