Browse Source

add ability to add maus and keyboard events to all elements in a uiml view

Kolja Strohm 8 months ago
parent
commit
78ee5b56f5
4 changed files with 145 additions and 3 deletions
  1. 53 3
      UIMLView.cpp
  2. 46 0
      UIMLView.h
  3. 30 0
      Zeichnung.cpp
  4. 16 0
      Zeichnung.h

+ 53 - 3
UIMLView.cpp

@@ -5,6 +5,7 @@
 #include "Fenster.h"
 #include "Knopf.h"
 #include "Rahmen.h"
+#include "RCPointer.h"
 #include "Schrift.h"
 #include "Scroll.h"
 #include "Tabelle.h"
@@ -893,6 +894,20 @@ void UIMLView::doMausEreignis(MausEreignis& me, bool userRet)
     }
 }
 
+void Framework::UIMLView::setOnMemberMouseEvent(std::function<bool(
+        XML::Element& element, Zeichnung& member, MausEreignis me)>
+        onEventAction)
+{
+    onMemberMouseEvent = onEventAction;
+}
+
+void Framework::UIMLView::setOnMemberKeyboardEvent(std::function<bool(
+        XML::Element& element, Zeichnung& member, TastaturEreignis te)>
+        onEventAction)
+{
+    onMemberKeyboardEvent = onEventAction;
+}
+
 //! entfernt alle bekannten elemente, die im uiml verwendet werden können
 void UIMLView::removeAllKnownElements()
 {
@@ -1218,6 +1233,41 @@ Zeichnung* UIMLView::parseElement(
         }
         if (z)
         {
+            if (hatStyle(Style::GlobalMouseEvent))
+            {
+                z->addMausEreignis(
+                    [this, z](void* p, void* o, MausEreignis me) {
+                        return dom->selectChildren()
+                            .selectAllElements()
+                            .whereAttributeEquals("id", getZeichnungId(*z))
+                            .getFirstElement()
+                            .map<bool>([this, &me, z](
+                                           RCPointer<XML::Element> element) {
+                                return onMemberMouseEvent
+                                         ? onMemberMouseEvent(*element, *z, me)
+                                         : 0;
+                            })
+                            .orElse(0);
+                    });
+            }
+            if (hatStyle(Style::GlobalTastaturEvent))
+            {
+                z->addTastaturEreignis(
+                    [this, z](void* p, void* o, TastaturEreignis te) {
+                        return dom->selectChildren()
+                            .selectAllElements()
+                            .whereAttributeEquals("id", getZeichnungId(*z))
+                            .getFirstElement()
+                            .map<bool>([this, &te, z](
+                                           RCPointer<XML::Element> element) {
+                                return onMemberKeyboardEvent
+                                         ? onMemberKeyboardEvent(
+                                             *element, *z, te)
+                                         : 0;
+                            })
+                            .orElse(0);
+                    });
+            }
             members->set(
                 id, id.getLength(), dynamic_cast<Zeichnung*>(z->getThis()));
             idList.add(new Text(id));
@@ -1271,10 +1321,10 @@ void Framework::UIMLView::removeZeichnung(Zeichnung& z)
     if (index >= 0)
     {
         Text id = *idList.z(index);
-		idList.remove(index);
-		memberList.remove(index);
+        idList.remove(index);
+        memberList.remove(index);
         members->remove(id, id.getLength());
-	}
+    }
 }
 
 bool Framework::UIMLView::registerZeichnung(const char* id, Zeichnung* z)

+ 46 - 0
UIMLView.h

@@ -242,6 +242,26 @@ namespace Framework
     class UIMLView : public ZeichnungHintergrund,
                      public UIMLContainer
     {
+    public:
+        class Style : public ZeichnungHintergrund::Style
+        {
+        public:
+            /// <summary>
+            /// if this style is set, then the mause event action will be
+            /// overwritten for all member views. The onMemberMouseEvent
+            /// function will be executed instead. The style needs to be set
+            /// before the uiml is parsed
+            /// </summary>
+            static const int GlobalMouseEvent = 0x01000;
+            /// <summary>
+            /// if this style is set, then the keyvord event action will be
+            /// overwritten for all member views. The onMemberKeybordEvent
+            /// function will be executed instead. The style needs to be set
+            /// before the uiml is parsed
+            /// </summary>
+            static const int GlobalTastaturEvent = 0x01000;
+        };
+
     private:
         RCArray<UIMLElement> knownElements;
         UIInit init;
@@ -250,6 +270,12 @@ namespace Framework
         RCArray<Text> idList;
         XML::Element* dom;
         int nextId;
+        std::function<bool(
+            XML::Element& element, Zeichnung& member, MausEreignis me)>
+            onMemberMouseEvent;
+        std::function<bool(
+            XML::Element& element, Zeichnung& member, TastaturEreignis te)>
+            onMemberKeyboardEvent;
 
         //! Verarbeitet ein Maus Ereignis. Wird vom Framework automatisch
         //! aufgerufen. \param me Das Ereignis
@@ -272,6 +298,26 @@ namespace Framework
         //! gezeichnet werden soll
         DLLEXPORT UIMLView(Text uiml, UIInit& init);
         DLLEXPORT ~UIMLView();
+        /// <summary>
+        /// sets a function that is executed if a mouse event on a member view
+        /// occures and the style Style::GlobalMouseEvent is set.
+        /// The mouse event will be ignored by the view if false is returned.
+        /// </summary>
+        /// <param name="onEventAction">the function to execute if a mouse event
+        /// occures</param>
+        DLLEXPORT void setOnMemberMouseEvent(std::function<bool(
+                XML::Element& element, Zeichnung& member, MausEreignis me)>
+                onEventAction);
+        /// <summary>
+        /// sets a function that is executed if a mouse event on a member view
+        /// occures and the style Style::GlobalTastaturEvent is set.
+        /// The mouse event will be ignored by the view if false is returned.
+        /// </summary>
+        /// <param name="onEventAction">the function to execute if a mouse event
+        /// occures</param>
+        DLLEXPORT void setOnMemberKeyboardEvent(std::function<bool(
+                XML::Element& element, Zeichnung& member, TastaturEreignis te)>
+                onEventAction);
         //! entfernt alle bekannten elemente, die im uiml verwendet werden
         //! können
         DLLEXPORT void removeAllKnownElements();

+ 30 - 0
Zeichnung.cpp

@@ -133,12 +133,42 @@ void Zeichnung::setMausEreignis(MausAktion ak) // setzt das Maus Ereignis
     mak = ak;
 }
 
