]> 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 3487f868135ec07dae2a5d242919c8b114e9065c..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;
@@ -554,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_ */