mirror of
https://github.com/penpot/penpot.git
synced 2026-05-06 00:28:43 +00:00
167 lines
5.6 KiB
Clojure
167 lines
5.6 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) UXBOX Labs SL
|
|
|
|
(ns app.main.data.workspace.path.selection
|
|
(:require
|
|
[app.common.geom.point :as gpt]
|
|
[app.common.geom.shapes :as gsh]
|
|
[app.main.data.workspace.common :as dwc]
|
|
[app.main.data.workspace.path.state :as st]
|
|
[app.main.streams :as ms]
|
|
[beicon.core :as rx]
|
|
[potok.core :as ptk]))
|
|
|
|
(defn path-pointer-enter [position]
|
|
(ptk/reify ::path-pointer-enter
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (st/get-path-id state)]
|
|
(update-in state [:workspace-local :edit-path id :hover-points] (fnil conj #{}) position)))))
|
|
|
|
(defn path-pointer-leave [position]
|
|
(ptk/reify ::path-pointer-leave
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (st/get-path-id state)]
|
|
(update-in state [:workspace-local :edit-path id :hover-points] disj position)))))
|
|
|
|
(defn path-handler-enter [index prefix]
|
|
(ptk/reify ::path-handler-enter
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (st/get-path-id state)]
|
|
(update-in state [:workspace-local :edit-path id :hover-handlers] (fnil conj #{}) [index prefix])))))
|
|
|
|
(defn path-handler-leave [index prefix]
|
|
(ptk/reify ::path-handler-leave
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (st/get-path-id state)]
|
|
(update-in state [:workspace-local :edit-path id :hover-handlers] disj [index prefix])))))
|
|
|
|
(defn select-node-area [shift?]
|
|
(ptk/reify ::select-node-area
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [selrect (get-in state [:workspace-local :selrect])
|
|
id (get-in state [:workspace-local :edition])
|
|
content (get-in state (st/get-path state :content))
|
|
selected-point? #(gsh/has-point-rect? selrect %)
|
|
selected-points (get-in state [:workspace-local :edit-path id :selected-points])
|
|
positions (into (if shift? selected-points #{})
|
|
(comp (filter #(not (= (:command %) :close-path)))
|
|
(map (comp gpt/point :params))
|
|
(filter selected-point?))
|
|
content)]
|
|
(cond-> state
|
|
(some? id)
|
|
(assoc-in [:workspace-local :edit-path id :selected-points] positions))))))
|
|
|
|
(defn select-node [position shift? kk]
|
|
(ptk/reify ::select-node
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (get-in state [:workspace-local :edition])
|
|
selected-points (or (get-in state [:workspace-local :edit-path id :selected-points]) #{})
|
|
selected-points (cond
|
|
(and shift? (contains? selected-points position))
|
|
(disj selected-points position)
|
|
|
|
shift?
|
|
(conj selected-points position)
|
|
|
|
:else
|
|
#{position})]
|
|
(cond-> state
|
|
(some? id)
|
|
(assoc-in [:workspace-local :edit-path id :selected-points] selected-points))))))
|
|
|
|
(defn deselect-node [position shift?]
|
|
(ptk/reify ::deselect-node
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (get-in state [:workspace-local :edition])]
|
|
(-> state
|
|
(update-in [:workspace-local :edit-path id :selected-points] (fnil disj #{}) position))))))
|
|
|
|
(defn add-to-selection-handler [index type]
|
|
(ptk/reify ::add-to-selection-handler
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
state)))
|
|
|
|
(defn add-to-selection-node [index]
|
|
(ptk/reify ::add-to-selection-node
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
state)))
|
|
|
|
(defn remove-from-selection-handler [index]
|
|
(ptk/reify ::remove-from-selection-handler
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
state)))
|
|
|
|
(defn remove-from-selection-node [index]
|
|
(ptk/reify ::remove-from-selection-handler
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
state)))
|
|
|
|
(defn deselect-all []
|
|
(ptk/reify ::deselect-all
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (st/get-path-id state)]
|
|
(-> state
|
|
(assoc-in [:workspace-local :edit-path id :selected-points] #{}))))))
|
|
|
|
(defn update-area-selection
|
|
[rect]
|
|
(ptk/reify ::update-area-selection
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(assoc-in state [:workspace-local :selrect] rect))))
|
|
|
|
(defn clear-area-selection
|
|
[]
|
|
(ptk/reify ::clear-area-selection
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(update state :workspace-local dissoc :selrect))))
|
|
|
|
(defn handle-selection
|
|
[shift?]
|
|
(letfn [(valid-rect? [{width :width height :height}]
|
|
(or (> width 10) (> height 10)))]
|
|
|
|
(ptk/reify ::handle-selection
|
|
ptk/WatchEvent
|
|
(watch [_ state stream]
|
|
(let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
|
|
stoper (->> stream (rx/filter stop?))
|
|
from-p @ms/mouse-position]
|
|
(rx/concat
|
|
(->> ms/mouse-position
|
|
(rx/take-until stoper)
|
|
(rx/map #(gsh/points->rect [from-p %]))
|
|
(rx/filter valid-rect?)
|
|
(rx/map update-area-selection))
|
|
|
|
(rx/of (select-node-area shift?)
|
|
(clear-area-selection))))))))
|
|
|
|
(defn update-selection
|
|
[point-change]
|
|
(ptk/reify ::update-selection
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [id (st/get-path-id state)
|
|
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
|
|
selected-points (into #{} (map point-change) selected-points)]
|
|
(-> state
|
|
(assoc-in [:workspace-local :edit-path id :selected-points] selected-points))))))
|