+void Framework::Zeichnung::addMausEreignis(MausAktion ak)
+{
+    if (!mak)
+    {
+        mak = ak;
+    }
+    else
+    {
+        MausAktion old = mak;
+        mak = [old, ak](void* p, void* o, MausEreignis me) {
+            return old(p, o, me) && ak(p, o, me);
+        };
+    }
+}
+
 void Zeichnung::setTastaturEreignis(
     TastaturAktion ak) // setzt das TastaturEreignis
 {
     tak = ak;
 }
 
+void Framework::Zeichnung::addTastaturEreignis(TastaturAktion ak)
+{
+    if (!tak)
+    {
+        tak = ak;
+    }
+    else
+    {
+        TastaturAktion old = tak;
+        tak = [old, ak](void* p, void* o, TastaturEreignis te) {
+            return old(p, o, te) && ak(p, o, te);
+        };
+    }
+}
+
 void Zeichnung::setNMausEreignisParameter(
     void* p) // setzt den Parameter vom Maus Ereignis
 {

+ 16 - 0
Zeichnung.h

@@ -128,6 +128,13 @@ namespace Framework
         //! in MausEreignis.h definiert ist und immer 1 zurückgibt \param ak Ein
         //! Zeiger auf die Rückruffunktion
         DLLEXPORT void setMausEreignis(MausAktion ak);
+        //! Fügt eine Rückruffunktion hinzu, die bei einem Maus Ereignis aufgerufen
+        //! werden soll. Wenn eine der Rückruffunktionen 0 zurückgiebt, oder keine
+        //! gesetzt wurde, wird ein Maus Ereignis von der Zeichnung nicht weiter
+        //! beachtet Es kann die Standartfunktion __ret1ME verwendet werden, die
+        //! in MausEreignis.h definiert ist und immer 1 zurückgibt \param ak Ein
+        //! Zeiger auf die Rückruffunktion
+        DLLEXPORT void addMausEreignis(MausAktion ak);
         //! Setzt die Rückruffunktion, die bei einem Tastatur Ereignis
         //! aufgerufen werdne soll. Wenn die Rückruffunktion 0 zurückgiebt, oder
         //! nicht gesetzt wurde, wird ein Tastatur Ereignis von der Zeichnung
@@ -137,6 +144,15 @@ namespace Framework
         //! _nurHexTE ebenfals aus TastaturEreignis.h \param ak Ein Zeiger auf
         //! die Rückruffunktion
         DLLEXPORT void setTastaturEreignis(TastaturAktion ak);
+        //! Fügt eine Rückruffunktion hinzu, die bei einem Tastatur Ereignis
+        //! aufgerufen werdne soll. Wenn eine der Rückruffunktionen 0 zurückgiebt, oder
+        //! keine gesetzt wurde, wird ein Tastatur Ereignis von der Zeichnung
+        //! nicht weiter beachtet Es kann die Standartfunktion __ret1TE
+        //! verwendet werden, die in TastaturEreignis.h definiert ist und immer
+        //! 1 zurückgibt Weitere Standartfunktionen sind _nurNummernTE und
+        //! _nurHexTE ebenfals aus TastaturEreignis.h \param ak Ein Zeiger auf
+        //! die Rückruffunktion
+        DLLEXPORT void addTastaturEreignis(TastaturAktion ak);
         //! setzt den Parameter, der bei einem Maus Ereignis an die
         //! Rückruffunktion übergeben wird, die aufgerufen wird, fals das
         //! Ereignis von der Zeichnung verarbeitet wurde \param p Der Parameter