membrane icon indicating copy to clipboard operation
membrane copied to clipboard

Add support for composite events

Open phronmophobic opened this issue 3 years ago • 2 comments

Membrane should do a better job supporting composite events/interactions like mouse-down-and-up, drag-and-drop, double-click, context menus (eg. right click), copy/cut/paste, modals, etc.

I don't think any changes to membrane's event model or state management are required. Off the top of my head, the steps required are something like:

  • simplify and break apart membrane.component/top-level-ui
  • package support for different interactions like mouse-down-and-up, drag-and-drop, double-click, context menus (eg. right click), copy/cut/paste, modals, etc into reusable pieces
  • provide sane defaults

phronmophobic avatar Mar 16 '22 05:03 phronmophobic

Below is a sketch of a workaround that doesn't require any changes/updates to membrane

(defui wrap-depressed [{:keys [body
                               ^:membrane.component/contextual
                               depressed]}]
  (ui/wrap-on

   ;; It's unclear whether you want mouse move events to be ignored while
   ;; a button is depressed. If you do, just uncomment the :mouse-move wrapper
   ;; here.
   #_#_
   :mouse-move
   (fn [handler pos]
     (when (not depressed)
       (handler pos)))

   :mouse-up
   (fn [handler pos]
     (concat (handler pos)
             [[:set $depressed nil]]))
   ;; The fixed bounds is a workaround for not being able to catch top level
   ;; mouse events outside the size of the app.
   ;; eg. If the user releases the mouse-up event outside the relatively small size of
   ;;     test-app ui, then depressed won't get reset correctly.
   (ui/fixed-bounds [4000 4000]
                    body)))

(defui normal-button [{:keys [text
                              private
                              ^:membrane.component/contextual
                              depressed]}]
  (let [is-depressed (= depressed $private)]
    (ui/on
     :mouse-down
     (fn [_]
       [[:set $depressed $private]])
     :mouse-up
     (fn [_]
       (when is-depressed
         [[:do-something]]))
     (ui/button text nil is-depressed))))

(defui test-app [{:keys []}]
  (wrap-depressed
   {:body
    (ui/vertical-layout
     (basic/textarea {:text (:text extra)})
     (basic/button {:text "no depression"})
     (ui/on
      :do-something
      (fn []
        [[::e1]])
      (normal-button {:text "with depression"}))
     (ui/on
      :do-something
      (fn []
        [[::e2]])
      (normal-button {:text "with depression 2"}))

     (apply
      ui/horizontal-layout
      (for [text ["a" "b" "c"]]
        (ui/on
         :do-something
         (fn []
           [[::e3 text]])
         (normal-button {:text text})))))}))

(def app (membrane.component/make-app #'test-app {}) )

(comment
  (backend/run app)
  ,)

phronmophobic avatar Mar 16 '22 05:03 phronmophobic

slack archive

rgkirch avatar Mar 22 '22 01:03 rgkirch