2009-10-09 Chris Toshok <toshok@ximian.com>
[moon.git] / src / canvas.cpp
blobd5c54851ae548dba91c6121f1c88e3d3ef33f5a8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * canvas.cpp: canvas definitions.
5 * Contact:
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
14 #include <config.h>
16 #include <math.h>
18 #include "rect.h"
19 #include "canvas.h"
20 #include "runtime.h"
21 #include "namescope.h"
22 #include "collection.h"
24 Canvas::Canvas ()
26 SetObjectType (Type::CANVAS);
29 void
30 Canvas::ComputeBounds ()
32 Surface *surface = GetSurface ();
33 Panel::ComputeBounds ();
34 if (surface && surface->IsTopLevel (this)) {
35 // toplevel canvas don't subscribe to the same bounds computation as others
36 bounds = Rect (0, 0, surface->GetWindow()->GetWidth(), surface->GetWindow()->GetHeight());
37 bounds_with_children = Rect (0, 0, surface->GetWindow()->GetWidth(), surface->GetWindow()->GetHeight());
41 void
42 Canvas::ShiftPosition (Point p)
44 Surface *surface = GetSurface ();
45 if (surface && surface->IsTopLevel (this)) {
46 ComputeBounds ();
47 } else {
48 Panel::ShiftPosition (p);
52 void
53 Canvas::OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error)
55 if (args->GetProperty ()->GetOwnerType() != Type::CANVAS) {
56 Panel::OnPropertyChanged (args, error);
57 return;
60 if (args->GetId () == Canvas::TopProperty
61 || args->GetId () == Canvas::LeftProperty) {
62 if (GetVisualParent () == NULL) {
63 UpdateTransform ();
64 InvalidateArrange ();
67 NotifyListenersOfPropertyChange (args, error);
70 bool
71 Canvas::IsLayoutContainer ()
73 Types *types = Deployment::GetCurrent ()->GetTypes ();
75 DeepTreeWalker walker = DeepTreeWalker (this);
76 while (UIElement *child = walker.Step ()) {
77 if (!types->IsSubclassOf (child->GetObjectType (), Type::CANVAS) && child->IsLayoutContainer ())
78 return true;
81 return false;
84 Size
85 Canvas::MeasureOverride (Size availableSize)
87 Size childSize = Size (INFINITY, INFINITY);
89 VisualTreeWalker walker = VisualTreeWalker (this);
90 while (UIElement *child = walker.Step ()) {
91 if (child->GetVisibility () != VisibilityVisible)
92 continue;
94 if (child->IsContainer ())
95 child->Measure (childSize);
96 else {
97 if (child->dirty_flags & DirtyMeasure) {
98 child->dirty_flags &= ~DirtyMeasure;
99 child->InvalidateArrange ();
104 Size desired = Size (0,0);
106 desired = ApplySizeConstraints (desired);
108 return desired.Min (availableSize);
111 Size
112 Canvas::ArrangeOverride (Size finalSize)
114 Size arranged = ApplySizeConstraints (finalSize);
116 // XXX ugly hack to maintain compat
117 //if (!GetVisualParent() && !GetSurface ())
118 // return arranged;
120 VisualTreeWalker walker = VisualTreeWalker (this);
121 while (FrameworkElement *child = (FrameworkElement *)walker.Step ()) {
122 if (child->GetVisibility () != VisibilityVisible)
123 continue;
125 if (child->IsContainer ()) {
126 Size desired = child->GetDesiredSize ();
127 Rect child_final = Rect (GetLeft (child), GetTop (child), desired.width, desired.height);
128 child->Arrange (child_final);
129 } else {
130 //g_warning ("arranging %s %g,%g", child->GetTypeName (),child->GetActualWidth (), child->GetActualHeight ());
131 Rect child_final = Rect (GetLeft (child), GetTop (child),
132 child->GetActualWidth (),
133 child->GetActualHeight ());
134 child->Arrange (child_final);
138 return arranged;
141 void
142 Canvas::OnCollectionItemChanged (Collection *col, DependencyObject *obj, PropertyChangedEventArgs *args)
144 if (col == GetChildren()) {
145 // this used to contain ZIndex property checking, but
146 // it has been moved to Panel's implementation, since
147 // all panels allow ZIndex sorting of children.
148 if (args->GetId () == Canvas::TopProperty ||
149 args->GetId () == Canvas::LeftProperty) {
150 UIElement *ui = (UIElement *) obj;
152 ui->InvalidateSubtreePaint ();
153 ui->InvalidateArrange ();
154 Rect *last = LayoutInformation::GetLayoutSlot (ui);
155 if (last) {
156 Rect updated = Rect (GetLeft (ui),
157 GetTop (ui),
158 last->width, last->height);
160 if (args->GetId () == Canvas::TopProperty)
161 updated.y = args->GetNewValue()->AsDouble ();
162 else
163 updated.x = args->GetNewValue()->AsDouble ();
165 LayoutInformation::SetLayoutSlot (ui, &updated);
166 } else {
167 InvalidateArrange ();
169 UpdateBounds ();
170 return;
174 Panel::OnCollectionItemChanged (col, obj, args);