]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/elements/CanvasElement.hxx
Canvas: Respect clipping while event handling.
[simgear.git] / simgear / canvas / elements / CanvasElement.hxx
index 07e876911ae900019d8a94409d31daebc7fc6a73..dc5e1bf7592985d125b588bc26470c5d4e770ead 100644 (file)
 #include <simgear/canvas/CanvasEvent.hxx>
 #include <simgear/props/PropertyBasedElement.hxx>
 #include <simgear/misc/stdint.hxx> // for uint32_t
-#include <simgear/nasal/cppbind/Ghost.hxx>
 
 #include <osg/BoundingBox>
 #include <osg/MatrixTransform>
 
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
+#include <boost/type_traits/is_base_of.hpp>
 
 namespace osg
 {
@@ -75,6 +75,17 @@ namespace canvas
                             ///   their parents
       };
 
+      /**
+       * Coordinate reference frame (eg. "clip" property)
+       */
+      enum ReferenceFrame
+      {
+        GLOBAL, ///!< Global coordinates
+        PARENT, ///!< Coordinates relative to parent coordinate frame
+        LOCAL   ///!< Coordinates relative to local coordinates (parent
+                ///   coordinates with local transformations applied)
+      };
+
       /**
        *
        */
@@ -84,6 +95,7 @@ namespace canvas
       virtual void onDestroy();
 
       ElementWeakPtr getWeakPtr() const;
+      ElementPtr getParent();
 
       /**
        * Called every frame to update internal state
@@ -92,7 +104,7 @@ namespace canvas
        */
       virtual void update(double dt);
 
-      naRef addEventListener(const nasal::CallContext& ctx);
+      bool addEventListener(const std::string& type, const EventListener& cb);
       virtual void clearEventListener();
 
       virtual bool accept(EventVisitor& visitor);
@@ -101,18 +113,34 @@ namespace canvas
 
       virtual bool handleEvent(canvas::EventPtr event);
 
