Author: toshok
Date: 2007-07-05 15:19:08 -0400 (Thu, 05 Jul 2007)
New Revision: 81425

Modified:
   trunk/moon/src/ChangeLog
   trunk/moon/src/canvas.cpp
   trunk/moon/src/canvas.h
   trunk/moon/src/control.cpp
   trunk/moon/src/control.h
   trunk/moon/src/frameworkelement.cpp
   trunk/moon/src/uielement.cpp
   trunk/moon/src/uielement.h
Log:
2007-07-05  Chris Toshok  <[EMAIL PROTECTED]>

        * uielement.h, uielement.cpp, canvas.h, canvas.cpp: refactor the
        mouse event code so that the Handle* calls return void, like the
        Enter/Leave calls do.  Also, all checks for "inside"-ness happen
        in the canvas/parent object.  Also factored out the loop over
        children to "FindMouseOver", with the checks happening in
        "CheckOver".

        This needs more testing to make sure that we're still emitting
        events in the right order/amount as silverlight.

        In uielement.cpp, also add support for showing the bounding
        rectangle.

        * control.h, control.cpp: track event refactoring.

        * frameworkelement.cpp (FrameworkElement::InsideObject): remove
        the bounding rect check.  that's handled in the parent object now.



Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog    2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/ChangeLog    2007-07-05 19:19:08 UTC (rev 81425)
@@ -1,3 +1,23 @@
+2007-07-05  Chris Toshok  <[EMAIL PROTECTED]>
+
+       * uielement.h, uielement.cpp, canvas.h, canvas.cpp: refactor the
+       mouse event code so that the Handle* calls return void, like the
+       Enter/Leave calls do.  Also, all checks for "inside"-ness happen
+       in the canvas/parent object.  Also factored out the loop over
+       children to "FindMouseOver", with the checks happening in
+       "CheckOver".
+
+       This needs more testing to make sure that we're still emitting
+       events in the right order/amount as silverlight.
+
+       In uielement.cpp, also add support for showing the bounding
+       rectangle.
+
+       * control.h, control.cpp: track event refactoring.
+
+       * frameworkelement.cpp (FrameworkElement::InsideObject): remove
+       the bounding rect check.  that's handled in the parent object now.
+
 2007-07-04  Chris Toshok  <[EMAIL PROTECTED]>
 
        * media.cpp, media.h: rework our caching for images.  we now

Modified: trunk/moon/src/canvas.cpp
===================================================================
--- trunk/moon/src/canvas.cpp   2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/canvas.cpp   2007-07-05 19:19:08 UTC (rev 81425)
@@ -21,7 +21,7 @@
 #include "runtime.h"
 #include "collection.h"
 
-Canvas::Canvas () : surface (NULL), current_item (NULL)
+Canvas::Canvas () : surface (NULL), mouse_over (NULL)
 {
 }
 
@@ -168,99 +168,126 @@
 }
 
 bool
