1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
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__
19 #include "dependencyobject.h"
20 #include "resources.h"
26 #include "layoutinformation.h"
28 #define QUANTUM_ALPHA 1
31 #define IS_TRANSLUCENT(x) (x * 255 < 254.5)
32 #define IS_INVISIBLE(x) (x * 255 < .5)
34 #define IS_TRANSLUCENT(x) (x < 1.0)
35 #define IS_INVISIBLE(x) (x <= 0.0)
40 /* @Namespace=System.Windows */
41 class UIElement
: public DependencyObject
{
44 virtual void Dispose ();
47 List::Node
*up_dirty_node
;
48 List::Node
*down_dirty_node
;
50 bool force_invalidate_of_new_bounds
;
55 int DumpHierarchy (UIElement
*obj
);
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
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 ();
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; }
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
);
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; }
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);
162 // Do an optimized render pass on the this element and it's
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 ();
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
);
179 // Gets real origin, required e.g. for lineargradientbrushes on Path
180 virtual Point
GetOriginPoint ()
182 return Point (0.0, 0.0);
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
);
197 // Recomputes the bounds of this element, and if they're
198 // different chains up to its parent telling it to update
201 void UpdateBounds (bool force_redraw_of_new_bounds
= false);
204 // Updates the bounding box for the given item, this uses the parent
205 // chain to compute the composite affine.
208 // item->bounds is updated
210 virtual void ComputeBounds ();
214 // returns the current bounding box for the given item in surface
217 Rect
GetBounds () { return bounds
; }
221 // returns the bounding box including all sub-uielements.
222 // implemented by containers in surface coordinates.
224 virtual Rect
GetSubtreeBounds () { return bounds
; }
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
244 virtual bool IsLayoutContainer () { return GetSubtreeObject () != NULL
; }
245 virtual bool IsContainer () { return IsLayoutContainer (); }
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
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
);
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 */
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
311 virtual Point
GetTransformOrigin () {
318 bool EmitKeyDown (GdkEventKey
*key
);
323 bool EmitKeyUp (GdkEventKey
*key
);
327 // Invoked when the mouse focuses the given object
329 bool EmitGotFocus ();
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 ();
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 List
* WalkTreeForLoaded (bool *delay
);
369 void PostSubtreeLoad (List
*load_list
);
370 static void EmitSubtreeLoad (List
*load_list
);
371 static void emit_delayed_loaded (EventObject
*data
);
373 virtual void OnLoaded ();
375 virtual void OnPropertyChanged (PropertyChangedEventArgs
*args
, MoonError
*error
);
376 virtual void OnSubPropertyChanged (DependencyProperty
*prop
, DependencyObject
*obj
, PropertyChangedEventArgs
*subobj_args
);
377 virtual void OnCollectionChanged (Collection
*col
, CollectionChangedEventArgs
*args
);
380 // CacheInvalidateHint:
381 // Give a hint to this UIElement that it should free any possible
382 // cached (mem-intensive) data it has. This ie. can happen when the
383 // element is removed from a collection, becomes invisible, etc.
385 virtual void CacheInvalidateHint ();
396 /* @GenerateCBinding,GeneratePInvoke */
397 virtual void Measure (Size availableSize
) = 0;
398 /* @GenerateCBinding,GeneratePInvoke */
399 virtual void Arrange (Rect finalRect
) = 0;
400 /* @GenerateCBinding,GeneratePInvoke */
401 void InvalidateMeasure ();
402 /* @GenerateCBinding,GeneratePInvoke */
403 void InvalidateArrange ();
404 /* @GenerateCBinding,GeneratePInvoke,GenerateJSBinding */
405 virtual void UpdateLayout () = 0;
407 /* @GenerateCBinding,GeneratePInvoke */
408 Size
GetDesiredSize () { return desired_size
; }
410 /* @GenerateCBinding,GeneratePInvoke */
411 Size
GetRenderSize () { return render_size
; }
413 /* @GenerateCBinding,GeneratePInvoke,GenerateJSBinding=TransformToVisual,Version=2.0 */
414 GeneralTransform
*GetTransformToUIElementWithError (UIElement
*to_element
, MoonError
*error
);
419 // Maps the point to the coordinate space of this item
421 void TransformPoint (double *x
, double *y
);
423 /* @PropertyType=Geometry,GenerateAccessors */
424 const static int ClipProperty
;
425 /* @PropertyType=bool,DefaultValue=true,GenerateAccessors */
426 const static int IsHitTestVisibleProperty
;
427 /* @PropertyType=Brush,GenerateAccessors */
428 const static int OpacityMaskProperty
;
429 /* @PropertyType=double,DefaultValue=1.0,GenerateAccessors */
430 const static int OpacityProperty
;
431 /* @PropertyType=Point,DefaultValue=Point (0\,0),GenerateAccessors */
432 const static int RenderTransformOriginProperty
;
433 /* @PropertyType=Transform,GenerateAccessors,GenerateManagedAccessors=false */
434 const static int RenderTransformProperty
;
435 /* @PropertyType=Visibility,DefaultValue=VisibilityVisible,GenerateAccessors */
436 const static int VisibilityProperty
;
437 /* @PropertyType=bool,DefaultValue=true,GenerateAccessors */
438 const static int UseLayoutRoundingProperty
;
440 // in 2.0 these properties are actually in FrameworkElement
441 /* @PropertyType=MouseCursor,DefaultValue=MouseCursorDefault,ManagedDeclaringType=FrameworkElement,ManagedPropertyType=Cursor,ManagedFieldAccess=Internal,GenerateAccessors,Validator=CursorValidator */
442 const static int CursorProperty
;
443 /* @PropertyType=ResourceDictionary,ManagedDeclaringType=FrameworkElement,AutoCreateValue,ManagedFieldAccess=Internal,ManagedSetterAccess=Internal,GenerateAccessors */
444 const static int ResourcesProperty
;
445 /* @PropertyType=object,ManagedDeclaringType=FrameworkElement,ManagedPropertyType=object,IsCustom=true */
446 const static int TagProperty
;
447 /* @PropertyType=TriggerCollection,ManagedDeclaringType=FrameworkElement,AutoCreateValue,ManagedFieldAccess=Internal,ManagedSetterAccess=Internal,GenerateAccessors */
448 const static int TriggersProperty
;
451 // Property Accessors
454 void SetClip (Geometry
*clip
);
455 Geometry
*GetClip ();
457 MouseCursor
GetCursor ();
458 void SetCursor (MouseCursor value
);
460 void SetIsHitTestVisible (bool visible
);
461 bool GetIsHitTestVisible ();
463 void SetOpacityMask (Brush
*mask
);
464 Brush
*GetOpacityMask ();
466 void SetOpacity (double opacity
);
467 double GetOpacity ();
469 void SetRenderTransform (Transform
*transform
);
470 Transform
*GetRenderTransform ();
472 void SetRenderTransformOrigin (Point
*origin
);
473 Point
*GetRenderTransformOrigin ();
475 ResourceDictionary
* GetResources();
476 void SetResources (ResourceDictionary
*value
);
478 TriggerCollection
*GetTriggers ();
479 void SetTriggers (TriggerCollection
* value
);
481 Visibility
GetVisibility ();
482 void SetVisibility (Visibility value
);
484 bool GetUseLayoutRounding ();
485 void SetUseLayoutRounding (bool value
);
487 // Events you can AddHandler to
489 /* @ManagedDeclaringType=FrameworkElement,DelegateType=RoutedEventHandler */
490 const static int LoadedEvent
;
491 /* @GenerateManagedEvent=false */
492 const static int UnloadedEvent
;
493 /* @DelegateType=MouseEventHandler */
494 const static int MouseMoveEvent
;
495 /* @DelegateType=MouseButtonEventHandler */
496 const static int MouseLeftButtonDownEvent
;
497 /* @DelegateType=MouseButtonEventHandler */
498 const static int MouseLeftButtonUpEvent
;
499 /* @DelegateType=KeyEventHandler */
500 const static int KeyDownEvent
;
501 /* @DelegateType=KeyEventHandler */
502 const static int KeyUpEvent
;
503 /* @DelegateType=MouseEventHandler */
504 const static int MouseEnterEvent
;
505 /* @DelegateType=MouseEventHandler */
506 const static int MouseLeaveEvent
;
507 /* @GenerateManagedEvent=false */
508 const static int InvalidatedEvent
;
509 /* @DelegateType=RoutedEventHandler */
510 const static int GotFocusEvent
;
511 /* @DelegateType=RoutedEventHandler */
512 const static int LostFocusEvent
;
513 /* @DelegateType=MouseEventHandler */
514 const static int LostMouseCaptureEvent
;
516 // these we turn off generation for and handle manually since
517 // they're desktop-only
519 /* @GenerateManagedEvent=false */
520 const static int MouseLeftButtonMultiClickEvent
;
521 /* @GenerateManagedEvent=false */
522 const static int MouseRightButtonDownEvent
;
523 /* @GenerateManagedEvent=false */
524 const static int MouseRightButtonUpEvent
;
525 /* @GenerateManagedEvent=false */
526 const static int MouseWheelEvent
;
528 // Helper method which checks recursively checks this element and its visual
529 // parents to see if any are loaded.
530 static bool IsSubtreeLoaded (UIElement
*element
);
533 virtual ~UIElement ();
534 Rect
IntersectBoundsWithClipPath (Rect bounds
, bool transform
);
535 void RenderClipPath (cairo_t
*cr
, bool path_only
= false);
537 void SetDesiredSize (Size s
) { desired_size
= s
; }
538 void SetRenderSize (Size s
) { render_size
= s
; }
540 // The computed bounding box
546 // Absolute affine transform, precomputed with all of its data
547 cairo_matrix_t absolute_xform
;
548 cairo_matrix_t layout_xform
;
550 void FrontToBack (Region
*surface_region
, List
*render_list
);
551 virtual void PreRender (cairo_t
*cr
, Region
*region
, bool front_to_back
);
552 virtual void PostRender (cairo_t
*cr
, Region
*region
, bool front_to_back
);
554 static void CallPreRender (cairo_t
*cr
, UIElement
*element
, Region
*region
, bool front_to_back
);
555 static void CallPostRender (cairo_t
*cr
, UIElement
*element
, Region
*region
, bool front_to_back
);
559 UIElement
*visual_parent
;
560 DependencyObject
*subtree_object
;
561 double total_opacity
;
566 // The local render transform including tranform origin
567 cairo_matrix_t local_xform
;
570 #endif /* __MOON_UIELEMENT_H__ */