0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-13 10:38:13 -05:00
penpot/frontend/uxbox/ui/workspace/base.cljs

157 lines
4.6 KiB
Text
Raw Normal View History

2015-12-17 12:51:36 +02:00
(ns uxbox.ui.workspace.base
2015-12-17 17:32:06 +02:00
(:require [beicon.core :as rx]
2015-12-17 12:51:36 +02:00
[cats.labs.lens :as l]
[uxbox.rstore :as rs]
[uxbox.state :as st]
2015-12-17 12:51:36 +02:00
[uxbox.data.projects :as dp]
2015-12-28 20:06:59 +02:00
[uxbox.data.workspace :as dw]
2015-12-18 11:18:00 +02:00
[uxbox.util.lens :as ul]
[uxbox.ui.util :as util]
[goog.events :as events])
(:import goog.events.EventType))
2015-12-17 12:51:36 +02:00
2015-12-17 16:43:58 +02:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2015-12-17 12:51:36 +02:00
;; Lenses
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def ^:static project-state
2015-12-17 16:43:58 +02:00
(as-> (ul/dep-in [:projects-by-id] [:workspace :project]) $
(l/focus-atom $ st/state)))
2015-12-17 12:51:36 +02:00
(def ^:static page-state
2015-12-17 16:43:58 +02:00
(as-> (ul/dep-in [:pages-by-id] [:workspace :page]) $
(l/focus-atom $ st/state)))
2015-12-17 12:51:36 +02:00
(def ^:static pages-state
2015-12-17 16:43:58 +02:00
(as-> (ul/getter #(let [pid (get-in % [:workspace :project])]
2015-12-17 12:51:36 +02:00
(dp/project-pages % pid))) $
(l/focus-atom $ st/state)))
2015-12-29 15:51:47 +02:00
2015-12-17 12:51:36 +02:00
(def ^:static workspace-state
(as-> (l/in [:workspace]) $
(l/focus-atom $ st/state)))
2015-12-28 20:39:46 +02:00
2015-12-17 12:51:36 +02:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Scroll Stream
2015-12-17 12:51:36 +02:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2016-01-06 19:48:37 +02:00
(defonce ^:private scroll-b (rx/bus))
2015-12-18 11:18:00 +02:00
2016-01-06 19:48:37 +02:00
(defonce scroll-s
(as-> scroll-b $
(rx/merge $ (rx/of {:top 0 :left 0}))
(rx/dedupe $)))
(defonce scroll-top-s
(->> scroll-s
2015-12-18 11:18:00 +02:00
(rx/map :top)
(rx/dedupe)))
2016-01-06 19:48:37 +02:00
(defonce scroll-left-s
(->> scroll-s
2015-12-18 11:18:00 +02:00
(rx/map :left)
(rx/dedupe)))
2015-12-17 12:51:36 +02:00
2016-01-06 19:48:37 +02:00
(defonce scroll-top (rx/to-atom scroll-top-s))
(defonce scroll-left (rx/to-atom scroll-left-s))
2015-12-17 12:51:36 +02:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Mouse Position Stream
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2015-12-18 11:18:00 +02:00
(defonce shapes-dragging? (atom false))
2016-01-01 22:27:21 +02:00
(defonce selrect-dragging? (atom false))
(defonce selrect-pos (atom nil))
2015-12-28 20:06:59 +02:00
(defonce mouse-b (rx/bus))
(defonce mouse-s
(->> mouse-b
(rx/filter #(= (:id %) (:id @page-state)))
(rx/map :coords)))
2015-12-28 20:06:59 +02:00
;; Deltas
(defn- coords-delta
[[old new]]
(let [[oldx oldy] old
[newx newy] new]
[(- newx oldx)
(- newy oldy)]))
(defonce mouse-delta-s
(->> mouse-s
(rx/sample 10)
(rx/buffer 2 1)
(rx/map coords-delta)))
(defonce $$drag-subscription$$
(as-> mouse-delta-s $
(rx/filter #(deref shapes-dragging?) $)
(rx/on-value $ (fn [delta]
(let [pageid (get-in @st/state [:workspace :page])
selected (get-in @st/state [:workspace :selected])
page (get-in @st/state [:pages-by-id pageid])]
(doseq [sid (filter selected (:shapes page))]
(rs/emit! (dw/move-shape sid delta))))))))
2015-12-28 20:06:59 +02:00
2016-01-01 22:27:21 +02:00
(defn selrect->rect
[data]
(let [start (:start data)
current (:current data )
start-x (min (first start) (first current))
start-y (min (second start) (second current))
current-x (max (first start) (first current))
current-y (max (second start) (second current))
width (- current-x start-x)
height (- current-y start-y)]
{:x start-x
:y start-y
:width (- current-x start-x)
:height (- current-y start-y)}))
(defonce $$selrect-subscription-0$$
(let [ss (as-> (rx/from-atom selrect-dragging?) $
(rx/dedupe $)
(rx/merge $ (rx/of false))
(rx/buffer 2 1 $)
(rx/share $))]
(as-> ss $
(rx/filter #(= (vec %) [false true]) $)
(rx/with-latest-from vector mouse-s $)
(rx/on-value $ (fn [[_ pos]]
(swap! selrect-pos assoc
:start pos
:current pos))))
(as-> ss $
(rx/filter #(= (vec %) [true false]) $)
(rx/on-value $ (fn []
(let [selrect (selrect->rect @selrect-pos)]
(rs/emit! (dw/select-shapes selrect))
(reset! selrect-pos nil)))))))
(defonce $$selrect-subscription-1$$
(as-> mouse-s $
(rx/filter #(deref selrect-dragging?) $)
(rx/on-value $ (fn [pos]
(swap! selrect-pos assoc :current pos)))))
2015-12-28 20:06:59 +02:00
;; Materialized views
(defonce mouse-position
(->> mouse-s
(rx/sample 50)
(rx/to-atom)))
(defonce bounding-rect (atom {}))
2015-12-18 11:18:00 +02:00
2015-12-17 15:44:05 +02:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Constants
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def viewport-height 2048)
(def viewport-width 2048)
2015-12-17 15:44:05 +02:00
(def document-start-x 50)
(def document-start-y 50)