-Canvas::HandleMotion (Surface *s, int state, double x, double y)
+Canvas::InsideObject (Surface *s, double x, double y)
 {
+       /* if we have explicitly set width/height, we check them */
+       if (FrameworkElement::InsideObject (s, x, y))
+               return true;
+
+       /* otherwise we try to figure out if we're inside one of our child 
elements */
+       UIElement *mouseover = FindMouseOver (s, x, y);
+
+       return mouseover != NULL;
+}
+
+bool
+Canvas::CheckOver (Surface *s, UIElement *item, double x, double y)
+{
+       // if the item isn't visible, it's really easy
+       if (item->GetValue (UIElement::VisibilityProperty)->AsInt32() != 
VisibilityVisible)
+               return false;
+               
+       // first a quick bounds check
+       if (!item->GetBounds().PointInside (x, y))
+               return false;
+
+       // then, if that passes, a more tailored shape check
+       if (!item->InsideObject (s, x, y))
+               return false;
+
+       return true;
+}
+
+UIElement *
+Canvas::FindMouseOver (Surface *s, double x, double y)
+{
        VisualCollection *children = GetChildren ();
-       bool handled = false;
        Collection::Node *cn;
 
-       // 
-       // Walk the list in reverse
+       // if we have a previous mouse_over, see if we're still in it
+       // first, to make things a little quicker in the case where we
+       // have a lot of children
        //
-       if (!(cn = (Collection::Node *) children->z_sorted_list->Last ()))
-               goto leave;
-       
-       for ( ; cn != NULL; cn = (Collection::Node *) cn->Prev ()) {
+       if (mouse_over) {
+               if (CheckOver (s, mouse_over, x, y))
+                       return mouse_over;
+       }
+
+       // Walk the list in reverse order, since it's sorted in ascending 
z-index order
+       //
+       for (cn = (Collection::Node *) children->z_sorted_list->Last (); cn != 
NULL; cn = (Collection::Node *) cn->Prev ()) {
                UIElement *item = (UIElement *) cn->obj;
 
-               if (item->GetValue (UIElement::VisibilityProperty)->AsInt32() 
!= VisibilityVisible)
+               // skip the mouse_over, since we already checked it above
+               if (item == mouse_over)
                        continue;
-               
-               // Bounds check:
-               if (!item->GetBounds().PointInside (x, y))
-                       continue;
-               
-               handled = item->HandleMotion (s, state, x, y);
-               if (handled){
-                       if (item != current_item){
-                               if (current_item != NULL)
-                                       current_item->Leave (s);
 
-                               current_item = item;
-                               current_item->Enter (s, state, x, y);
-                       }
-                       goto leave;
-               } 
+               if (CheckOver (s, item, x, y))
+                       return item;
        }
 
-       if (current_item != NULL){
-               current_item->Leave (s);
-               current_item = NULL;
+       return NULL;
+}
+
+void
+Canvas::HandleMotion (Surface *s, int state, double x, double y)
+{
+       UIElement *new_over = FindMouseOver (s, x, y);
+
+       if (new_over != mouse_over) {
+               if (mouse_over)
+                       mouse_over->Leave (s);
+
+               mouse_over = new_over;
+
+               if (mouse_over)
+                       mouse_over->Enter (s, state, x, y);
        }
 
- leave:
-       if (handled || InsideObject (s, x, y)){
-               s->cb_motion (this, state, x, y);
-               return true;
-       }
-       
-       return handled;
+       if (mouse_over)
+               mouse_over->HandleMotion (s, state, x, y);
+
+       if (mouse_over || InsideObject (s, x, y))
+               UIElement::HandleMotion (s, state, x, y);
 }
 
-bool
+void
 Canvas::HandleButton (Surface *s, callback_mouse_event cb, int state, double 
x, double y)
 {
-       VisualCollection *children = GetChildren ();
-       bool handled = false;
-       Collection::Node *cn;
+       // not sure if this is correct, but we don't bother updating
+       // the current mouse_over here (and along with that, emitting
+       // enter/leave events).
+       if (mouse_over) {
+               if (mouse_over->GetBounds().PointInside (x, y)
+                   && mouse_over->InsideObject (s, x, y)) {
 
-       // 
-       // Walk the list in reverse
-       //
-       if (!(cn = (Collection::Node *) children->z_sorted_list->Last ()))
-               goto leave;
-       
-       for ( ; cn != NULL; cn = (Collection::Node *) cn->Prev ()) {
-               UIElement *item = (UIElement *) cn->obj;
+                       mouse_over->HandleButton (s, cb, state, x, y);
+               }
+       }
 
-               if (item->GetValue (UIElement::VisibilityProperty)->AsInt32() 
!= VisibilityVisible)
-                       continue;
+       UIElement::HandleButton (s, cb, state, x, y);
+}
 
-               // Quick bound check:
-               if (!item->GetBounds().PointInside (x, y))
-                       continue;
-               
-               handled = item->HandleButton (s, cb, state, x, y);
-               if (handled)
-                       break;
-       }
- leave:
-       if (handled || InsideObject (s, x, y)){
-               cb (this, state, x, y);
-               return true;
-       }
-       
-       return handled;
+void
+Canvas::Enter (Surface *s, int state, double x, double y)
+{
+       mouse_over = FindMouseOver (s, x, y);
+
+       if (mouse_over)
+               mouse_over->Enter (s, state, x, y);
+         
+       UIElement::Enter (s, state, x, y);
 }
 
 void
 Canvas::Leave (Surface *s)
 {
-       if (current_item != NULL){
-              current_item->Leave (s);
-              current_item = NULL;
+       if (mouse_over) {
+              mouse_over->Leave (s);
+              mouse_over = NULL;
        }
-       s->cb_mouse_leave (this);
+
+       UIElement::Leave (s);
 }
 
 static int level = 0;

Modified: trunk/moon/src/canvas.h
===================================================================
--- trunk/moon/src/canvas.h     2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/canvas.h     2007-07-05 19:19:08 UTC (rev 81425)
@@ -35,7 +35,7 @@
        //
        // Contains the last element where the mouse entered
        //
-       UIElement *current_item;
+       UIElement *mouse_over;
        
        virtual Type::Kind GetObjectType () { return Type::CANVAS; }
 
@@ -45,8 +45,16 @@
        virtual void ComputeBounds ();
        virtual void UpdateTransform ();
        virtual void GetTransformFor (UIElement *item, cairo_matrix_t *result);
-       virtual bool HandleMotion (Surface *s, int state, double x, double y);
-       virtual bool HandleButton (Surface *s, callback_mouse_event cb, int 
state, double x, double y);
+
+       bool CheckOver (Surface *s, UIElement *item, double x, double y);
+
+       virtual UIElement* FindMouseOver (Surface *s, double x, double y);
+
+       virtual bool InsideObject (Surface *s, double x, double y);
+
+       virtual void HandleMotion (Surface *s, int state, double x, double y);
+       virtual void HandleButton (Surface *s, callback_mouse_event cb, int 
state, double x, double y);
+       virtual void Enter (Surface *s, int state, double x, double y);
        virtual void Leave (Surface *s);
        
        virtual bool OnChildPropertyChanged (DependencyProperty *prop, 
DependencyObject *child);

Modified: trunk/moon/src/control.cpp
===================================================================
--- trunk/moon/src/control.cpp  2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/control.cpp  2007-07-05 19:19:08 UTC (rev 81425)
@@ -80,35 +80,27 @@
                return false;
 }
 
-bool
+void
 Control::HandleMotion (Surface *s, int state, double x, double y)
 {
-       if (real_object){
-               bool handled =real_object->HandleMotion (s, state, x, y);
-               if (handled)
-                       s->cb_motion (this, state, x, y);
-               return handled;
-       }
-       return false;
+       if (real_object)
+               real_object->HandleMotion (s, state, x, y);
+       FrameworkElement::HandleMotion (s, state, x, y);
 }
 
-bool
+void
 Control::HandleButton (Surface *s, callback_mouse_event cb, int state, double 
x, double y)
 {
-       if (real_object){
-               bool handled = real_object->HandleButton (s, cb, state, x, y);
-               if (handled)
-                       cb (this, state, x, y);
-               return handled;
-       }
-       return false;
+       if (real_object)
+               real_object->HandleButton (s, cb, state, x, y);
+       FrameworkElement::HandleButton (s, cb, state, x, y);
 }
 
 void 
 Control::Enter (Surface *s, int state, double x, double y)
 {
        if (real_object){
-               s->cb_enter (this, state, x, y);
+               FrameworkElement::Enter (s, state, x, y);
                real_object->Enter (s, state, x, y);
        }
 }
@@ -118,7 +110,7 @@
 {
        if (real_object){
                real_object->Leave (s);
-               s->cb_mouse_leave (this);
+               FrameworkElement::Leave (s);
        }
 }
 

Modified: trunk/moon/src/control.h
===================================================================
--- trunk/moon/src/control.h    2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/control.h    2007-07-05 19:19:08 UTC (rev 81425)
@@ -32,8 +32,8 @@
        virtual void GetTransformFor (UIElement *item, cairo_matrix_t *result);
        virtual Point GetTransformOrigin ();
        virtual bool InsideObject (Surface *s, double x, double y);
-       virtual bool HandleMotion (Surface *s, int state, double x, double y);
-       virtual bool HandleButton (Surface *s, callback_mouse_event cb, int 
state, double x, double y);
+       virtual void HandleMotion (Surface *s, int state, double x, double y);
+       virtual void HandleButton (Surface *s, callback_mouse_event cb, int 
state, double x, double y);
        virtual void Enter (Surface *s, int state, double x, double y);
        virtual void Leave (Surface *s);
 

Modified: trunk/moon/src/frameworkelement.cpp
===================================================================
--- trunk/moon/src/frameworkelement.cpp 2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/frameworkelement.cpp 2007-07-05 19:19:08 UTC (rev 81425)
@@ -37,10 +37,6 @@
 bool
 FrameworkElement::InsideObject (Surface *s, double x, double y)
 {
-       // Quick bounding box check.
-       if (!bounds.PointInside (x, y))
-               return FALSE;
-
        double nx = x, ny = y;
 
        uielement_transform_point (this, &nx, &ny);

Modified: trunk/moon/src/uielement.cpp
===================================================================
--- trunk/moon/src/uielement.cpp        2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/uielement.cpp        2007-07-05 19:19:08 UTC (rev 81425)
@@ -19,6 +19,8 @@
 #include "transform.h"
 #include "runtime.h"
 
+#define SHOW_BOUNDING_BOXES 0
+
 void
 UIElement::UpdateBounds (bool force_redraw_of_new_bounds)
 {
@@ -260,24 +262,16 @@
        return false;
 }
 
-bool
+void
 UIElement::HandleMotion (Surface *s, int state, double x, double y)
 {
-       if (InsideObject (s, x, y)){
-               s->cb_motion (this, state, x, y);
-               return true;
-       } 
-       return false;
+       s->cb_motion (this, state, x, y);
 }
 
-bool
+void
 UIElement::HandleButton (Surface *s, callback_mouse_event cb, int state, 
double x, double y)
 {
-       if (InsideObject (s, x, y)){
-               cb (this, state, x, y);
-               return true;
-       }
-       return false;
+       cb (this, state, x, y);
 }
 
 void
@@ -305,6 +299,16 @@
        STARTTIMER (UIElement_render, Type::Find (GetObjectType())->name);
        Render (cr, x, y, width, height);
        ENDTIMER (UIElement_render, Type::Find (GetObjectType())->name);
+
+#if SHOW_BOUNDING_BOXES
+       cairo_restore (cr);
+       cairo_save (cr);
+       cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 1.0);
+       cairo_set_line_width (cr, 2);
+       cairo_rectangle (cr, bounds.x + 1, bounds.y + 1, bounds.w - 2, bounds.h 
- 2);
+       cairo_stroke (cr);
+       cairo_new_path (cr);
+#endif
 }
 
 void

Modified: trunk/moon/src/uielement.h
===================================================================
--- trunk/moon/src/uielement.h  2007-07-05 19:04:26 UTC (rev 81424)
+++ trunk/moon/src/uielement.h  2007-07-05 19:19:08 UTC (rev 81425)
@@ -134,10 +134,9 @@
        //
        // HandleMotion:
        //   handles an mouse motion event, and dispatches it to anyone that
-       //   might want it.   Returns true if the event was within this 
UIElement
-       //   boundaries.
+       //   might want it.
        //
-       virtual bool HandleMotion (Surface *s, int state, double x, double y);
+       virtual void HandleMotion (Surface *s, int state, double x, double y);
 
        //
        // HandleButton:
@@ -145,9 +144,7 @@
        //   it to all the objects that might be interested in it (nested
        //   objects).
        //
-       //   Returns true if the button click was handled. 
-       //
-       virtual bool HandleButton (Surface *s, callback_mouse_event cb, int 
state, double x, double y);
+       virtual void HandleButton (Surface *s, callback_mouse_event cb, int 
state, double x, double y);
        
        //
        // Enter:

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to