-      virtual bool hitBound( const osg::Vec2f& pos,
+      /**
+       *
+       * @param global_pos Position in global (canvas) coordinate frame
+       * @param parent_pos Position in parent coordinate frame
+       * @param local_pos  Position in local (element) coordinate frame
+       */
+      virtual bool hitBound( const osg::Vec2f& global_pos,
+                             const osg::Vec2f& parent_pos,
                              const osg::Vec2f& local_pos ) const;
 
       /**
-       * Get whether the element is visible or hidden (Can be changed with
-       * setting property "visible" accordingly).
+       * Set visibility of the element.
+       */
+      void setVisible(bool visible);
+
+      /**
+       * Get whether the element is visible or hidden.
        */
       bool isVisible() const;
 
       osg::MatrixTransform* getMatrixTransform();
       osg::MatrixTransform const* getMatrixTransform() const;
 
+      /**
+       * Transform position to local coordinages.
+       */
+      osg::Vec2f posToLocal(const osg::Vec2f& pos) const;
+
       virtual void childAdded( SGPropertyNode * parent,
                                SGPropertyNode * child );
       virtual void childRemoved( SGPropertyNode * parent,
@@ -130,6 +158,11 @@ namespace canvas
        */
       void setClip(const std::string& clip);
 
+      /**
+       * Clipping coordinates reference frame
+       */
+      void setClipFrame(ReferenceFrame rf);
+
       /**
        * Write the given bounding box to the property tree
        */
@@ -140,6 +173,11 @@ namespace canvas
        */
       virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const;
 
+      /**
+       * Get the transformation matrix (product of all transforms)
+       */
+      osg::Matrix getMatrix() const;
+
       /**
        * Create an canvas Element
        *
@@ -164,8 +202,10 @@ namespace canvas
 
       enum Attributes
       {
-        BLEND_FUNC = 0x0001,
-        LAST_ATTRIBUTE  = BLEND_FUNC << 1
+        TRANSFORM       = 1,
+        BLEND_FUNC      = TRANSFORM << 1,
+        SCISSOR_COORDS  = BLEND_FUNC << 1,
+        LAST_ATTRIBUTE  = SCISSOR_COORDS << 1
       };
 
       enum TransformType
@@ -177,19 +217,21 @@ namespace canvas
         TT_SCALE
       };
 
+      class RelativeScissor;
+
       CanvasWeakPtr _canvas;
       Element      *_parent;
 
-      uint32_t _attributes_dirty;
+      mutable uint32_t _attributes_dirty;
 
-      bool _transform_dirty;
       osg::observer_ptr<osg::MatrixTransform> _transform;
       std::vector<TransformType>              _transform_types;
 
       Style                             _style;
       std::vector<SGPropertyNode_ptr>   _bounding_box;
+      RelativeScissor                  *_scissor;
 
-      typedef std::vector<EventListenerPtr> Listener;
+      typedef std::vector<EventListener> Listener;
       typedef std::map<Event::Type, Listener> ListenerMap;
 
       ListenerMap _listener;
@@ -197,6 +239,8 @@ namespace canvas
       typedef std::map<std::string, StyleInfo> StyleSetters;
       static StyleSetters       _style_setters;
 
+      static void staticInit();
+
       Element( const CanvasWeakPtr& canvas,
                const SGPropertyNode_ptr& node,
                const Style& parent_style,
@@ -210,7 +254,7 @@ namespace canvas
        * @tparam Derived    (Derived) class type
        */
       template<class Derived>
-      bool isInit() const
+      static bool isInit()
       {
         static bool is_init = false;
         if( is_init )
@@ -239,6 +283,7 @@ namespace canvas
         typename T2,
         class Derived
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -282,6 +327,7 @@ namespace canvas
         typename T,
         class Derived
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -295,6 +341,7 @@ namespace canvas
         typename T,
         class Derived
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -315,6 +362,7 @@ namespace canvas
         typename T2,
         class Derived
       >
+      static
       StyleSetterFunc
       addStyle( const std::string& name,
                 const std::string& type,
@@ -333,6 +381,7 @@ namespace canvas
       template<
         class Derived
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -354,6 +403,7 @@ namespace canvas
         class Other,
         class OtherRef
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -377,6 +427,7 @@ namespace canvas
         class Other,
         class OtherRef
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -400,6 +451,7 @@ namespace canvas
         class Other,
         class OtherRef
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -421,6 +473,7 @@ namespace canvas
         class Other,
         class OtherRef
       >
+      static
       StyleSetter
       addStyle( const std::string& name,
                 const std::string& type,
@@ -439,6 +492,7 @@ namespace canvas
       }
 
       template<typename T, class Derived, class Other, class OtherRef>
+      static
       boost::function<void (Derived&, T)>
       bindOther( void (Other::*setter)(T), OtherRef Derived::*instance_ref )
       {
@@ -446,6 +500,7 @@ namespace canvas
       }
 
       template<typename T, class Derived, class Other, class OtherRef>
+      static
       boost::function<void (Derived&, T)>
       bindOther( const boost::function<void (Other&, T)>& setter,
                  OtherRef Derived::*instance_ref )
@@ -463,6 +518,7 @@ namespace canvas
       }
 
       template<typename T1, typename T2, class Derived>
+      static
       StyleSetterFuncUnchecked
       bindStyleSetter( const std::string& name,
                        const boost::function<void (Derived&, T2)>& setter )
@@ -540,6 +596,27 @@ namespace canvas
   };
 
 } // namespace canvas
+
+  template<>
+  struct enum_traits<canvas::Element::ReferenceFrame>
+  {
+    static const char* name()
+    {
+      return "canvas::Element::ReferenceFrame";
+    }
+
+    static canvas::Element::ReferenceFrame defVal()
+    {
+      return canvas::Element::GLOBAL;
+    }
+
+    static bool validate(int frame)
+    {
+      return frame >= canvas::Element::GLOBAL
+          && frame <= canvas::Element::LOCAL;
+    }
+  };
+
 } // namespace simgear
 
 #endif /* CANVAS_ELEMENT_HXX_ */