in class/Microsoft.SilverlightControls/:
[moon.git] / src / uielement.h
blob5793be511400cdc6c093d969a89bb00c411ad867
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * uielement.h
5 * Contact:
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007-2009 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
14 #ifndef __MOON_UIELEMENT_H__
15 #define __MOON_UIELEMENT_H__
17 #include <glib.h>
19 #include "dependencyobject.h"
20 #include "resources.h"
21 #include "point.h"
22 #include "rect.h"
23 #include "region.h"
24 #include "list.h"
25 #include "size.h"
26 #include "layoutinformation.h"
28 #define QUANTUM_ALPHA 1
30 #if QUANTUM_ALPHA
31 #define IS_TRANSLUCENT(x) (x * 255 < 254.5)
32 #define IS_INVISIBLE(x) (x * 255 < .5)
33 #else
34 #define IS_TRANSLUCENT(x) (x < 1.0)
35 #define IS_INVISIBLE(x) (x <= 0.0)
36 #endif
38 class Surface;
40 /* @Namespace=System.Windows */
41 class UIElement : public DependencyObject {
42 public:
43 UIElement ();
44 virtual void Dispose ();
46 int dirty_flags;
47 List::Node *up_dirty_node;
48 List::Node *down_dirty_node;
50 bool force_invalidate_of_new_bounds;
51 bool emitting_loaded;
53 Region *dirty_region;
55 int DumpHierarchy (UIElement *obj);
57 enum UIElementFlags {
58 IS_LOADED = 0x01,
60 // these two flags correspond to the 2 states of VisibilityProperty
61 RENDER_VISIBLE = 0x02,
63 // the HitTestVisible property
64 HIT_TEST_VISIBLE = 0x04,
66 TOTAL_RENDER_VISIBLE = 0x08,
67 TOTAL_HIT_TEST_VISIBLE = 0x10,
69 SHAPE_EMPTY = 0x20, // there's is nothing to draw, the cached path may be NULL
70 SHAPE_NORMAL = 0x40, // normal drawing
71 SHAPE_DEGENERATE = 0x80, // degenerate drawing, use the Stroke brush for filling
72 SHAPE_RADII = 0x100,
73 SHAPE_MASK = (SHAPE_EMPTY | SHAPE_NORMAL | SHAPE_DEGENERATE | SHAPE_RADII),
75 // this means the element will be emitting OnLoaded
76 // shortly, and any child added to the element while
77 // it is in this state should post Loaded as well.
78 PENDING_LOADED = 0x200
81 virtual TimeManager *GetTimeManager ();
83 virtual bool PermitsMultipleParents () { return false; }
85 virtual void SetVisualParent (UIElement *visual_parent);
86 /* @GenerateCBinding,GeneratePInvoke */
87 UIElement *GetVisualParent () { return visual_parent; }
89 int GetVisualLevel () { return visual_level; }
90 void SetVisualLevel (int level) { visual_level = level; }
92 /* @GenerateCBinding,GeneratePInvoke,ManagedAccess=Internal */
93 virtual void SetSubtreeObject (DependencyObject *value);
95 /* @GenerateCBinding,GeneratePInvoke,ManagedAccess=Internal */
96 virtual DependencyObject *GetSubtreeObject () { return subtree_object; }
98 /* @GenerateCBinding,GeneratePInvoke */
99 virtual void ElementAdded (UIElement *obj);
100 /* @GenerateCBinding,GeneratePInvoke */
101 virtual void ElementRemoved (UIElement *obj);
103 virtual bool EnableAntiAlias() { return true; }
105 virtual void SetSurface (Surface *s);
107 // UpdateTotalRenderVisibility:
108 // Updates the opacity and render visibility on this item based on
109 // its parent's opacity and visibility as well as the value of its
110 // OpacityProperty and RenderVisibilityProperty.
112 void UpdateTotalRenderVisibility ();
113 void ComputeTotalRenderVisibility ();
114 bool GetActualTotalRenderVisibility ();
117 // GetRenderVisible:
118 // Returns true if the Visibility property of this item is "Visible", and false otherwise
120 bool GetRenderVisible () { return (flags & UIElement::TOTAL_RENDER_VISIBLE) != 0; }
123 // UpdateTotalHitTestVisibility:
124 // Updates the hit testability of the item based on the you know..
125 // The hit test flag.
126 void UpdateTotalHitTestVisibility ();
127 void ComputeTotalHitTestVisibility ();
128 bool GetActualTotalHitTestVisibility ();
131 // GetHitTestVisible:
132 // Returns true if the IsHitTestVisible property of this item true, and false otherwise
134 bool GetHitTestVisible () { return (flags & UIElement::TOTAL_HIT_TEST_VISIBLE) != 0; }
137 // UpdateTransform:
138 // Updates the absolute_xform for this item
140 void UpdateTransform ();
141 void ComputeLocalTransform ();
142 void ComputeTransform ();
143 virtual void TransformBounds (cairo_matrix_t *old, cairo_matrix_t *current);
146 // IsLoaded:
147 // Returns true if the element has been attached to a
148 // surface and is part of the visual hierarchy.
150 bool IsLoaded () { return (flags & UIElement::IS_LOADED) != 0; }
151 void ClearLoaded ();
154 // Render:
155 // Renders the given @item on the @surface. the area that is
156 // exposed is delimited by x, y, width, height
158 virtual void Render (cairo_t *cr, Region *region, bool path_only = false);
161 // Paint:
162 // Do an optimized render pass on the this element and it's
163 // subtree.
165 void Paint (cairo_t *cr, Region *region, cairo_matrix_t *matrix);
167 // a non virtual method for use when we want to wrap render
168 // with debugging and/or timing info
169 void DoRender (cairo_t *cr, Region *region);
170 bool UseBackToFront ();
173 // GetSizeForBrush:
174 // Gets the size of the area to be painted by a Brush (needed for image/video scaling)
175 virtual void GetSizeForBrush (cairo_t *cr, double *width, double *height);
178 // GetOriginPoint:
179 // Gets real origin, required e.g. for lineargradientbrushes on Path
180 virtual Point GetOriginPoint ()
182 return Point (0.0, 0.0);
186 // ShiftPosition:
188 // This method should actually set the x/y of the bounds
189 // rectangle to the new position. It is virtual to allow
190 // subclasses with specialized bounds (Panel, InkPresenter)
191 // the opportunity to set those bounds' positions as well.
193 virtual void ShiftPosition (Point p);
196 // UpdateBounds:
197 // Recomputes the bounds of this element, and if they're
198 // different chains up to its parent telling it to update
199 // its bounds.
201 void UpdateBounds (bool force_redraw_of_new_bounds = false);
203 // ComputeBounds:
204 // Updates the bounding box for the given item, this uses the parent
205 // chain to compute the composite affine.
207 // Output:
208 // item->bounds is updated
210 virtual void ComputeBounds ();
213 // GetBounds:
214 // returns the current bounding box for the given item in surface
215 // coordinates.
217 Rect GetBounds () { return bounds; }
220 // GetSubtreeBounds:
221 // returns the bounding box including all sub-uielements.
222 // implemented by containers in surface coordinates.
224 virtual Rect GetSubtreeBounds () { return bounds; }
227 // GetRenderBounds:
228 // returns the bounding box to be rendered, which
229 // unfortunately isn't necessarily the same as either our
230 // bounds or subtree bounds (in the case of inkpresenter)
231 virtual Rect GetRenderBounds () { return bounds; }
234 // GetCoverageBounds:
235 // returns the bounding box in global coordinates that opaquely covered by this object
237 virtual Rect GetCoverageBounds () { return Rect (); }
241 // IsLayoutContainer:
242 // returns true if the container has children that require a measure
243 // pass.
244 virtual bool IsLayoutContainer () { return GetSubtreeObject () != NULL; }
245 virtual bool IsContainer () { return IsLayoutContainer (); }
247 // HitTest
249 // Accumulate a list of all elements that will contain the
250 // point (or intersect the rectangle). The first node in the
251 // list is the most deeply nested node, the last node is the
252 // root.
253 virtual void HitTest (cairo_t *cr, Point p, List *uielement_list);
254 virtual void HitTest (cairo_t *cr, Rect r, List *uielement_list);
256 /* @GenerateCBinding,GeneratePInvoke */
257 void FindElementsInHostCoordinates_p (Point p, HitTestCollection *uielement_list);
258 /* @GenerateCBinding,GeneratePInvoke */
259 void FindElementsInHostCoordinates_r (Rect p, HitTestCollection *uielement_list);
261 virtual bool CanFindElement () { return false; }
262 virtual void FindElementsInHostCoordinates (cairo_t *cr, Point P, List *uielement_list);
263 virtual void FindElementsInHostCoordinates (cairo_t *cr, Rect r, List *uielement_list);
266 // Recomputes the bounding box, requests redraws,
267 // the parameter determines if we should also update the transformation
269 void FullInvalidate (bool render_xform);
272 // InsideObject:
273 // Returns whether the position x, y is inside the object
275 virtual bool InsideObject (cairo_t *cr, double x, double y);
278 // Checks if the point is inside the Clip region.
279 // Returns true if no Clip region is defined
280 // (which is actually an infinitely big Clip region).
282 bool InsideClip (cairo_t *cr, double x, double y);
285 // Invalidates a subrectangle of this element
287 void Invalidate (Rect r);
290 // Invalidates a subregion of this element
291 void Invalidate (Region *region);
294 // Invalidates the entire bounding rectangle of this element
296 /* @GenerateCBinding */
297 void Invalidate ();
300 // Invalidates the paint region of the element and its subtree
302 void InvalidateSubtreePaint ();
303 void InvalidateMask ();
304 void InvalidateClip ();
305 void InvalidateVisibility ();
308 // GetTransformOrigin:
309 // Returns the transformation origin based on of the item and the
310 // xform_origin
311 virtual Point GetTransformOrigin () {
312 return Point (0, 0);
316 // EmitKeyDown:
318 bool EmitKeyDown (GdkEventKey *key);
321 // EmitKeyUp:
323 bool EmitKeyUp (GdkEventKey *key);
326 // EmitGotFocus:
327 // Invoked when the mouse focuses the given object
329 bool EmitGotFocus ();
332 // EmitLostFocus:
333 // Invoked when the given object loses mouse focus
335 bool EmitLostFocus ();
338 // EmitLostMouseCapture:
339 // Invoked when the given object loses mouse capture
341 bool EmitLostMouseCapture ();
344 // CaptureMouse:
346 // Attempts to capture the mouse. If successful, all mouse
347 // events will be transmitted directly to this element.
348 // Leave/Enter events will no longer be sent.
350 /* @GenerateCBinding,GeneratePInvoke,GenerateJSBinding */
351 bool CaptureMouse ();
352 virtual bool CanCaptureMouse () { return true; }
354 /* @GenerateCBinding,GeneratePInvoke */
355 virtual bool Focus (bool recurse = true);
358 // ReleaseMouseCapture:
360 // Attempts to release the mouse. If successful, any
361 // applicable Leave/Enter events for the current mouse
362 // position will be sent.
364 /* @GenerateCBinding,GeneratePInvoke,GenerateJSBinding */
365 void ReleaseMouseCapture ();
367 virtual int RemoveHandler (int event_id, EventHandler handler, gpointer data);
368 virtual void RemoveHandler (int event_id, int token);
370 void WalkTreeForLoadedHandlers (bool *delay, bool only_unemitted, bool force_walk_up);
372 virtual void OnLoaded ();
374 virtual void OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error);
375 virtual void OnSubPropertyChanged (DependencyProperty *prop, DependencyObject *obj, PropertyChangedEventArgs *subobj_args);
376 virtual void OnCollectionChanged (Collection *col, CollectionChangedEventArgs *args);
379 // CacheInvalidateHint:
380 // Give a hint to this UIElement that it should free any possible
381 // cached (mem-intensive) data it has. This ie. can happen when the
382 // element is removed from a collection, becomes invisible, etc.
384 virtual void CacheInvalidateHint ();
387 // 2.0 methods
390 // Layout foo
392 void DoMeasure ();
393 void DoArrange ();
395 /* @GenerateCBinding,GeneratePInvoke */
396 virtual void Measure (Size availableSize) = 0;
397 /* @GenerateCBinding,GeneratePInvoke */
398 virtual void Arrange (Rect finalRect) = 0;
399 /* @GenerateCBinding,GeneratePInvoke */
400 void InvalidateMeasure ();
401 /* @GenerateCBinding,GeneratePInvoke */
402 void InvalidateArrange ();
403 /* @GenerateCBinding,GeneratePInvoke,GenerateJSBinding */
404 virtual void UpdateLayout () = 0;
406 /* @GenerateCBinding,GeneratePInvoke */
407 Size GetDesiredSize () { return desired_size; }
409 /* @GenerateCBinding,GeneratePInvoke */
410 Size GetRenderSize () { return render_size; }
412 /* @GenerateCBinding,GeneratePInvoke,GenerateJSBinding=TransformToVisual,Version=2.0 */
413 GeneralTransform *GetTransformToUIElementWithError (UIElement *to_element, MoonError *error);
416 // TransformPoint:
418 // Maps the point to the coordinate space of this item
420 void TransformPoint (double *x, double *y);
422 /* @PropertyType=Geometry,GenerateAccessors */
423 const static int ClipProperty;
424 /* @PropertyType=Effect,GenerateAccessors */
425 const static int EffectProperty;
426 /* @PropertyType=bool,DefaultValue=true,GenerateAccessors */
427 const static int IsHitTestVisibleProperty;
428 /* @PropertyType=Brush,GenerateAccessors */
429 const static int OpacityMaskProperty;
430 /* @PropertyType=double,DefaultValue=1.0,GenerateAccessors */
431 const static int OpacityProperty;
432 /* @PropertyType=Point,DefaultValue=Point (0\,0),GenerateAccessors */
433 const static int RenderTransformOriginProperty;
434 /* @PropertyType=Transform,GenerateAccessors,GenerateManagedAccessors=false */
435 const static int RenderTransformProperty;
436 /* @PropertyType=Visibility,DefaultValue=VisibilityVisible,GenerateAccessors */
437 const static int VisibilityProperty;
438 /* @PropertyType=bool,DefaultValue=true,GenerateAccessors */
439 const static int UseLayoutRoundingProperty;
441 // in 2.0 these properties are actually in FrameworkElement
442 /* @PropertyType=MouseCursor,DefaultValue=MouseCursorDefault,ManagedDeclaringType=FrameworkElement,ManagedPropertyType=Cursor,ManagedFieldAccess=Internal,GenerateAccessors,Validator=CursorValidator */
443 const static int CursorProperty;
444 /* @PropertyType=ResourceDictionary,ManagedDeclaringType=FrameworkElement,AutoCreateValue,ManagedFieldAccess=Internal,ManagedSetterAccess=Internal,GenerateAccessors */
445 const static int ResourcesProperty;
446 /* @PropertyType=object,ManagedDeclaringType=FrameworkElement,ManagedPropertyType=object,IsCustom=true */
447 const static int TagProperty;
448 /* @PropertyType=TriggerCollection,ManagedDeclaringType=FrameworkElement,AutoCreateValue,ManagedFieldAccess=Internal,ManagedSetterAccess=Internal,GenerateAccessors */
449 const static int TriggersProperty;
452 // Property Accessors
455 void SetClip (Geometry *clip);
456 Geometry *GetClip ();
458 MouseCursor GetCursor ();
459 void SetCursor (MouseCursor value);
461 Effect* GetEffect ();
462 void SetEffect (Effect *value);
464 void SetIsHitTestVisible (bool visible);
465 bool GetIsHitTestVisible ();
467 void SetOpacityMask (Brush *mask);
468 Brush *GetOpacityMask ();
470 void SetOpacity (double opacity);
471 double GetOpacity ();
473 void SetRenderTransform (Transform *transform);
474 Transform *GetRenderTransform ();
476 void SetRenderTransformOrigin (Point *origin);
477 Point *GetRenderTransformOrigin ();
479 ResourceDictionary* GetResources();
480 void SetResources (ResourceDictionary *value);
482 TriggerCollection *GetTriggers ();
483 void SetTriggers (TriggerCollection* value);
485 Visibility GetVisibility ();
486 void SetVisibility (Visibility value);
488 bool GetUseLayoutRounding ();
489 void SetUseLayoutRounding (bool value);
491 // Events you can AddHandler to
493 /* @ManagedDeclaringType=FrameworkElement,DelegateType=RoutedEventHandler,GenerateManagedEventField=true */
494 const static int LoadedEvent;
495 /* @DelegateType=MouseEventHandler */
496 const static int MouseMoveEvent;
497 /* @DelegateType=MouseButtonEventHandler,GenerateManagedEventField=true */
498 const static int MouseLeftButtonDownEvent;
499 /* @DelegateType=MouseButtonEventHandler,GenerateManagedEventField=true */
500 const static int MouseLeftButtonUpEvent;
501 /* @DelegateType=KeyEventHandler,GenerateManagedEventField=true */
502 const static int KeyDownEvent;
503 /* @DelegateType=KeyEventHandler,GenerateManagedEventField=true */
504 const static int KeyUpEvent;
505 /* @DelegateType=MouseEventHandler */
506 const static int MouseEnterEvent;
507 /* @DelegateType=MouseEventHandler */
508 const static int MouseLeaveEvent;
509 /* @GenerateManagedEvent=false */
510 const static int InvalidatedEvent;
511 /* @DelegateType=RoutedEventHandler */
512 const static int GotFocusEvent;
513 /* @DelegateType=RoutedEventHandler */
514 const static int LostFocusEvent;
515 /* @DelegateType=MouseEventHandler */
516 const static int LostMouseCaptureEvent;
517 /* @DelegateType=MouseWheelEventHandler */
518 const static int MouseWheelEvent;
520 // these we turn off generation for and handle manually since
521 // they're desktop-only
523 /* @GenerateManagedEvent=false */
524 const static int MouseLeftButtonMultiClickEvent;
525 /* @GenerateManagedEvent=false */
526 const static int MouseRightButtonDownEvent;
527 /* @GenerateManagedEvent=false */
528 const static int MouseRightButtonUpEvent;
530 // Helper method which checks recursively checks this element and its visual
531 // parents to see if any are loaded.
532 static bool IsSubtreeLoaded (UIElement *element);
534 protected:
535 virtual ~UIElement ();
536 Rect IntersectBoundsWithClipPath (Rect bounds, bool transform);
537 void RenderClipPath (cairo_t *cr, bool path_only = false);
539 void SetDesiredSize (Size s) { desired_size = s; }
540 void SetRenderSize (Size s) { render_size = s; }
542 // The computed bounding box
543 Rect bounds;
544 Rect extents;
546 int flags;
548 // Absolute affine transform, precomputed with all of its data
549 cairo_matrix_t absolute_xform;
550 cairo_matrix_t layout_xform;
552 void FrontToBack (Region *surface_region, List *render_list);
553 virtual void PreRender (cairo_t *cr, Region *region, bool front_to_back);
554 virtual void PostRender (cairo_t *cr, Region *region, bool front_to_back);
556 static void CallPreRender (cairo_t *cr, UIElement *element, Region *region, bool front_to_back);
557 static void CallPostRender (cairo_t *cr, UIElement *element, Region *region, bool front_to_back);
559 private:
560 int visual_level;
561 UIElement *visual_parent;
562 DependencyObject *subtree_object;
563 double total_opacity;
564 Brush *opacityMask;
565 Size desired_size;
566 Size render_size;
568 // The local render transform including tranform origin
569 cairo_matrix_t local_xform;
572 #endif /* __MOON_UIELEMENT_H__ */