mirror of
https://github.com/penpot/penpot.git
synced 2025-01-21 06:02:32 -05:00
✨ Fix linter issues on frontend (part 6).
This commit is contained in:
parent
0f3e4c289c
commit
e796c3dfba
55 changed files with 629 additions and 771 deletions
|
@ -7,14 +7,17 @@
|
|||
|
||||
:hooks
|
||||
{:analyze-call {app.common.data/export hooks.export/export
|
||||
potok.core/reify hooks.export/potok-reify}}
|
||||
potok.core/reify hooks.export/potok-reify
|
||||
cljs.core/specify! hooks.export/clojure-specify}}
|
||||
|
||||
:output
|
||||
{:exclude-files
|
||||
["data_readers.clj"
|
||||
"app/util/perf.cljs"
|
||||
"app/common/exceptions.cljc"
|
||||
"app/util/import/.*"
|
||||
"app/worker/.*"
|
||||
"app/worker/export.cljs"
|
||||
"app/worker/import.cljs"
|
||||
"app/libs/.*"
|
||||
"app/main/data/workspace/path/selection.cljs"
|
||||
"app/main/data/workspace/transforms.cljs"
|
||||
|
@ -31,6 +34,9 @@
|
|||
:single-key-in
|
||||
{:level :warning}
|
||||
|
||||
:redundant-do
|
||||
{:level :off}
|
||||
|
||||
:unused-binding
|
||||
{:exclude-destructured-as true
|
||||
:exclude-destructured-keys-in-fn-args false
|
||||
|
|
|
@ -19,3 +19,12 @@
|
|||
(api/vector-node [])]
|
||||
other))]
|
||||
{:node result}))
|
||||
|
||||
(defn clojure-specify
|
||||
[{:keys [:node]}]
|
||||
(let [[rnode rtype & other] (:children node)
|
||||
result (api/list-node
|
||||
(into [(api/token-node (symbol "extend-type"))
|
||||
(api/token-node (gensym (:string-value rtype)))]
|
||||
other))]
|
||||
{:node result}))
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
(:require-macros [app.common.data]))
|
||||
(:require
|
||||
[app.common.math :as mth]
|
||||
[cljs.analyzer.api :as aapi]
|
||||
[clojure.set :as set]
|
||||
#?(:clj [cljs.analyzer.api :as aapi])
|
||||
#?(:cljs [cljs.reader :as r]
|
||||
:clj [clojure.edn :as r])
|
||||
#?(:cljs [cljs.core :as core]
|
||||
|
@ -275,7 +275,7 @@
|
|||
;; Data Parsing / Conversion
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- nan?
|
||||
(defn nan?
|
||||
[v]
|
||||
(not= v v))
|
||||
|
||||
|
@ -506,7 +506,7 @@
|
|||
|
||||
(defn- extract-numeric-suffix
|
||||
[basename]
|
||||
(if-let [[match p1 p2] (re-find #"(.*)-([0-9]+)$" basename)]
|
||||
(if-let [[_ p1 p2] (re-find #"(.*)-([0-9]+)$" basename)]
|
||||
[p1 (+ 1 (parse-integer p2))]
|
||||
[basename 1]))
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
(defn str->matrix
|
||||
[matrix-str]
|
||||
(let [params (->> (re-seq number-regex matrix-str)
|
||||
(filter #(-> % first empty? not))
|
||||
(filter #(-> % first seq))
|
||||
(map (comp d/parse-double first)))]
|
||||
(apply matrix params)))
|
||||
|
||||
|
@ -52,12 +52,11 @@
|
|||
"Given two TRANSLATE matrixes (only e and f have significative
|
||||
values), combine them. Quicker than multiplying them, for this
|
||||
precise case."
|
||||
([{m1a :a m1b :b m1c :c m1d :d m1e :e m1f :f}
|
||||
{m2a :a m2b :b m2c :c m2d :d m2e :e m2f :f}]
|
||||
([{m1e :e m1f :f} {m2e :e m2f :f}]
|
||||
(Matrix.
|
||||
1
|
||||
0
|
||||
0
|
||||
1
|
||||
0
|
||||
0
|
||||
1
|
||||
(+ m1e m2e)
|
||||
(+ m1f m2f)))
|
||||
|
|
|
@ -32,13 +32,10 @@
|
|||
(when verify?
|
||||
(us/assert ::spec/changes items))
|
||||
|
||||
(let [pages (into #{} (map :page-id) items)
|
||||
result (->> items
|
||||
(reduce #(or (process-change %1 %2) %1) data))]
|
||||
|
||||
(let [result (reduce #(or (process-change %1 %2) %1) data items)]
|
||||
;; Validate result shapes (only on the backend)
|
||||
#?(:clj
|
||||
(doseq [page-id pages]
|
||||
(doseq [page-id (into #{} (map :page-id) items)]
|
||||
(let [page (get-in result [:pages-index page-id])]
|
||||
(doseq [[id shape] (:objects page)]
|
||||
(when-not (= shape (get-in data [:pages-index page-id :objects id]))
|
||||
|
|
|
@ -395,11 +395,11 @@
|
|||
:internal.media-object/mtype]))
|
||||
|
||||
(s/def ::media-object-update
|
||||
(s/keys :req-un [::id]
|
||||
:req-opt [::name
|
||||
:internal.media-object/width
|
||||
:internal.media-object/height
|
||||
:internal.media-object/mtype]))
|
||||
(s/keys :req-un [::id]
|
||||
:opt-un [::name
|
||||
:internal.media-object/width
|
||||
:internal.media-object/height
|
||||
:internal.media-object/mtype]))
|
||||
|
||||
(s/def :internal.file/colors
|
||||
(s/map-of ::uuid ::color))
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
;; NOTE: don't remove this, causes exception on advanced build
|
||||
;; because of some strange interaction with cljs.spec.alpha and
|
||||
;; modules spliting.
|
||||
[expound.alpha]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.uuid :as uuid]
|
||||
[cuerdas.core :as str]))
|
||||
[cuerdas.core :as str]
|
||||
[expound.alpha]))
|
||||
|
||||
(s/check-asserts true)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.common.uuid
|
||||
(:refer-clojure :exclude [next uuid zero?])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
#?(:clj [app.common.data :as d])
|
||||
#?(:clj [clj-uuid :as impl])
|
||||
#?(:clj [clojure.core :as c])
|
||||
#?(:cljs [app.common.uuid-impl :as impl])
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
(apply min-key first)
|
||||
second)))
|
||||
|
||||
(defn- snap-frame-id [shapes]
|
||||
(defn snap-frame-id [shapes]
|
||||
(let [frames (into #{} (map :frame-id shapes))]
|
||||
(cond
|
||||
;; Only shapes from one frame. The common is the only one
|
||||
|
|
|
@ -6,15 +6,12 @@
|
|||
|
||||
(ns app.main.ui
|
||||
(:require
|
||||
[app.config :as cf]
|
||||
[app.common.data :as d]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cfg]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.data.messages :as dm]
|
||||
[app.config :as cf]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.messages :as dm]
|
||||
[app.main.data.users :as du]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.auth :refer [auth]]
|
||||
|
@ -32,8 +29,6 @@
|
|||
[app.main.ui.static :as static]
|
||||
[app.main.ui.viewer :refer [viewer-page]]
|
||||
[app.main.ui.workspace :as workspace]
|
||||
[app.util.i18n :as i18n :refer [tr t]]
|
||||
[app.util.router :as rt]
|
||||
[app.util.timers :as ts]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
[cljs.spec.alpha :as s]
|
||||
|
@ -60,11 +55,11 @@
|
|||
(def routes
|
||||
[["/auth"
|
||||
["/login" :auth-login]
|
||||
(when cfg/registration-enabled
|
||||
(when cf/registration-enabled
|
||||
["/register" :auth-register])
|
||||
(when cfg/registration-enabled
|
||||
(when cf/registration-enabled
|
||||
["/register/validate" :auth-register-validate])
|
||||
(when cfg/registration-enabled
|
||||
(when cf/registration-enabled
|
||||
["/register/success" :auth-register-success])
|
||||
["/recovery/request" :auth-recovery-request]
|
||||
["/recovery" :auth-recovery]
|
||||
|
@ -102,9 +97,8 @@
|
|||
|
||||
(mf/defc on-main-error
|
||||
[{:keys [error] :as props}]
|
||||
(let [data (ex-data error)]
|
||||
(mf/use-effect #(ptk/handle-error error))
|
||||
[:span "Internal application errror"]))
|
||||
(mf/use-effect #(ptk/handle-error error))
|
||||
[:span "Internal application errror"])
|
||||
|
||||
(mf/defc main-page
|
||||
{::mf/wrap [#(mf/catch % {:fallback on-main-error})]}
|
||||
|
@ -211,14 +205,14 @@
|
|||
(derive :service-unavailable ::exceptional-state)
|
||||
|
||||
(defmethod ptk/handle-error ::exceptional-state
|
||||
[{:keys [status] :as error}]
|
||||
[error]
|
||||
(ts/schedule
|
||||
(st/emitf (dm/assign-exception error))))
|
||||
|
||||
;; We receive a explicit authentication error; this explicitly clears
|
||||
;; all profile data and redirect the user to the login page.
|
||||
(defmethod ptk/handle-error :authentication
|
||||
[error]
|
||||
[_]
|
||||
(ts/schedule (st/emitf (du/logout))))
|
||||
|
||||
;; Error that happens on an active bussines model validation does not
|
||||
|
@ -245,7 +239,7 @@
|
|||
|
||||
;; Error on parsing an SVG
|
||||
(defmethod ptk/handle-error :svg-parser
|
||||
[error]
|
||||
[_]
|
||||
(ts/schedule
|
||||
(st/emitf
|
||||
(dm/show {:content "SVG is invalid or malformed"
|
||||
|
@ -261,7 +255,7 @@
|
|||
context (str/fmt "ns: '%s'\nname: '%s'\nfile: '%s:%s'"
|
||||
(:ns context)
|
||||
(:name context)
|
||||
(str cfg/public-uri "js/cljs-runtime/" (:file context))
|
||||
(str cf/public-uri "js/cljs-runtime/" (:file context))
|
||||
(:line context))]
|
||||
(ts/schedule
|
||||
(st/emitf
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
(st/emit! (dm/error (tr "errors.generic")))))
|
||||
|
||||
(defn- handle-prepare-register-success
|
||||
[form {:keys [token] :as result}]
|
||||
[_form {:keys [token] :as result}]
|
||||
(st/emit! (rt/nav :auth-register-validate {} {:token token})))
|
||||
|
||||
(mf/defc register-form
|
||||
|
@ -163,7 +163,7 @@
|
|||
(st/emit! (dm/error (tr "errors.generic"))))))
|
||||
|
||||
(defn- handle-register-success
|
||||
[form data]
|
||||
[_form data]
|
||||
(cond
|
||||
(some? (:invitation-token data))
|
||||
(let [token (:invitation-token data)]
|
||||
|
@ -197,7 +197,7 @@
|
|||
|
||||
on-submit
|
||||
(mf/use-callback
|
||||
(fn [form event]
|
||||
(fn [form _event]
|
||||
(reset! submitted? true)
|
||||
(let [params (:clean-data @form)]
|
||||
(->> (rp/mutation :register-profile params)
|
||||
|
|
|
@ -6,14 +6,10 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.common
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.util.dom :as dom]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc advanced-options [{:keys [visible? on-close children]}]
|
||||
(let [ref (mf/use-ref nil)
|
||||
handle-click (fn [event] (when on-close
|
||||
(do (dom/stop-propagation event)
|
||||
(on-close))))]
|
||||
(mf/defc advanced-options [{:keys [visible? children]}]
|
||||
(let [ref (mf/use-ref nil)]
|
||||
(mf/use-effect
|
||||
(mf/deps visible?)
|
||||
(fn []
|
||||
|
|
|
@ -6,16 +6,13 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.blur
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [t]]))
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def blur-attrs [:blur])
|
||||
|
||||
|
@ -27,8 +24,7 @@
|
|||
:hidden false}))
|
||||
|
||||
(mf/defc blur-menu [{:keys [ids type values]}]
|
||||
(let [locale (i18n/use-locale)
|
||||
blur (:blur values)
|
||||
(let [blur (:blur values)
|
||||
has-value? (not (nil? blur))
|
||||
multiple? (= blur :multiple)
|
||||
|
||||
|
@ -59,9 +55,9 @@
|
|||
[:div.element-set-title
|
||||
[:span
|
||||
(case type
|
||||
:multiple (t locale "workspace.options.blur-options.title.multiple")
|
||||
:group (t locale "workspace.options.blur-options.title.group")
|
||||
(t locale "workspace.options.blur-options.title"))]
|
||||
:multiple (tr "workspace.options.blur-options.title.multiple")
|
||||
:group (tr "workspace.options.blur-options.title.group")
|
||||
(tr "workspace.options.blur-options.title"))]
|
||||
|
||||
[:div.element-set-title-actions
|
||||
(when (and has-value? (not multiple?))
|
||||
|
@ -78,5 +74,5 @@
|
|||
:class "pixels"
|
||||
:min 0
|
||||
:value (:value blur)
|
||||
:placeholder (t locale "settings.multiple")
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-change handle-change}]])]))
|
||||
|
|
|
@ -6,20 +6,19 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.component
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [t]]
|
||||
[app.util.dom :as dom]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def component-attrs [:component-id :component-file :shape-ref])
|
||||
|
||||
|
|
|
@ -6,19 +6,16 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.exports
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[beicon.core :as rx]
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.data.messages :as dm]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.util.object :as obj]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.http :as http]
|
||||
[app.util.i18n :as i18n :refer [tr t]]))
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[beicon.core :as rx]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(defn request-export
|
||||
[shape exports]
|
||||
|
@ -31,8 +28,7 @@
|
|||
|
||||
(mf/defc exports-menu
|
||||
[{:keys [shape page-id file-id] :as props}]
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
exports (:exports shape [])
|
||||
(let [exports (:exports shape [])
|
||||
loading? (mf/use-state false)
|
||||
|
||||
filename (cond-> (:name shape)
|
||||
|
@ -50,7 +46,7 @@
|
|||
(rx/subs
|
||||
(fn [body]
|
||||
(dom/trigger-download filename body))
|
||||
(fn [error]
|
||||
(fn [_error]
|
||||
(swap! loading? not)
|
||||
(st/emit! (dm/error (tr "errors.unexpected-error"))))
|
||||
(fn []
|
||||
|
@ -108,7 +104,7 @@
|
|||
|
||||
[:div.element-set.exports-options
|
||||
[:div.element-set-title
|
||||
[:span (t locale "workspace.options.export")]
|
||||
[:span (tr "workspace.options.export")]
|
||||
[:div.add-page {:on-click add-export} i/close]]
|
||||
(when (seq exports)
|
||||
[:div.element-set-content
|
||||
|
@ -141,6 +137,6 @@
|
|||
:btn-disabled @loading?)
|
||||
:disabled @loading?}
|
||||
(if @loading?
|
||||
(t locale "workspace.options.exporting-object")
|
||||
(t locale "workspace.options.export-object"))]])]))
|
||||
(tr "workspace.options.exporting-object")
|
||||
(tr "workspace.options.export-object"))]])]))
|
||||
|
||||
|
|
|
@ -8,16 +8,12 @@
|
|||
(:require
|
||||
[app.common.pages :as cp]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||
[app.util.color :as uc]
|
||||
[app.util.i18n :as i18n :refer [tr t]]
|
||||
[app.util.object :as obj]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def fill-attrs
|
||||
|
@ -30,14 +26,13 @@
|
|||
(mf/defc fill-menu
|
||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values"]))]}
|
||||
[{:keys [ids type values] :as props}]
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
show? (or (not (nil? (:fill-color values)))
|
||||
(not (nil? (:fill-color-gradient values))))
|
||||
(let [show? (or (not (nil? (:fill-color values)))
|
||||
(not (nil? (:fill-color-gradient values))))
|
||||
|
||||
label (case type
|
||||
:multiple (t locale "workspace.options.selection-fill")
|
||||
:group (t locale "workspace.options.group-fill")
|
||||
(t locale "workspace.options.fill"))
|
||||
:multiple (tr "workspace.options.selection-fill")
|
||||
:group (tr "workspace.options.group-fill")
|
||||
(tr "workspace.options.fill"))
|
||||
|
||||
color {:color (:fill-color values)
|
||||
:opacity (:fill-opacity values)
|
||||
|
@ -48,21 +43,21 @@
|
|||
on-add
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (dc/change-fill ids {:color cp/default-color
|
||||
:opacity 1}))))
|
||||
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (dc/change-fill ids (into {} uc/empty-color)))))
|
||||
|
||||
on-change
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [color]
|
||||
(let [remove-multiple (fn [[key value]] (not= value :multiple))
|
||||
(let [remove-multiple (fn [[_ value]] (not= value :multiple))
|
||||
color (into {} (filter remove-multiple) color)]
|
||||
(st/emit! (dc/change-fill ids color)))))
|
||||
|
||||
|
@ -70,7 +65,7 @@
|
|||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn []
|
||||
(let [remove-multiple (fn [[key value]] (not= value :multiple))
|
||||
(let [remove-multiple (fn [[_ value]] (not= value :multiple))
|
||||
color (-> (into {} (filter remove-multiple) color)
|
||||
(assoc :id nil :file-id nil))]
|
||||
(st/emit! (dc/change-fill ids color)))))
|
||||
|
@ -78,13 +73,13 @@
|
|||
on-open-picker
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [value opacity id file-id]
|
||||
(fn [_value _opacity _id _file-id]
|
||||
(st/emit! (dwu/start-undo-transaction))))
|
||||
|
||||
on-close-picker
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [value opacity id file-id]
|
||||
(fn [_value _opacity _id _file-id]
|
||||
(st/emit! (dwu/commit-undo-transaction))))]
|
||||
|
||||
(if show?
|
||||
|
|
|
@ -6,38 +6,34 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.frame-grid
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[okulary.core :as l]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.data :as d]
|
||||
[app.common.math :as mth]
|
||||
[app.common.data :refer [parse-integer]]
|
||||
[app.main.store :as st]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.data.workspace.grid :as dw]
|
||||
[app.util.geom.grid :as gg]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.editable-select :refer [editable-select]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
|
||||
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
[app.main.ui.components.editable-select :refer [editable-select]]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.util.i18n :as i18n :refer [tr t]]))
|
||||
[app.util.data :as d]
|
||||
[app.util.geom.grid :as gg]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[okulary.core :as l]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def workspace-saved-grids
|
||||
(l/derived :saved-grids refs/workspace-page-options))
|
||||
|
||||
(defn- get-size-options [locale]
|
||||
[{:value :auto :label (t locale "workspace.options.grid.auto")}
|
||||
(defn- get-size-options []
|
||||
[{:value :auto :label (tr "workspace.options.grid.auto")}
|
||||
:separator
|
||||
18 12 10 8 6 4 3 2])
|
||||
|
||||
(mf/defc grid-options
|
||||
[{:keys [grid frame default-grid-params on-change on-remove on-save-grid]}]
|
||||
(let [locale (i18n/use-locale)
|
||||
size-options (get-size-options locale)
|
||||
(let [size-options (get-size-options)
|
||||
state (mf/use-state {:show-advanced-options false})
|
||||
{:keys [type display params]} grid
|
||||
|
||||
|
@ -45,12 +41,12 @@
|
|||
#(swap! state update :show-advanced-options not)
|
||||
|
||||
handle-toggle-visibility
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when on-change
|
||||
(on-change (update grid :display #(if (nil? %) false (not %))))))
|
||||
|
||||
handle-remove-grid
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when on-remove (on-remove)))
|
||||
|
||||
handle-change-type
|
||||
|
@ -82,7 +78,7 @@
|
|||
|
||||
handle-change-item-length
|
||||
(fn [item-length]
|
||||
(let [{:keys [margin gutter size]} (:params grid)
|
||||
(let [size (get-in grid [:params :size])
|
||||
size (if (and (nil? item-length) (or (nil? size) (= :auto size))) 12 size)]
|
||||
(when on-change
|
||||
(on-change (-> grid
|
||||
|
@ -128,9 +124,9 @@
|
|||
|
||||
[:& select {:class "flex-grow"
|
||||
:default-value type
|
||||
:options [{:value :square :label (t locale "workspace.options.grid.square")}
|
||||
{:value :column :label (t locale "workspace.options.grid.column")}
|
||||
{:value :row :label (t locale "workspace.options.grid.row")}]
|
||||
:options [{:value :square :label (tr "workspace.options.grid.square")}
|
||||
{:value :column :label (tr "workspace.options.grid.column")}
|
||||
{:value :row :label (tr "workspace.options.grid.row")}]
|
||||
:on-change handle-change-type}]
|
||||
|
||||
(if (= type :square)
|
||||
|
@ -154,14 +150,14 @@
|
|||
:on-close toggle-advanced-options}
|
||||
[:button.custom-button {:on-click toggle-advanced-options} i/actions]
|
||||
(when (= :square type)
|
||||
[:& input-row {:label (t locale "workspace.options.grid.params.size")
|
||||
[:& input-row {:label (tr "workspace.options.grid.params.size")
|
||||
:class "pixels"
|
||||
:min 1
|
||||
:value (:size params)
|
||||
:on-change (handle-change :params :size)}])
|
||||
|
||||
(when (= :row type)
|
||||
[:& input-row {:label (t locale "workspace.options.grid.params.rows")
|
||||
[:& input-row {:label (tr "workspace.options.grid.params.rows")
|
||||
:type :editable-select
|
||||
:options size-options
|
||||
:value (:size params)
|
||||
|
@ -170,7 +166,7 @@
|
|||
:on-change handle-change-size}])
|
||||
|
||||
(when (= :column type)
|
||||
[:& input-row {:label (t locale "workspace.options.grid.params.columns")
|
||||
[:& input-row {:label (tr "workspace.options.grid.params.columns")
|
||||
:type :editable-select
|
||||
:options size-options
|
||||
:value (:size params)
|
||||
|
@ -179,23 +175,23 @@
|
|||
:on-change handle-change-size}])
|
||||
|
||||
(when (#{:row :column} type)
|
||||
[:& input-row {:label (t locale "workspace.options.grid.params.type")
|
||||
[:& input-row {:label (tr "workspace.options.grid.params.type")
|
||||
:type :select
|
||||
:options [{:value :stretch :label (t locale "workspace.options.grid.params.type.stretch")}
|
||||
:options [{:value :stretch :label (tr "workspace.options.grid.params.type.stretch")}
|
||||
{:value :left :label (if (= type :row)
|
||||
(t locale "workspace.options.grid.params.type.top")
|
||||
(t locale "workspace.options.grid.params.type.left"))}
|
||||
{:value :center :label (t locale "workspace.options.grid.params.type.center")}
|
||||
(tr "workspace.options.grid.params.type.top")
|
||||
(tr "workspace.options.grid.params.type.left"))}
|
||||
{:value :center :label (tr "workspace.options.grid.params.type.center")}
|
||||
{:value :right :label (if (= type :row)
|
||||
(t locale "workspace.options.grid.params.type.bottom")
|
||||
(t locale "workspace.options.grid.params.type.right"))}]
|
||||
(tr "workspace.options.grid.params.type.bottom")
|
||||
(tr "workspace.options.grid.params.type.right"))}]
|
||||
:value (:type params)
|
||||
:on-change (handle-change :params :type)}])
|
||||
|
||||
(when (#{:row :column} type)
|
||||
[:& input-row {:label (if (= :row type)
|
||||
(t locale "workspace.options.grid.params.height")
|
||||
(t locale "workspace.options.grid.params.width"))
|
||||
(tr "workspace.options.grid.params.height")
|
||||
(tr "workspace.options.grid.params.width"))
|
||||
:class "pixels"
|
||||
:placeholder "Auto"
|
||||
:value (or (:item-length params) "")
|
||||
|
@ -203,13 +199,13 @@
|
|||
|
||||
(when (#{:row :column} type)
|
||||
[:*
|
||||
[:& input-row {:label (t locale "workspace.options.grid.params.gutter")
|
||||
[:& input-row {:label (tr "workspace.options.grid.params.gutter")
|
||||
:class "pixels"
|
||||
:value (:gutter params)
|
||||
:min 0
|
||||
:placeholder "0"
|
||||
:on-change (handle-change :params :gutter)}]
|
||||
[:& input-row {:label (t locale "workspace.options.grid.params.margin")
|
||||
[:& input-row {:label (tr "workspace.options.grid.params.margin")
|
||||
:class "pixels"
|
||||
:min 0
|
||||
:placeholder "0"
|
||||
|
@ -222,13 +218,12 @@
|
|||
:on-detach handle-detach-color}]
|
||||
[:div.row-flex
|
||||
[:button.btn-options {:disabled is-default
|
||||
:on-click handle-use-default} (t locale "workspace.options.grid.params.use-default")]
|
||||
:on-click handle-use-default} (tr "workspace.options.grid.params.use-default")]
|
||||
[:button.btn-options {:disabled is-default
|
||||
:on-click handle-set-as-default} (t locale "workspace.options.grid.params.set-default")]]]]))
|
||||
:on-click handle-set-as-default} (tr "workspace.options.grid.params.set-default")]]]]))
|
||||
|
||||
(mf/defc frame-grid [{:keys [shape]}]
|
||||
(let [locale (i18n/use-locale)
|
||||
id (:id shape)
|
||||
(let [id (:id shape)
|
||||
default-grid-params (merge dw/default-grid-params (mf/deref workspace-saved-grids))
|
||||
handle-create-grid #(st/emit! (dw/add-frame-grid id))
|
||||
handle-remove-grid (fn [index] #(st/emit! (dw/remove-frame-grid id index)))
|
||||
|
@ -236,10 +231,10 @@
|
|||
handle-save-grid (fn [grid] (st/emit! (dw/set-default-grid (:type grid) (:params grid))))]
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span (t locale "workspace.options.grid.title")]
|
||||
[:span (tr "workspace.options.grid.title")]
|
||||
[:div.add-page {:on-click handle-create-grid} i/close]]
|
||||
|
||||
(when (not (empty? (:grids shape)))
|
||||
(when (seq (:grids shape))
|
||||
[:div.element-set-content
|
||||
(for [[index grid] (map-indexed vector (:grids shape))]
|
||||
[:& grid-options {:key (str (:id shape) "-" index)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.interactions
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -14,13 +13,12 @@
|
|||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [t]]))
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc interactions-menu
|
||||
[{:keys [shape] :as props}]
|
||||
(let [locale (mf/deref i18n/locale)
|
||||
objects (deref refs/workspace-page-objects)
|
||||
(let [objects (deref refs/workspace-page-objects)
|
||||
interaction (first (:interactions shape)) ; TODO: in the
|
||||
; future we may
|
||||
; have several
|
||||
|
@ -48,26 +46,26 @@
|
|||
(if (not shape)
|
||||
[:*
|
||||
[:div.interactions-help-icon i/interaction]
|
||||
[:div.interactions-help (t locale "workspace.options.select-a-shape")]
|
||||
[:div.interactions-help (tr "workspace.options.select-a-shape")]
|
||||
[:div.interactions-help-icon i/play]
|
||||
[:div.interactions-help (t locale "workspace.options.use-play-button")]]
|
||||
[:div.interactions-help (tr "workspace.options.use-play-button")]]
|
||||
|
||||
[:div.element-set {:on-blur on-set-blur}
|
||||
[:div.element-set-title
|
||||
[:span (t locale "workspace.options.navigate-to")]]
|
||||
[:span (tr "workspace.options.navigate-to")]]
|
||||
[:div.element-set-content
|
||||
[:div.row-flex
|
||||
[:div.custom-select.flex-grow {:on-click #(reset! show-frames-dropdown? true)}
|
||||
(if destination
|
||||
[:span (:name destination)]
|
||||
[:span (t locale "workspace.options.select-artboard")])
|
||||
[:span (tr "workspace.options.select-artboard")])
|
||||
[:span.dropdown-button i/arrow-down]
|
||||
[:& dropdown {:show @show-frames-dropdown?
|
||||
:on-close #(reset! show-frames-dropdown? false)}
|
||||
[:ul.custom-select-dropdown
|
||||
[:li.dropdown-separator
|
||||
{:on-click #(on-select-destination nil)}
|
||||
(t locale "workspace.options.none")]
|
||||
(tr "workspace.options.none")]
|
||||
|
||||
(for [frame frames]
|
||||
(when (and (not= (:id frame) (:id shape)) ; A frame cannot navigate to itself
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.math :as mth]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
|
@ -54,25 +53,25 @@
|
|||
handle-set-hidden
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(change! :hidden true)))
|
||||
|
||||
handle-set-visible
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(change! :hidden false)))
|
||||
|
||||
handle-set-blocked
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(change! :blocked true)))
|
||||
|
||||
handle-set-unblocked
|
||||
(mf/use-callback
|
||||
(mf/deps change!)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(change! :blocked false)))]
|
||||
|
||||
[:div.element-set
|
||||
|
@ -92,7 +91,7 @@
|
|||
[:option {:value "multiple"} "--"])
|
||||
|
||||
[:option {:value "normal"} (tr "workspace.options.layer-options.blend-mode.normal")]
|
||||
|
||||
|
||||
[:option {:value "darken"} (tr "workspace.options.layer-options.blend-mode.darken")]
|
||||
[:option {:value "multiply"} (tr "workspace.options.layer-options.blend-mode.multiply")]
|
||||
[:option {:value "color-burn"} (tr "workspace.options.layer-options.blend-mode.color-burn")]
|
||||
|
@ -127,13 +126,13 @@
|
|||
(cond
|
||||
(or (= :multiple (:hidden values)) (not (:hidden values)))
|
||||
[:div.element-set-actions-button {:on-click handle-set-hidden} i/eye]
|
||||
|
||||
|
||||
:else
|
||||
[:div.element-set-actions-button {:on-click handle-set-visible} i/eye-closed])
|
||||
|
||||
(cond
|
||||
(or (= :multiple (:blocked values)) (not (:blocked values)))
|
||||
[:div.element-set-actions-button {:on-click handle-set-blocked} i/unlock]
|
||||
|
||||
|
||||
:else
|
||||
[:div.element-set-actions-button {:on-click handle-set-unblocked} i/lock])]]]]))
|
||||
|
|
|
@ -6,24 +6,21 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.measures
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.store :as st]
|
||||
[app.main.refs :as refs]
|
||||
[app.common.data :as d]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.data :refer [classnames]]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.math :as math]
|
||||
[app.common.pages.spec :as spec]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.common.math :as math]
|
||||
[app.util.i18n :refer [tr] :as i18n]))
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def measure-attrs [:proportion-lock
|
||||
:width :height
|
||||
|
@ -88,7 +85,7 @@
|
|||
on-proportion-lock-change
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(let [new-lock (if (= proportion-lock :multiple) true (not proportion-lock))]
|
||||
(run! #(st/emit! (udw/set-shape-proportion-lock % new-lock)) ids))))
|
||||
|
||||
|
@ -114,7 +111,7 @@
|
|||
on-switch-to-radius-1
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [value]
|
||||
(fn [_value]
|
||||
(let [radius-update
|
||||
(fn [shape]
|
||||
(cond-> shape
|
||||
|
@ -126,7 +123,7 @@
|
|||
on-switch-to-radius-4
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [value]
|
||||
(fn [_value]
|
||||
(let [radius-update
|
||||
(fn [shape]
|
||||
(cond-> shape
|
||||
|
@ -180,164 +177,162 @@
|
|||
|
||||
on-constraint-button-clicked
|
||||
(mf/use-callback
|
||||
(mf/deps [ids values])
|
||||
(fn [button]
|
||||
(fn [event]
|
||||
(let [constraints-h (get values :constraints-h :scale)
|
||||
constraints-v (get values :constraints-v :scale)
|
||||
(mf/deps [ids values])
|
||||
(fn [button]
|
||||
(fn [_]
|
||||
(let [constraints-h (get values :constraints-h :scale)
|
||||
constraints-v (get values :constraints-v :scale)
|
||||
|
||||
[constraint new-value]
|
||||
(case button
|
||||
:top (case constraints-v
|
||||
:top [:constraints-v :scale]
|
||||
:topbottom [:constraints-v :bottom]
|
||||
:bottom [:constraints-v :topbottom]
|
||||
[:constraints-v :top])
|
||||
:bottom (case constraints-v
|
||||
:bottom [:constraints-v :scale]
|
||||
:topbottom [:constraints-v :top]
|
||||
:top [:constraints-v :topbottom]
|
||||
[:constraints-v :bottom])
|
||||
:left (case constraints-h
|
||||
:left [:constraints-h :scale]
|
||||
:leftright [:constraints-h :right]
|
||||
:right [:constraints-h :leftright]
|
||||
[:constraints-h :left])
|
||||
:right (case constraints-h
|
||||
:right [:constraints-h :scale]
|
||||
:leftright [:constraints-h :left]
|
||||
:left [:constraints-h :leftright]
|
||||
[:constraints-h :right])
|
||||
:centerv (case constraints-v
|
||||
[constraint new-value]
|
||||
(case button
|
||||
:top (case constraints-v
|
||||
:top [:constraints-v :scale]
|
||||
:topbottom [:constraints-v :bottom]
|
||||
:bottom [:constraints-v :topbottom]
|
||||
[:constraints-v :top])
|
||||
:bottom (case constraints-v
|
||||
:bottom [:constraints-v :scale]
|
||||
:topbottom [:constraints-v :top]
|
||||
:top [:constraints-v :topbottom]
|
||||
[:constraints-v :bottom])
|
||||
:left (case constraints-h
|
||||
:left [:constraints-h :scale]
|
||||
:leftright [:constraints-h :right]
|
||||
:right [:constraints-h :leftright]
|
||||
[:constraints-h :left])
|
||||
:right (case constraints-h
|
||||
:right [:constraints-h :scale]
|
||||
:leftright [:constraints-h :left]
|
||||
:left [:constraints-h :leftright]
|
||||
[:constraints-h :right])
|
||||
:centerv (case constraints-v
|
||||
:center [:constraints-v :scale]
|
||||
[:constraints-v :center])
|
||||
:centerh (case constraints-h
|
||||
:centerh (case constraints-h
|
||||
:center [:constraints-h :scale]
|
||||
[:constraints-h :center]))]
|
||||
(st/emit! (dch/update-shapes
|
||||
ids
|
||||
#(assoc % constraint new-value)))))))
|
||||
(st/emit! (dch/update-shapes
|
||||
ids
|
||||
#(assoc % constraint new-value)))))))
|
||||
|
||||
on-constraint-select-changed
|
||||
(mf/use-callback
|
||||
(mf/deps [ids values])
|
||||
(fn [constraint]
|
||||
(mf/deps [ids values])
|
||||
(fn [constraint]
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target-val event) (keyword))]
|
||||
(when-not (str/empty? value)
|
||||
(st/emit! (dch/update-shapes
|
||||
ids
|
||||
#(assoc % constraint value))))))))
|
||||
ids
|
||||
#(assoc % constraint value))))))))
|
||||
|
||||
on-fixed-scroll-clicked
|
||||
(mf/use-callback
|
||||
(mf/deps [ids values])
|
||||
(fn [event]
|
||||
(st/emit! (dch/update-shapes
|
||||
ids
|
||||
#(update % :fixed-scroll not)))))]
|
||||
(mf/deps [ids values])
|
||||
(fn [_]
|
||||
(st/emit! (dch/update-shapes ids #(update % :fixed-scroll not)))))]
|
||||
[:*
|
||||
[:div.element-set
|
||||
[:div.element-set-content
|
||||
[:div.element-set
|
||||
[:div.element-set-content
|
||||
|
||||
;; WIDTH & HEIGHT
|
||||
(when (options :size)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (tr "workspace.options.size")]
|
||||
[:div.input-element.width
|
||||
[:> numeric-input {:min 1
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-width-change
|
||||
:value (attr->string :width values)}]]
|
||||
;; WIDTH & HEIGHT
|
||||
(when (options :size)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (tr "workspace.options.size")]
|
||||
[:div.input-element.width
|
||||
[:> numeric-input {:min 1
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-width-change
|
||||
:value (attr->string :width values)}]]
|
||||
|
||||
[:div.input-element.height
|
||||
[:> numeric-input {:min 1
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-height-change
|
||||
:value (attr->string :height values)}]]
|
||||
[:div.input-element.height
|
||||
[:> numeric-input {:min 1
|
||||
:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-height-change
|
||||
:value (attr->string :height values)}]]
|
||||
|
||||
[:div.lock-size {:class (classnames
|
||||
[:div.lock-size {:class (dom/classnames
|
||||
:selected (true? proportion-lock)
|
||||
:disabled (= proportion-lock :multiple))
|
||||
:on-click on-proportion-lock-change}
|
||||
(if proportion-lock
|
||||
i/lock
|
||||
i/unlock)]])
|
||||
:on-click on-proportion-lock-change}
|
||||
(if proportion-lock
|
||||
i/lock
|
||||
i/unlock)]])
|
||||
|
||||
;; POSITION
|
||||
(when (options :position)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (tr "workspace.options.position")]
|
||||
[:div.input-element.Xaxis
|
||||
[:> numeric-input {:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-pos-x-change
|
||||
:value (attr->string :x values)}]]
|
||||
[:div.input-element.Yaxis
|
||||
[:> numeric-input {:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-pos-y-change
|
||||
:value (attr->string :y values)}]]])
|
||||
;; POSITION
|
||||
(when (options :position)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (tr "workspace.options.position")]
|
||||
[:div.input-element.Xaxis
|
||||
[:> numeric-input {:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-pos-x-change
|
||||
:value (attr->string :x values)}]]
|
||||
[:div.input-element.Yaxis
|
||||
[:> numeric-input {:no-validate true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-pos-y-change
|
||||
:value (attr->string :y values)}]]])
|
||||
|
||||
;; ROTATION
|
||||
(when (options :rotation)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (tr "workspace.options.rotation")]
|
||||
[:div.input-element.degrees
|
||||
[:> numeric-input
|
||||
{:no-validate true
|
||||
:min 0
|
||||
:max 359
|
||||
:data-wrap true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-rotation-change
|
||||
:value (attr->string :rotation values)}]]
|
||||
#_[:input.slidebar
|
||||
{:type "range"
|
||||
:min "0"
|
||||
:max "359"
|
||||
:step "10"
|
||||
:no-validate true
|
||||
:on-change on-rotation-change
|
||||
:value (attr->string :rotation values)}]])
|
||||
;; ROTATION
|
||||
(when (options :rotation)
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (tr "workspace.options.rotation")]
|
||||
[:div.input-element.degrees
|
||||
[:> numeric-input
|
||||
{:no-validate true
|
||||
:min 0
|
||||
:max 359
|
||||
:data-wrap true
|
||||
:placeholder "--"
|
||||
:on-click select-all
|
||||
:on-change on-rotation-change
|
||||
:value (attr->string :rotation values)}]]
|
||||
#_[:input.slidebar
|
||||
{:type "range"
|
||||
:min "0"
|
||||
:max "359"
|
||||
:step "10"
|
||||
:no-validate true
|
||||
:on-change on-rotation-change
|
||||
:value (attr->string :rotation values)}]])
|
||||
|
||||
;; RADIUS
|
||||
(let [radius-1? (some? (:rx values))
|
||||
radius-4? (some? (:r1 values))]
|
||||
(when (and (options :radius) (or radius-1? radius-4?))
|
||||
[:div.row-flex
|
||||
[:div.radius-options
|
||||
;; RADIUS
|
||||
(let [radius-1? (some? (:rx values))
|
||||
radius-4? (some? (:r1 values))]
|
||||
(when (and (options :radius) (or radius-1? radius-4?))
|
||||
[:div.row-flex
|
||||
[:div.radius-options
|
||||
[:div.radius-icon.tooltip.tooltip-bottom
|
||||
{:class (classnames
|
||||
:selected
|
||||
(and radius-1? (not radius-4?)))
|
||||
{:class (dom/classnames
|
||||
:selected
|
||||
(and radius-1? (not radius-4?)))
|
||||
:alt (tr "workspace.options.radius.all-corners")
|
||||
:on-click on-switch-to-radius-1}
|
||||
i/radius-1]
|
||||
[:div.radius-icon.tooltip.tooltip-bottom
|
||||
{:class (classnames
|
||||
:selected
|
||||
(and radius-4? (not radius-1?)))
|
||||
{:class (dom/classnames
|
||||
:selected
|
||||
(and radius-4? (not radius-1?)))
|
||||
:alt (tr "workspace.options.radius.single-corners")
|
||||
:on-click on-switch-to-radius-4}
|
||||
i/radius-4]]
|
||||
(if radius-1?
|
||||
[:div.input-element.mini
|
||||
[:> numeric-input
|
||||
{:placeholder "--"
|
||||
:min 0
|
||||
:on-click select-all
|
||||
:on-change on-radius-1-change
|
||||
:value (attr->string :rx values)}]]
|
||||
(if radius-1?
|
||||
[:div.input-element.mini
|
||||
[:> numeric-input
|
||||
{:placeholder "--"
|
||||
:min 0
|
||||
:on-click select-all
|
||||
:on-change on-radius-1-change
|
||||
:value (attr->string :rx values)}]]
|
||||
|
||||
[:*
|
||||
[:*
|
||||
[:div.input-element.mini
|
||||
[:> numeric-input
|
||||
{:placeholder "--"
|
||||
|
@ -367,66 +362,66 @@
|
|||
:on-change on-radius-r4-change
|
||||
:value (attr->string :r4 values)}]]])]))]]
|
||||
|
||||
;; CONSTRAINTS
|
||||
(when in-frame?
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span (tr "workspace.options.constraints")]]
|
||||
;; CONSTRAINTS
|
||||
(when in-frame?
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
[:span (tr "workspace.options.constraints")]]
|
||||
|
||||
[:div.element-set-content
|
||||
[:div.row-flex.align-top
|
||||
[:div.element-set-content
|
||||
[:div.row-flex.align-top
|
||||
|
||||
[:div.constraints-widget
|
||||
[:div.constraints-box]
|
||||
[:div.constraint-button.top
|
||||
{:class (classnames :active (or (= constraints-v :top)
|
||||
(= constraints-v :topbottom)))
|
||||
:on-click (on-constraint-button-clicked :top)}]
|
||||
[:div.constraint-button.bottom
|
||||
{:class (classnames :active (or (= constraints-v :bottom)
|
||||
(= constraints-v :topbottom)))
|
||||
:on-click (on-constraint-button-clicked :bottom)}]
|
||||
[:div.constraint-button.left
|
||||
{:class (classnames :active (or (= constraints-h :left)
|
||||
(= constraints-h :leftright)))
|
||||
:on-click (on-constraint-button-clicked :left)}]
|
||||
[:div.constraint-button.right
|
||||
{:class (classnames :active (or (= constraints-h :right)
|
||||
(= constraints-h :leftright)))
|
||||
:on-click (on-constraint-button-clicked :right)}]
|
||||
[:div.constraint-button.centerv
|
||||
{:class (classnames :active (= constraints-v :center))
|
||||
:on-click (on-constraint-button-clicked :centerv)}]
|
||||
[:div.constraint-button.centerh
|
||||
{:class (classnames :active (= constraints-h :center))
|
||||
:on-click (on-constraint-button-clicked :centerh)}]]
|
||||
[:div.constraints-widget
|
||||
[:div.constraints-box]
|
||||
[:div.constraint-button.top
|
||||
{:class (dom/classnames :active (or (= constraints-v :top)
|
||||
(= constraints-v :topbottom)))
|
||||
:on-click (on-constraint-button-clicked :top)}]
|
||||
[:div.constraint-button.bottom
|
||||
{:class (dom/classnames :active (or (= constraints-v :bottom)
|
||||
(= constraints-v :topbottom)))
|
||||
:on-click (on-constraint-button-clicked :bottom)}]
|
||||
[:div.constraint-button.left
|
||||
{:class (dom/classnames :active (or (= constraints-h :left)
|
||||
(= constraints-h :leftright)))
|
||||
:on-click (on-constraint-button-clicked :left)}]
|
||||
[:div.constraint-button.right
|
||||
{:class (dom/classnames :active (or (= constraints-h :right)
|
||||
(= constraints-h :leftright)))
|
||||
:on-click (on-constraint-button-clicked :right)}]
|
||||
[:div.constraint-button.centerv
|
||||
{:class (dom/classnames :active (= constraints-v :center))
|
||||
:on-click (on-constraint-button-clicked :centerv)}]
|
||||
[:div.constraint-button.centerh
|
||||
{:class (dom/classnames :active (= constraints-h :center))
|
||||
:on-click (on-constraint-button-clicked :centerh)}]]
|
||||
|
||||
[:div.constraints-form
|
||||
[:div.row-flex
|
||||
[:span.left-right i/full-screen]
|
||||
[:select.input-select {:on-change (on-constraint-select-changed :constraints-h)
|
||||
:value (d/name constraints-h "scale")}
|
||||
(when (= constraints-h :multiple)
|
||||
[:option {:value ""} (tr "settings.multiple")])
|
||||
[:option {:value "left"} (tr "workspace.options.constraints.left")]
|
||||
[:option {:value "right"} (tr "workspace.options.constraints.right")]
|
||||
[:option {:value "leftright"} (tr "workspace.options.constraints.leftright")]
|
||||
[:option {:value "center"} (tr "workspace.options.constraints.center")]
|
||||
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
|
||||
[:div.row-flex
|
||||
[:span.top-bottom i/full-screen]
|
||||
[:select.input-select {:on-change (on-constraint-select-changed :constraints-v)
|
||||
:value (d/name constraints-v "scale")}
|
||||
(when (= constraints-v :multiple)
|
||||
[:option {:value ""} (tr "settings.multiple")])
|
||||
[:option {:value "top"} (tr "workspace.options.constraints.top")]
|
||||
[:option {:value "bottom"} (tr "workspace.options.constraints.bottom")]
|
||||
[:option {:value "topbottom"} (tr "workspace.options.constraints.topbottom")]
|
||||
[:option {:value "center"} (tr "workspace.options.constraints.center")]
|
||||
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
|
||||
(when first-level?
|
||||
[:div.row-flex
|
||||
[:div.fix-when {:class (classnames :active (:fixed-scroll values))
|
||||
:on-click on-fixed-scroll-clicked}
|
||||
i/pin
|
||||
[:span (tr "workspace.options.constraints.fix-when-scrolling")]]])]]]])]))
|
||||
[:div.constraints-form
|
||||
[:div.row-flex
|
||||
[:span.left-right i/full-screen]
|
||||
[:select.input-select {:on-change (on-constraint-select-changed :constraints-h)
|
||||
:value (d/name constraints-h "scale")}
|
||||
(when (= constraints-h :multiple)
|
||||
[:option {:value ""} (tr "settings.multiple")])
|
||||
[:option {:value "left"} (tr "workspace.options.constraints.left")]
|
||||
[:option {:value "right"} (tr "workspace.options.constraints.right")]
|
||||
[:option {:value "leftright"} (tr "workspace.options.constraints.leftright")]
|
||||
[:option {:value "center"} (tr "workspace.options.constraints.center")]
|
||||
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
|
||||
[:div.row-flex
|
||||
[:span.top-bottom i/full-screen]
|
||||
[:select.input-select {:on-change (on-constraint-select-changed :constraints-v)
|
||||
:value (d/name constraints-v "scale")}
|
||||
(when (= constraints-v :multiple)
|
||||
[:option {:value ""} (tr "settings.multiple")])
|
||||
[:option {:value "top"} (tr "workspace.options.constraints.top")]
|
||||
[:option {:value "bottom"} (tr "workspace.options.constraints.bottom")]
|
||||
[:option {:value "topbottom"} (tr "workspace.options.constraints.topbottom")]
|
||||
[:option {:value "center"} (tr "workspace.options.constraints.center")]
|
||||
[:option {:value "scale"} (tr "workspace.options.constraints.scale")]]]
|
||||
(when first-level?
|
||||
[:div.row-flex
|
||||
[:div.fix-when {:class (dom/classnames :active (:fixed-scroll values))
|
||||
:on-click on-fixed-scroll-clicked}
|
||||
i/pin
|
||||
[:span (tr "workspace.options.constraints.fix-when-scrolling")]]])]]]])]))
|
||||
|
|
|
@ -6,19 +6,18 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.shadow
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
|
||||
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [t]]))
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def shadow-attrs [:shadow])
|
||||
|
||||
|
@ -38,8 +37,7 @@
|
|||
|
||||
(mf/defc shadow-entry
|
||||
[{:keys [ids index value]}]
|
||||
(let [locale (i18n/use-locale)
|
||||
open-shadow (mf/use-state false)
|
||||
(let [open-shadow (mf/use-state false)
|
||||
|
||||
basic-offset-x-ref (mf/use-ref nil)
|
||||
basic-offset-y-ref (mf/use-ref nil)
|
||||
|
@ -52,7 +50,7 @@
|
|||
|
||||
remove-shadow-by-index
|
||||
(fn [values index] (->> (d/enumerate values)
|
||||
(filterv (fn [[idx s]] (not= idx index)))
|
||||
(filterv (fn [[idx _]] (not= idx index)))
|
||||
(mapv second)))
|
||||
|
||||
on-remove-shadow
|
||||
|
@ -61,7 +59,7 @@
|
|||
(st/emit! (dch/update-shapes ids #(update % :shadow remove-shadow-by-index index) ))))
|
||||
|
||||
select-text
|
||||
(fn [ref] (fn [event] (dom/select-text! (mf/ref-val ref))))
|
||||
(fn [ref] (fn [_] (dom/select-text! (mf/ref-val ref))))
|
||||
|
||||
update-attr
|
||||
(fn update-attr
|
||||
|
@ -86,12 +84,12 @@
|
|||
|
||||
detach-color
|
||||
(fn [index]
|
||||
(fn [color opacity]
|
||||
(if-not (string? (:color value))
|
||||
(fn [_color _opacity]
|
||||
(when-not (string? (:color value))
|
||||
(st/emit! (dch/update-shapes
|
||||
ids
|
||||
#(assoc-in % [:shadow index :color]
|
||||
(dissoc (:color value) :id :file-id)))))))
|
||||
ids
|
||||
#(assoc-in % [:shadow index :color]
|
||||
(dissoc (:color value) :id :file-id)))))))
|
||||
|
||||
toggle-visibility
|
||||
(fn [index]
|
||||
|
@ -122,8 +120,8 @@
|
|||
:on-change (fn [event]
|
||||
(let [value (-> event dom/get-target dom/get-value d/read-string)]
|
||||
(st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :style] value)))))}
|
||||
[:option {:value ":drop-shadow"} (t locale "workspace.options.shadow-options.drop-shadow")]
|
||||
[:option {:value ":inner-shadow"} (t locale "workspace.options.shadow-options.inner-shadow")]]
|
||||
[:option {:value ":drop-shadow"} (tr "workspace.options.shadow-options.drop-shadow")]
|
||||
[:option {:value ":inner-shadow"} (tr "workspace.options.shadow-options.inner-shadow")]]
|
||||
|
||||
[:div.element-set-actions
|
||||
[:div.element-set-actions-button {:on-click (toggle-visibility index)}
|
||||
|
@ -142,8 +140,8 @@
|
|||
:on-change (fn [event]
|
||||
(let [value (-> event dom/get-target dom/get-value d/read-string)]
|
||||
(st/emit! (dch/update-shapes ids #(assoc-in % [:shadow index :style] value)))))}
|
||||
[:option {:value ":drop-shadow"} (t locale "workspace.options.shadow-options.drop-shadow")]
|
||||
[:option {:value ":inner-shadow"} (t locale "workspace.options.shadow-options.inner-shadow")]]]
|
||||
[:option {:value ":drop-shadow"} (tr "workspace.options.shadow-options.drop-shadow")]
|
||||
[:option {:value ":inner-shadow"} (tr "workspace.options.shadow-options.inner-shadow")]]]
|
||||
|
||||
[:div.row-grid-2
|
||||
[:div.input-element
|
||||
|
@ -153,7 +151,7 @@
|
|||
:on-click (select-text adv-offset-x-ref)
|
||||
:on-change (update-attr index :offset-x valid-number? basic-offset-x-ref)
|
||||
:value (:offset-x value)}]
|
||||
[:span.after (t locale "workspace.options.shadow-options.offsetx")]]
|
||||
[:span.after (tr "workspace.options.shadow-options.offsetx")]]
|
||||
|
||||
[:div.input-element
|
||||
[:> numeric-input {:ref adv-offset-y-ref
|
||||
|
@ -162,7 +160,7 @@
|
|||
:on-click (select-text adv-offset-y-ref)
|
||||
:on-change (update-attr index :offset-y valid-number? basic-offset-y-ref)
|
||||
:value (:offset-y value)}]
|
||||
[:span.after (t locale "workspace.options.shadow-options.offsety")]]]
|
||||
[:span.after (tr "workspace.options.shadow-options.offsety")]]]
|
||||
|
||||
[:div.row-grid-2
|
||||
[:div.input-element
|
||||
|
@ -173,7 +171,7 @@
|
|||
:on-change (update-attr index :blur valid-number? basic-blur-ref)
|
||||
:min 0
|
||||
:value (:blur value)}]
|
||||
[:span.after (t locale "workspace.options.shadow-options.blur")]]
|
||||
[:span.after (tr "workspace.options.shadow-options.blur")]]
|
||||
|
||||
[:div.input-element
|
||||
[:> numeric-input {:ref adv-spread-ref
|
||||
|
@ -183,7 +181,7 @@
|
|||
:on-change (update-attr index :spread valid-number?)
|
||||
:min 0
|
||||
:value (:spread value)}]
|
||||
[:span.after (t locale "workspace.options.shadow-options.spread")]]]
|
||||
[:span.after (tr "workspace.options.shadow-options.spread")]]]
|
||||
|
||||
[:div.color-row-wrap
|
||||
[:& color-row {:color (if (string? (:color value))
|
||||
|
@ -197,10 +195,8 @@
|
|||
:on-close #(st/emit! (dwu/commit-undo-transaction))}]]]]))
|
||||
(mf/defc shadow-menu
|
||||
[{:keys [ids type values] :as props}]
|
||||
(let [locale (i18n/use-locale)
|
||||
on-remove-all-shadows
|
||||
(fn [event]
|
||||
(st/emit! (dch/update-shapes ids #(dissoc % :shadow) )))
|
||||
(let [on-remove-all-shadows
|
||||
(fn [_] (st/emit! (dch/update-shapes ids #(dissoc % :shadow))))
|
||||
|
||||
on-add-shadow
|
||||
(fn []
|
||||
|
@ -209,9 +205,9 @@
|
|||
[:div.element-set-title
|
||||
[:span
|
||||
(case type
|
||||
:multiple (t locale "workspace.options.shadow-options.title.multiple")
|
||||
:group (t locale "workspace.options.shadow-options.title.group")
|
||||
(t locale "workspace.options.shadow-options.title"))]
|
||||
:multiple (tr "workspace.options.shadow-options.title.multiple")
|
||||
:group (tr "workspace.options.shadow-options.title.group")
|
||||
(tr "workspace.options.shadow-options.title"))]
|
||||
|
||||
(when-not (= :multiple (:shadow values))
|
||||
[:div.add-page {:on-click on-add-shadow} i/close])]
|
||||
|
@ -220,14 +216,14 @@
|
|||
(= :multiple (:shadow values))
|
||||
[:div.element-set-content
|
||||
[:div.element-set-options-group
|
||||
[:div.element-set-label (t locale "settings.multiple")]
|
||||
[:div.element-set-label (tr "settings.multiple")]
|
||||
[:div.element-set-actions
|
||||
[:div.element-set-actions-button {:on-click on-remove-all-shadows}
|
||||
i/minus]]]]
|
||||
|
||||
(not (empty? (:shadow values)))
|
||||
(seq (:shadow values))
|
||||
[:div.element-set-content
|
||||
(for [[index {:keys [id] :as value}] (d/enumerate (:shadow values []))]
|
||||
(for [[index value] (d/enumerate (:shadow values []))]
|
||||
[:& shadow-entry {:key (str "shadow-" index)
|
||||
:ids ids
|
||||
:value value
|
||||
|
|
|
@ -6,21 +6,18 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.stroke
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.common.math :as math]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||
[app.util.data :refer [classnames]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr t]]
|
||||
[app.util.object :as obj]))
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def stroke-attrs
|
||||
[:stroke-style
|
||||
|
@ -47,11 +44,10 @@
|
|||
(mf/defc stroke-menu
|
||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type"]))]}
|
||||
[{:keys [ids type values] :as props}]
|
||||
(let [locale (i18n/use-locale)
|
||||
label (case type
|
||||
:multiple (t locale "workspace.options.selection-stroke")
|
||||
:group (t locale "workspace.options.group-stroke")
|
||||
(t locale "workspace.options.stroke"))
|
||||
(let [label (case type
|
||||
:multiple (tr "workspace.options.selection-stroke")
|
||||
:group (tr "workspace.options.group-stroke")
|
||||
(tr "workspace.options.stroke"))
|
||||
|
||||
show-options (not= (:stroke-style values :none) :none)
|
||||
|
||||
|
@ -65,7 +61,7 @@
|
|||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [color]
|
||||
(let [remove-multiple (fn [[key value]] (not= value :multiple))
|
||||
(let [remove-multiple (fn [[_ value]] (not= value :multiple))
|
||||
color (into {} (filter remove-multiple) color)]
|
||||
(st/emit! (dc/change-stroke ids color)))))
|
||||
|
||||
|
@ -99,7 +95,7 @@
|
|||
(st/emit! (dch/update-shapes ids #(assoc % :stroke-width value))))))
|
||||
|
||||
on-add-stroke
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (dch/update-shapes ids #(assoc %
|
||||
:stroke-style :solid
|
||||
:stroke-color "#000000"
|
||||
|
@ -107,19 +103,19 @@
|
|||
:stroke-width 1))))
|
||||
|
||||
on-del-stroke
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (dch/update-shapes ids #(assoc % :stroke-style :none))))
|
||||
|
||||
on-open-picker
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [value opacity id file-id]
|
||||
(fn [_value _opacity _id _file-id]
|
||||
(st/emit! (dwu/start-undo-transaction))))
|
||||
|
||||
on-close-picker
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [value opacity id file-id]
|
||||
(fn [_value _opacity _id _file-id]
|
||||
(st/emit! (dwu/commit-undo-transaction))))]
|
||||
|
||||
(if show-options
|
||||
|
@ -139,29 +135,29 @@
|
|||
;; Stroke Width, Alignment & Style
|
||||
[:div.row-flex
|
||||
[:div.input-element
|
||||
{:class (classnames :pixels (not= (:stroke-width values) :multiple))}
|
||||
{:class (dom/classnames :pixels (not= (:stroke-width values) :multiple))}
|
||||
[:input.input-text {:type "number"
|
||||
:min "0"
|
||||
:value (-> (:stroke-width values) width->string)
|
||||
:placeholder (t locale "settings.multiple")
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-change on-stroke-width-change}]]
|
||||
|
||||
[:select#style.input-select {:value (enum->string (:stroke-alignment values))
|
||||
:on-change on-stroke-alignment-change}
|
||||
(when (= (:stroke-alignment values) :multiple)
|
||||
[:option {:value ""} "--"])
|
||||
[:option {:value ":center"} (t locale "workspace.options.stroke.center")]
|
||||
[:option {:value ":inner"} (t locale "workspace.options.stroke.inner")]
|
||||
[:option {:value ":outer"} (t locale "workspace.options.stroke.outer")]]
|
||||
[:option {:value ":center"} (tr "workspace.options.stroke.center")]
|
||||
[:option {:value ":inner"} (tr "workspace.options.stroke.inner")]
|
||||
[:option {:value ":outer"} (tr "workspace.options.stroke.outer")]]
|
||||
|
||||
[:select#style.input-select {:value (enum->string (:stroke-style values))
|
||||
:on-change on-stroke-style-change}
|
||||
(when (= (:stroke-style values) :multiple)
|
||||
[:option {:value ""} "--"])
|
||||
[:option {:value ":solid"} (t locale "workspace.options.stroke.solid")]
|
||||
[:option {:value ":dotted"} (t locale "workspace.options.stroke.dotted")]
|
||||
[:option {:value ":dashed"} (t locale "workspace.options.stroke.dashed")]
|
||||
[:option {:value ":mixed"} (t locale "workspace.options.stroke.mixed")]]]]]
|
||||
[:option {:value ":solid"} (tr "workspace.options.stroke.solid")]
|
||||
[:option {:value ":dotted"} (tr "workspace.options.stroke.dotted")]
|
||||
[:option {:value ":dashed"} (tr "workspace.options.stroke.dashed")]
|
||||
[:option {:value ":mixed"} (tr "workspace.options.stroke.mixed")]]]]]
|
||||
|
||||
;; NO STROKE
|
||||
[:div.element-set
|
||||
|
|
|
@ -6,16 +6,14 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.svg-attrs
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[app.common.data :as d]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.icons :as i]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc attribute-value [{:keys [attr value on-change on-delete] :as props}]
|
||||
(let [handle-change
|
||||
|
@ -55,7 +53,7 @@
|
|||
:on-change on-change
|
||||
:on-delete on-delete}])])]))
|
||||
|
||||
(mf/defc svg-attrs-menu [{:keys [ids type values]}]
|
||||
(mf/defc svg-attrs-menu [{:keys [ids values]}]
|
||||
(let [handle-change
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
|
@ -86,7 +84,7 @@
|
|||
[:div.element-set-title
|
||||
[:span (tr "workspace.sidebar.options.svg-attrs.title")]]
|
||||
|
||||
(for [[index [attr-key attr-value]] (d/enumerate (:svg-attrs values))]
|
||||
(for [[attr-key attr-value] (:svg-attrs values)]
|
||||
[:& attribute-value {:key attr-key
|
||||
:attr [attr-key]
|
||||
:value attr-value
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
(ns app.main.ui.workspace.sidebar.options.menus.text
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.text :as txt]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
|
@ -81,10 +80,10 @@
|
|||
(def attrs (d/concat #{} shape-attrs root-attrs paragraph-attrs text-attrs))
|
||||
|
||||
(mf/defc text-align-options
|
||||
[{:keys [ids values on-change] :as props}]
|
||||
[{:keys [values on-change] :as props}]
|
||||
(let [{:keys [text-align]} values
|
||||
handle-change
|
||||
(fn [event new-align]
|
||||
(fn [_ new-align]
|
||||
(on-change {:text-align new-align}))]
|
||||
|
||||
;; --- Align
|
||||
|
@ -111,9 +110,9 @@
|
|||
i/text-align-justify]]))
|
||||
|
||||
(mf/defc text-direction-options
|
||||
[{:keys [ids values on-change] :as props}]
|
||||
[{:keys [values on-change] :as props}]
|
||||
(let [direction (:text-direction values)
|
||||
handle-change (fn [event val]
|
||||
handle-change (fn [_ val]
|
||||
(on-change {:text-direction val}))]
|
||||
;; --- Align
|
||||
[:div.align-icons
|
||||
|
@ -129,11 +128,11 @@
|
|||
i/text-direction-rtl]]))
|
||||
|
||||
(mf/defc vertical-align
|
||||
[{:keys [shapes ids values on-change] :as props}]
|
||||
[{:keys [values on-change] :as props}]
|
||||
(let [{:keys [vertical-align]} values
|
||||
vertical-align (or vertical-align "top")
|
||||
handle-change
|
||||
(fn [event new-align]
|
||||
(fn [_ new-align]
|
||||
(on-change {:vertical-align new-align}))]
|
||||
|
||||
[:div.align-icons
|
||||
|
@ -154,11 +153,10 @@
|
|||
i/align-bottom]]))
|
||||
|
||||
(mf/defc grow-options
|
||||
[{:keys [ids values on-change] :as props}]
|
||||
(let [to-single-value (fn [coll] (if (> (count coll) 1) nil (first coll)))
|
||||
grow-type (->> values :grow-type)
|
||||
[{:keys [ids values] :as props}]
|
||||
(let [grow-type (:grow-type values)
|
||||
handle-change-grow
|
||||
(fn [event grow-type]
|
||||
(fn [_ grow-type]
|
||||
(st/emit! (dch/update-shapes ids #(assoc % :grow-type grow-type))))]
|
||||
|
||||
[:div.align-icons
|
||||
|
@ -179,13 +177,10 @@
|
|||
i/auto-height]]))
|
||||
|
||||
(mf/defc text-decoration-options
|
||||
[{:keys [ids values on-change] :as props}]
|
||||
(let [{:keys [text-decoration]} values
|
||||
|
||||
text-decoration (or text-decoration "none")
|
||||
|
||||
[{:keys [values on-change] :as props}]
|
||||
(let [text-decoration (or (:text-decoration values) "none")
|
||||
handle-change
|
||||
(fn [event type]
|
||||
(fn [_ type]
|
||||
(on-change {:text-decoration type}))]
|
||||
[:div.align-icons
|
||||
[:span.tooltip.tooltip-bottom
|
||||
|
@ -262,18 +257,18 @@
|
|||
(get typographies (:typography-ref-id values)))))
|
||||
|
||||
on-convert-to-typography
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(let [setted-values (-> (d/without-nils values)
|
||||
(select-keys
|
||||
(d/concat text-font-attrs
|
||||
text-spacing-attrs
|
||||
text-transform-attrs)))
|
||||
typography (merge txt/default-typography setted-values)
|
||||
typography (generate-typography-name typography)]
|
||||
(let [id (uuid/next)]
|
||||
(st/emit! (dwl/add-typography (assoc typography :id id) false))
|
||||
(run! #(emit-update! % {:typography-ref-id id
|
||||
:typography-ref-file file-id}) ids))))
|
||||
typography (generate-typography-name typography)
|
||||
id (uuid/next)]
|
||||
(st/emit! (dwl/add-typography (assoc typography :id id) false))
|
||||
(run! #(emit-update! % {:typography-ref-id id
|
||||
:typography-ref-file file-id}) ids)))
|
||||
|
||||
handle-detach-typography
|
||||
(mf/use-callback
|
||||
|
|
|
@ -7,30 +7,24 @@
|
|||
(ns app.main.ui.workspace.sidebar.options.menus.typography
|
||||
(:require
|
||||
["react-virtualized" :as rvt]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.data :as d]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.text :as txt]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.shortcuts :as dsc]
|
||||
[app.main.data.fonts :as df]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.components.editable-select :refer [editable-select]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.common :refer [advanced-options]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.object :as obj]
|
||||
[app.util.timers :as tm]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
[app.util.router :as rt]
|
||||
[app.util.timers :as ts]
|
||||
[goog.events :as events]
|
||||
[app.util.timers :as tm]
|
||||
[cuerdas.core :as str]
|
||||
[goog.events :as events]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(defn- attr->string [value]
|
||||
|
@ -88,11 +82,11 @@
|
|||
(comp (filter #(contains? backends (:backend %)))))]
|
||||
(into [] xform fonts)))
|
||||
|
||||
(defn- toggle-backend
|
||||
[backends id]
|
||||
(if (contains? backends id)
|
||||
(disj backends id)
|
||||
(conj backends id)))
|
||||
;; (defn- toggle-backend
|
||||
;; [backends id]
|
||||
;; (if (contains? backends id)
|
||||
;; (disj backends id)
|
||||
;; (conj backends id)))
|
||||
|
||||
(mf/defc font-selector
|
||||
[{:keys [on-select on-close current-font] :as props}]
|
||||
|
@ -101,7 +95,6 @@
|
|||
|
||||
flist (mf/use-ref)
|
||||
input (mf/use-ref)
|
||||
ddown (mf/use-ref)
|
||||
|
||||
fonts (mf/use-memo (mf/deps @state) #(filter-fonts @state @fonts/fonts))
|
||||
|
||||
|
@ -237,7 +230,7 @@
|
|||
:current? (= (:id font) (:id selected))}])))
|
||||
|
||||
(mf/defc font-options
|
||||
[{:keys [editor ids values on-change] :as props}]
|
||||
[{:keys [values on-change] :as props}]
|
||||
(let [{:keys [font-id font-size font-variant-id]} values
|
||||
|
||||
font-id (or font-id (:font-id txt/default-text-attrs))
|
||||
|
@ -261,15 +254,6 @@
|
|||
:font-weight weight
|
||||
:font-style style}))))
|
||||
|
||||
on-font-family-change
|
||||
(mf/use-callback
|
||||
(mf/deps fonts change-font)
|
||||
(fn [event]
|
||||
(let [new-font-id (dom/get-target-val event)]
|
||||
(when-not (str/empty? new-font-id)
|
||||
(let [font (get fonts new-font-id)]
|
||||
(fonts/ensure-loaded! new-font-id (partial change-font new-font-id)))))))
|
||||
|
||||
on-font-size-change
|
||||
(mf/use-callback
|
||||
(mf/deps on-change)
|
||||
|
@ -345,7 +329,7 @@
|
|||
|
||||
|
||||
(mf/defc spacing-options
|
||||
[{:keys [editor ids values on-change] :as props}]
|
||||
[{:keys [values on-change] :as props}]
|
||||
(let [{:keys [line-height
|
||||
letter-spacing]} values
|
||||
|
||||
|
@ -385,13 +369,10 @@
|
|||
:on-change #(handle-change % :letter-spacing)}]]]))
|
||||
|
||||
(mf/defc text-transform-options
|
||||
[{:keys [editor ids values on-change] :as props}]
|
||||
(let [{:keys [text-transform]} values
|
||||
|
||||
text-transform (or text-transform "none")
|
||||
|
||||
[{:keys [values on-change] :as props}]
|
||||
(let [text-transform (or (:text-transform values) "none")
|
||||
handle-change
|
||||
(fn [event type]
|
||||
(fn [_ type]
|
||||
(on-change {:text-transform type}))]
|
||||
[:div.align-icons
|
||||
[:span.tooltip.tooltip-bottom
|
||||
|
@ -461,7 +442,7 @@
|
|||
(mf/deps focus-name?)
|
||||
(fn []
|
||||
(when focus-name?
|
||||
(ts/schedule
|
||||
(tm/schedule
|
||||
#(when-let [node (mf/ref-val name-input-ref)]
|
||||
(dom/focus! node)
|
||||
(dom/select-text! node))))))
|
||||
|
@ -539,7 +520,7 @@
|
|||
:ref name-input-ref
|
||||
:default-value (cp/merge-path-item (:path typography) (:name typography))
|
||||
:on-blur on-name-blur}]
|
||||
|
||||
|
||||
[:div.element-set-actions-button
|
||||
{:on-click #(reset! open? false)}
|
||||
i/actions]]]
|
||||
|
|
|
@ -6,12 +6,10 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.rows.input-row
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.main.ui.components.editable-select :refer [editable-select]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
[app.main.ui.components.editable-select :refer [editable-select]]
|
||||
[app.util.dom :as dom]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc input-row [{:keys [label options value class min max on-change type placeholder]}]
|
||||
[:div.row-flex.input-row
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.circle
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
|
|
|
@ -6,23 +6,22 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.frame
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.util.dom :as dom]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[app.common.math :as math]
|
||||
[app.main.store :as st]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(declare +size-presets+)
|
||||
|
||||
|
@ -50,7 +49,7 @@
|
|||
(st/emit! (udw/update-dimensions [(:id shape)] attr value)))
|
||||
|
||||
on-proportion-lock-change
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (udw/set-shape-proportion-lock (:id shape) (not (:proportion-lock shape)))))
|
||||
|
||||
on-position-change
|
||||
|
@ -82,8 +81,8 @@
|
|||
:on-click #(on-preset-selected (:width size-preset) (:height size-preset))}
|
||||
(:name size-preset)
|
||||
[:span (:width size-preset) " x " (:height size-preset)]]))]]]
|
||||
[:span.orientation-icon {on-click #(on-orientation-clicked :vert)} i/size-vert]
|
||||
[:span.orientation-icon {on-click #(on-orientation-clicked :horiz)} i/size-horiz]]
|
||||
[:span.orientation-icon {:on-click #(on-orientation-clicked :vert)} i/size-vert]
|
||||
[:span.orientation-icon {:on-click #(on-orientation-clicked :horiz)} i/size-horiz]]
|
||||
|
||||
;; WIDTH & HEIGHT
|
||||
[:div.row-flex
|
||||
|
|
|
@ -6,18 +6,18 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.group
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.text :as ot]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.multiple :refer [get-attrs]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.image
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
:else (attrs/get-attrs-multi [v1 v2] attrs)))
|
||||
|
||||
extract-attrs
|
||||
(fn [[ids values] {:keys [id type shapes content] :as shape}]
|
||||
(fn [[ids values] {:keys [id type content] :as shape}]
|
||||
(let [props (get-in type->props [type attr-type])]
|
||||
(case props
|
||||
:ignore [ids values]
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.path
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.data :as d]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.rect
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.layer :refer [layer-attrs layer-menu]]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]}
|
||||
|
|
|
@ -6,22 +6,23 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.svg-raw
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[app.util.data :as d]
|
||||
[app.util.color :as uc]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]))
|
||||
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.measures :refer [measure-attrs measures-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.shadow :refer [shadow-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.stroke :refer [stroke-attrs stroke-menu]]
|
||||
[app.main.ui.workspace.sidebar.options.menus.svg-attrs :refer [svg-attrs-menu]]
|
||||
[app.util.color :as uc]
|
||||
[app.util.data :as d]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
;; This is a list of svg tags that can be grouped in shape-container
|
||||
;; this allows them to have gradients, shadows and masks
|
||||
(def svg-elements #{:svg :g :circle :ellipse :image :line :path :polygon :polyline :rect :symbol :text :textPath})
|
||||
|
||||
(defn hex->number [hex] 1)
|
||||
(defn hex->number [_] 1)
|
||||
|
||||
(defn shorthex->longhex [hex]
|
||||
(let [[_ r g b] hex]
|
||||
(str "#" r r g g b b)))
|
||||
|
@ -45,10 +46,10 @@
|
|||
|
||||
|
||||
(defn get-fill-values [shape]
|
||||
(let [fill-values (or (select-keys shape fill-attrs))
|
||||
color (-> (or (get-in shape [:content :attrs :fill])
|
||||
(get-in shape [:content :attrs :style :fill]))
|
||||
(parse-color))
|
||||
(let [fill-values (select-keys shape fill-attrs)
|
||||
color (-> (or (get-in shape [:content :attrs :fill])
|
||||
(get-in shape [:content :attrs :style :fill]))
|
||||
(parse-color))
|
||||
|
||||
fill-values (if (and (empty? fill-values) color)
|
||||
{:fill-color (:color color)
|
||||
|
@ -57,10 +58,10 @@
|
|||
fill-values))
|
||||
|
||||
(defn get-stroke-values [shape]
|
||||
(let [stroke-values (or (select-keys shape stroke-attrs))
|
||||
color (-> (or (get-in shape [:content :attrs :stroke])
|
||||
(get-in shape [:content :attrs :style :stroke]))
|
||||
(parse-color))
|
||||
(let [stroke-values (select-keys shape stroke-attrs)
|
||||
color (-> (or (get-in shape [:content :attrs :stroke])
|
||||
(get-in shape [:content :attrs :style :stroke]))
|
||||
(parse-color))
|
||||
|
||||
stroke-color (:color color "#000000")
|
||||
stroke-opacity (:opacity color 1)
|
||||
|
@ -90,7 +91,7 @@
|
|||
|
||||
(let [ids [(:id shape)]
|
||||
type (:type shape)
|
||||
{:keys [tag attrs] :as content} (:content shape)
|
||||
{:keys [tag] :as content} (:content shape)
|
||||
measure-values (select-keys shape measure-attrs)
|
||||
fill-values (get-fill-values shape)
|
||||
stroke-values (get-stroke-values shape)]
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.router :as rt]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
|
@ -86,12 +84,12 @@
|
|||
on-drop
|
||||
(mf/use-callback
|
||||
(mf/deps id)
|
||||
(fn [side {:keys [id name] :as data}]
|
||||
(fn [side {:keys [id] :as data}]
|
||||
(let [index (if (= :bot side) (inc index) index)]
|
||||
(st/emit! (dw/relocate-page id index)))))
|
||||
|
||||
on-duplicate
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (dw/duplicate-page id)))
|
||||
|
||||
[dprops dref]
|
||||
|
@ -169,7 +167,7 @@
|
|||
st/state =))
|
||||
|
||||
(mf/defc page-item-wrapper
|
||||
[{:keys [file-id page-id index deletable? selected?] :as props}]
|
||||
[{:keys [page-id index deletable? selected?] :as props}]
|
||||
(let [page-ref (mf/use-memo (mf/deps page-id) #(make-page-ref page-id))
|
||||
page (mf/deref page-ref)]
|
||||
[:& page-item {:page page
|
||||
|
@ -197,7 +195,7 @@
|
|||
;; --- Sitemap Toolbox
|
||||
|
||||
(mf/defc sitemap
|
||||
[{:keys [layout] :as props}]
|
||||
[]
|
||||
(let [file (mf/deref refs/workspace-file)
|
||||
create (mf/use-callback
|
||||
(mf/deps file)
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
(ns app.main.ui.workspace.viewport
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.context :as muc]
|
||||
[app.main.ui.measurements :as msr]
|
||||
[app.main.ui.shapes.embed :as embed]
|
||||
[app.main.ui.shapes.export :as use]
|
||||
|
@ -79,7 +77,6 @@
|
|||
|
||||
;; REFS
|
||||
viewport-ref (mf/use-ref nil)
|
||||
zoom-view-ref (mf/use-ref nil)
|
||||
render-ref (mf/use-ref nil)
|
||||
|
||||
;; VARS
|
||||
|
@ -139,7 +136,9 @@
|
|||
show-presence? page-id
|
||||
show-prototypes? (= options-mode :prototype)
|
||||
show-selection-handlers? (seq selected)
|
||||
show-snap-distance? (and (contains? layout :dynamic-alignment) (= transform :move) (not (empty? selected)))
|
||||
show-snap-distance? (and (contains? layout :dynamic-alignment)
|
||||
(= transform :move)
|
||||
(seq selected))
|
||||
show-snap-points? (and (or (contains? layout :dynamic-alignment)
|
||||
(contains? layout :snap-grid))
|
||||
(or drawing-obj transform))
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.drawing :as dd]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.path :as dwdp]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.main.ui.workspace.viewport.utils :as utils]
|
||||
[app.main.data.workspace.path :as dwdp]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.dom.dnd :as dnd]
|
||||
[app.util.keyboard :as kbd]
|
||||
|
@ -290,8 +290,7 @@
|
|||
(st/emit! (ms/->KeyboardEvent :up key shift? ctrl? alt? meta?))))))
|
||||
|
||||
(defn on-mouse-move [viewport-ref zoom]
|
||||
(let [last-position (mf/use-var nil)
|
||||
viewport (mf/ref-val viewport-ref)]
|
||||
(let [last-position (mf/use-var nil)]
|
||||
(mf/use-callback
|
||||
(mf/deps zoom)
|
||||
(fn [event]
|
||||
|
@ -477,7 +476,7 @@
|
|||
|
||||
(defn on-resize [viewport-ref]
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(let [node (mf/ref-val viewport-ref)
|
||||
prnt (dom/get-parent node)
|
||||
size (dom/get-client-size prnt)]
|
||||
|
|
|
@ -7,17 +7,12 @@
|
|||
(ns app.main.ui.workspace.viewport.drawarea
|
||||
"Drawing components."
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.drawing :as dd]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.workspace.shapes :as shapes]
|
||||
[app.main.ui.shapes.path :refer [path-shape]]
|
||||
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.data :as d]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [t]]))
|
||||
[app.common.math :as mth]
|
||||
[app.main.ui.shapes.path :refer [path-shape]]
|
||||
[app.main.ui.workspace.shapes :as shapes]
|
||||
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(declare generic-draw-area)
|
||||
(declare path-draw-area)
|
||||
|
@ -38,8 +33,8 @@
|
|||
[{:keys [shape zoom]}]
|
||||
(let [{:keys [x y width height]} (:selrect (gsh/transform-shape shape))]
|
||||
(when (and x y
|
||||
(not (d/nan? x))
|
||||
(not (d/nan? y)))
|
||||
(not (mth/nan? x))
|
||||
(not (mth/nan? y)))
|
||||
|
||||
[:rect.main {:x x :y y
|
||||
:width width
|
||||
|
|
|
@ -6,18 +6,17 @@
|
|||
|
||||
(ns app.main.ui.workspace.viewport.frame-grid
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[okulary.core :as l]
|
||||
[app.main.refs :as refs]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.refs :as refs]
|
||||
[app.util.geom.grid :as gg]
|
||||
[app.common.uuid :as uuid]))
|
||||
[okulary.core :as l]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc square-grid [{:keys [frame zoom grid] :as props}]
|
||||
(let [grid-id (mf/use-memo #(uuid/next))
|
||||
{:keys [color size] :as params} (-> grid :params)
|
||||
{:keys [size] :as params} (-> grid :params)
|
||||
{color-value :color color-opacity :opacity} (-> grid :params :color)
|
||||
;; Support for old color format
|
||||
color-value (or color-value (:value (get-in grid [:params :color :value])))]
|
||||
|
@ -43,7 +42,7 @@
|
|||
:height (:height frame)
|
||||
:fill (str "url(#" grid-id ")")}]]))
|
||||
|
||||
(mf/defc layout-grid [{:keys [key frame zoom grid]}]
|
||||
(mf/defc layout-grid [{:keys [key frame grid]}]
|
||||
(let [{color-value :color color-opacity :opacity} (-> grid :params :color)
|
||||
;; Support for old color format
|
||||
color-value (or color-value (:value (get-in grid [:params :color :value])))
|
||||
|
|
|
@ -7,21 +7,19 @@
|
|||
(ns app.main.ui.workspace.viewport.gradients
|
||||
"Gradients handlers and renders"
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[cuerdas.core :as str]
|
||||
[beicon.core :as rx]
|
||||
[okulary.core :as l]
|
||||
[app.common.math :as mth]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.util.dom :as dom]
|
||||
[app.main.store :as st]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.colors :as dc]))
|
||||
[app.util.dom :as dom]
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(def gradient-line-stroke-width 2)
|
||||
(def gradient-line-stroke-color "white")
|
||||
|
@ -94,7 +92,7 @@
|
|||
on-click on-mouse-down on-mouse-up]}]
|
||||
[:g {:filter (str/fmt "url(#%s)" filter-id)
|
||||
:transform (gmt/rotate-matrix angle point)}
|
||||
|
||||
|
||||
[:image {:href checkboard
|
||||
:x (- (:x point) (/ gradient-square-width 2 zoom))
|
||||
:y (- (:y point) (/ gradient-square-width 2 zoom))
|
||||
|
@ -127,7 +125,7 @@
|
|||
|
||||
(mf/defc gradient-handler-transformed
|
||||
[{:keys [from-p to-p width-p from-color to-color zoom editing
|
||||
on-change-start on-change-finish on-change-width on-change-stop-color]}]
|
||||
on-change-start on-change-finish on-change-width]}]
|
||||
(let [moving-point (mf/use-var nil)
|
||||
angle (+ 90 (gpt/angle from-p to-p))
|
||||
|
||||
|
@ -138,7 +136,7 @@
|
|||
(st/emit! (dc/select-gradient-stop (case position
|
||||
:from-p 0
|
||||
:to-p 1)))))
|
||||
|
||||
|
||||
on-mouse-down (fn [position event]
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
|
@ -148,7 +146,7 @@
|
|||
:from-p 0
|
||||
:to-p 1)))))
|
||||
|
||||
on-mouse-up (fn [position event]
|
||||
on-mouse-up (fn [_position event]
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
(reset! moving-point nil))]
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
(mf/deps on-key-down on-key-up on-mouse-move on-mouse-wheel on-resize on-paste)
|
||||
(fn []
|
||||
(let [node (mf/ref-val viewport-ref)
|
||||
prnt (dom/get-parent node)
|
||||
|
||||
keys [(events/listen js/document EventType.KEYDOWN on-key-down)
|
||||
(events/listen js/document EventType.KEYUP on-key-up)
|
||||
(events/listen node EventType.MOUSEMOVE on-mouse-move)
|
||||
|
@ -90,7 +88,8 @@
|
|||
(hooks/use-stream ms/keyboard-alt #(reset! alt? %))
|
||||
(hooks/use-stream ms/keyboard-ctrl #(reset! ctrl? %)))
|
||||
|
||||
(defn setup-hover-shapes [page-id move-stream selected objects transform selected ctrl? hover hover-ids zoom]
|
||||
;; TODO: revisit the arguments, looks like `selected` is not necessary here
|
||||
(defn setup-hover-shapes [page-id move-stream _selected objects transform selected ctrl? hover hover-ids zoom]
|
||||
(let [query-point
|
||||
(mf/use-callback
|
||||
(mf/deps page-id)
|
||||
|
@ -111,12 +110,7 @@
|
|||
;; When transforming shapes we stop querying the worker
|
||||
(rx/filter #(not (some? (mf/ref-val transform-ref))))
|
||||
(rx/switch-map query-point))
|
||||
|
||||
roots (mf/use-memo
|
||||
(mf/deps selected objects)
|
||||
(fn []
|
||||
(let [roots-ids (cp/clean-loops objects selected)]
|
||||
(->> roots-ids (mapv #(get objects %))))))]
|
||||
]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps transform)
|
||||
|
|
|
@ -7,15 +7,11 @@
|
|||
(ns app.main.ui.workspace.viewport.interactions
|
||||
"Visually show shape interactions in workspace"
|
||||
(:require
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as geom]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.workspace.viewport.outline :refer [outline]]
|
||||
[app.util.data :as dt]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]
|
||||
))
|
||||
|
@ -24,14 +20,11 @@
|
|||
[shape]
|
||||
(first (filter #(= (:event-type %) :click) (:interactions shape))))
|
||||
|
||||
|
||||
(defn- on-mouse-down
|
||||
[event {:keys [id type] :as shape} selected]
|
||||
(do
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dw/select-shape id))
|
||||
(st/emit! (dw/start-create-interaction))))
|
||||
|
||||
[event {:keys [id] :as shape}]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dw/select-shape id))
|
||||
(st/emit! (dw/start-create-interaction)))
|
||||
|
||||
(defn connect-to-shape
|
||||
"Calculate the best position to draw an interaction line
|
||||
|
@ -118,7 +111,7 @@
|
|||
|
||||
|
||||
(mf/defc interaction-path
|
||||
[{:keys [orig-shape dest-shape dest-point selected selected? zoom] :as props}]
|
||||
[{:keys [orig-shape dest-shape dest-point selected? zoom] :as props}]
|
||||
(let [[orig-pos orig-x orig-y dest-pos dest-x dest-y]
|
||||
(if dest-shape
|
||||
(connect-to-shape orig-shape dest-shape)
|
||||
|
@ -138,9 +131,9 @@
|
|||
:pointer-events "visible"
|
||||
:stroke-width (/ 2 zoom)
|
||||
:d pdata
|
||||
:on-mouse-down #(on-mouse-down % orig-shape selected)}]
|
||||
:on-mouse-down #(on-mouse-down % orig-shape)}]
|
||||
|
||||
[:g {:on-mouse-down #(on-mouse-down % orig-shape selected)}
|
||||
[:g {:on-mouse-down #(on-mouse-down % orig-shape)}
|
||||
[:path {:stroke "#31EFB8"
|
||||
:fill "none"
|
||||
:pointer-events "visible"
|
||||
|
@ -161,11 +154,11 @@
|
|||
|
||||
|
||||
(mf/defc interaction-handle
|
||||
[{:keys [shape selected zoom] :as props}]
|
||||
[{:keys [shape zoom] :as props}]
|
||||
(let [shape-rect (:selrect shape)
|
||||
handle-x (+ (:x shape-rect) (:width shape-rect))
|
||||
handle-y (+ (:y shape-rect) (/ (:height shape-rect) 2))]
|
||||
[:g {:on-mouse-down #(on-mouse-down % shape selected)}
|
||||
[:g {:on-mouse-down #(on-mouse-down % shape)}
|
||||
[:& interaction-marker {:x handle-x
|
||||
:y handle-y
|
||||
:arrow-dir :right
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.refs :as refs]
|
||||
[app.util.path.format :as upf]
|
||||
[app.util.object :as obj]
|
||||
[app.util.path.format :as upf]
|
||||
[clojure.set :as set]
|
||||
[rumext.alpha :as mf]
|
||||
[rumext.util :refer [map->obj]]))
|
||||
|
@ -29,7 +29,7 @@
|
|||
(mf/deps shape)
|
||||
#(when path? (upf/format-path (:content shape))))
|
||||
|
||||
{:keys [id x y width height selrect]} shape
|
||||
{:keys [x y width height selrect]} shape
|
||||
|
||||
outline-type (case (:type shape)
|
||||
:circle "ellipse"
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
(ns app.main.ui.workspace.viewport.path-actions
|
||||
(:require
|
||||
[app.main.data.workspace.path :as drp]
|
||||
[app.main.data.workspace.path.helpers :as wph]
|
||||
[app.main.data.workspace.path.shortcuts :as sc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.shapes.path.common :as pc]
|
||||
|
@ -20,8 +18,8 @@
|
|||
(defn check-enabled [content selected-points]
|
||||
(let [segments (upt/get-segments content selected-points)
|
||||
num-points (count selected-points)
|
||||
points-selected? (not (empty? selected-points))
|
||||
segments-selected? (not (empty? segments))]
|
||||
points-selected? (seq selected-points)
|
||||
segments-selected? (seq segments)]
|
||||
{:make-corner points-selected?
|
||||
:make-curve points-selected?
|
||||
:add-node segments-selected?
|
||||
|
@ -31,8 +29,7 @@
|
|||
:separate-nodes segments-selected?}))
|
||||
|
||||
(mf/defc path-actions [{:keys [shape]}]
|
||||
(let [id (mf/deref refs/selected-edition)
|
||||
{:keys [edit-mode selected-points snap-toggled] :as all} (mf/deref pc/current-edit-path-ref)
|
||||
(let [{:keys [edit-mode selected-points snap-toggled] :as all} (mf/deref pc/current-edit-path-ref)
|
||||
content (:content shape)
|
||||
|
||||
enabled-buttons
|
||||
|
@ -42,66 +39,66 @@
|
|||
|
||||
on-select-draw-mode
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (drp/change-edit-mode :draw))))
|
||||
|
||||
|
||||
on-select-edit-mode
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (drp/change-edit-mode :move))))
|
||||
|
||||
|
||||
on-add-node
|
||||
(mf/use-callback
|
||||
(mf/deps (:add-node enabled-buttons))
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when (:add-node enabled-buttons)
|
||||
(st/emit! (drp/add-node)))))
|
||||
|
||||
|
||||
on-remove-node
|
||||
(mf/use-callback
|
||||
(mf/deps (:remove-node enabled-buttons))
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when (:remove-node enabled-buttons)
|
||||
(st/emit! (drp/remove-node)))))
|
||||
|
||||
|
||||
on-merge-nodes
|
||||
(mf/use-callback
|
||||
(mf/deps (:merge-nodes enabled-buttons))
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when (:merge-nodes enabled-buttons)
|
||||
(st/emit! (drp/merge-nodes)))))
|
||||
|
||||
|
||||
on-join-nodes
|
||||
(mf/use-callback
|
||||
(mf/deps (:join-nodes enabled-buttons))
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when (:join-nodes enabled-buttons)
|
||||
(st/emit! (drp/join-nodes)))))
|
||||
|
||||
|
||||
on-separate-nodes
|
||||
(mf/use-callback
|
||||
(mf/deps (:separate-nodes enabled-buttons))
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when (:separate-nodes enabled-buttons)
|
||||
(st/emit! (drp/separate-nodes)))))
|
||||
|
||||
on-make-corner
|
||||
(mf/use-callback
|
||||
(mf/deps (:make-corner enabled-buttons))
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when (:make-corner enabled-buttons)
|
||||
(st/emit! (drp/make-corner)))))
|
||||
|
||||
|
||||
on-make-curve
|
||||
(mf/use-callback
|
||||
(mf/deps (:make-curve enabled-buttons))
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(when (:make-curve enabled-buttons)
|
||||
(st/emit! (drp/make-curve)))))
|
||||
|
||||
on-toggle-snap
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(st/emit! (drp/toggle-snap))))
|
||||
|
||||
]
|
||||
|
@ -121,7 +118,7 @@
|
|||
:alt (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes))
|
||||
:on-click on-select-edit-mode}
|
||||
i/pointer-inner]]
|
||||
|
||||
|
||||
[:div.viewport-actions-group
|
||||
;; Add Node
|
||||
[:div.viewport-actions-entry.tooltip.tooltip-bottom
|
||||
|
|
|
@ -7,21 +7,18 @@
|
|||
(ns app.main.ui.workspace.viewport.pixel-overlay
|
||||
(:require
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.colors :as dwc]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.colors :as dwc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.context :as muc]
|
||||
[app.main.ui.cursors :as cur]
|
||||
[app.main.ui.workspace.shapes :refer [shape-wrapper frame-wrapper]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
[app.util.timers :as timers]
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[goog.events :as events]
|
||||
[okulary.core :as l]
|
||||
[promesa.core :as p]
|
||||
[rumext.alpha :as mf])
|
||||
(:import goog.events.EventType))
|
||||
|
@ -54,11 +51,8 @@
|
|||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [vport (unchecked-get props "vport")
|
||||
vbox (unchecked-get props "vbox")
|
||||
viewport-ref (unchecked-get props "viewport-ref")
|
||||
viewport-node (mf/ref-val viewport-ref)
|
||||
options (unchecked-get props "options")
|
||||
svg-ref (mf/use-ref nil)
|
||||
canvas-ref (mf/use-ref nil)
|
||||
img-ref (mf/use-ref nil)
|
||||
|
||||
|
@ -67,11 +61,11 @@
|
|||
handle-keydown
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(when (and (kbd/esc? event))
|
||||
(do (dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
(st/emit! (dwc/stop-picker))
|
||||
(modal/disallow-click-outside!)))))
|
||||
(when (kbd/esc? event)
|
||||
(dom/stop-propagation event)
|
||||
(dom/prevent-default event)
|
||||
(st/emit! (dwc/stop-picker))
|
||||
(modal/disallow-click-outside!))))
|
||||
|
||||
handle-mouse-move-picker
|
||||
(mf/use-callback
|
||||
|
|
|
@ -10,23 +10,15 @@
|
|||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as geom]
|
||||
[app.common.math :as mth]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.main.ui.cursors :as cur]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
|
||||
[app.util.data :as d]
|
||||
[app.util.debug :refer [debug?]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.object :as obj]
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]
|
||||
[rumext.alpha :as mf]
|
||||
[rumext.util :refer [map->obj]]))
|
||||
|
||||
|
@ -178,17 +170,12 @@
|
|||
:cursor cursor}
|
||||
:on-mouse-down #(on-resize {:x cx' :y cy'} %)}])
|
||||
|
||||
(let [rot-square (case position
|
||||
:top-left 0
|
||||
:top-right 90
|
||||
:bottom-right 180
|
||||
:bottom-left 270)]
|
||||
[:circle {:on-mouse-down #(on-resize {:x cx' :y cy'} %)
|
||||
:r (/ resize-point-circle-radius zoom)
|
||||
:cx cx'
|
||||
:cy cy'
|
||||
:style {:fill (if (debug? :resize-handler) "red" "none")
|
||||
:cursor cursor}}])
|
||||
[:circle {:on-mouse-down #(on-resize {:x cx' :y cy'} %)
|
||||
:r (/ resize-point-circle-radius zoom)
|
||||
:cx cx'
|
||||
:cy cy'
|
||||
:style {:fill (if (debug? :resize-handler) "red" "none")
|
||||
:cursor cursor}}]
|
||||
)]))
|
||||
|
||||
(mf/defc resize-side-handler
|
||||
|
@ -232,7 +219,7 @@
|
|||
(mf/defc controls
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [{:keys [overflow-text type] :as shape} (obj/get props "shape")
|
||||
(let [{:keys [overflow-text] :as shape} (obj/get props "shape")
|
||||
zoom (obj/get props "zoom")
|
||||
color (obj/get props "color")
|
||||
on-move-selected (obj/get props "on-move-selected")
|
||||
|
@ -275,7 +262,7 @@
|
|||
;; TODO: add specs for clarity
|
||||
|
||||
(mf/defc text-edition-selection-handlers
|
||||
[{:keys [shape zoom color] :as props}]
|
||||
[{:keys [shape color] :as props}]
|
||||
(let [{:keys [x y width height]} shape]
|
||||
[:g.controls
|
||||
[:rect.main {:x x :y y
|
||||
|
@ -299,12 +286,6 @@
|
|||
|
||||
shape-center (geom/center-shape shape)
|
||||
|
||||
hover-id (-> (mf/deref refs/current-hover) first)
|
||||
hover-id (when-not (d/seek #(= hover-id (:id %)) shapes) hover-id)
|
||||
hover-shape (mf/deref (refs/object-by-id hover-id))
|
||||
|
||||
vbox (mf/deref refs/vbox)
|
||||
|
||||
on-resize (fn [current-position initial-position event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dw/start-resize current-position initial-position selected shape)))
|
||||
|
@ -329,14 +310,6 @@
|
|||
(let [shape-id (:id shape)
|
||||
shape (geom/transform-shape shape {:round-coords? false})
|
||||
|
||||
frame (mf/deref (refs/object-by-id (:frame-id shape)))
|
||||
frame (when-not (= (:id frame) uuid/zero) frame)
|
||||
vbox (mf/deref refs/vbox)
|
||||
|
||||
hover-id (-> (mf/deref refs/current-hover) first)
|
||||
hover-id (when-not (= shape-id hover-id) hover-id)
|
||||
hover-shape (mf/deref (refs/object-by-id hover-id))
|
||||
|
||||
shape' (if (debug? :simple-selection) (geom/setup {:type :rect} (geom/selection-rect [shape])) shape)
|
||||
on-resize (fn [current-position initial-position event]
|
||||
(dom/stop-propagation event)
|
||||
|
@ -357,7 +330,7 @@
|
|||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [shapes selected edition zoom disable-handlers on-move-selected] :as props}]
|
||||
(let [num (count shapes)
|
||||
{:keys [id type] :as shape} (first shapes)
|
||||
{:keys [type] :as shape} (first shapes)
|
||||
|
||||
color (if (or (> num 1) (nil? (:shape-ref shape)))
|
||||
selection-rect-color-normal
|
||||
|
|
|
@ -7,15 +7,11 @@
|
|||
(ns app.main.ui.workspace.viewport.snap-distances
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.snap :as snap]
|
||||
[app.main.worker :as uw]
|
||||
[app.util.geom.snap-points :as sp]
|
||||
[beicon.core :as rx]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]
|
||||
|
@ -275,21 +271,20 @@
|
|||
|
||||
update-shape (fn [shape] (-> shape
|
||||
(update :modifiers merge (:modifiers local))
|
||||
gsh/transform-shape))]
|
||||
(let [selrect (->> selected-shapes (map update-shape) gsh/selection-rect)
|
||||
key (->> selected (map str) (str/join "-"))]
|
||||
[:g.distance
|
||||
[:& shape-distance
|
||||
{:selrect selrect
|
||||
:page-id page-id
|
||||
:frame frame
|
||||
:zoom zoom
|
||||
:coord :x
|
||||
:selected selected}]
|
||||
[:& shape-distance
|
||||
{:selrect selrect
|
||||
:page-id page-id
|
||||
:frame frame
|
||||
:zoom zoom
|
||||
:coord :y
|
||||
:selected selected}]])))
|
||||
gsh/transform-shape))
|
||||
selrect (->> selected-shapes (map update-shape) gsh/selection-rect)]
|
||||
[:g.distance
|
||||
[:& shape-distance
|
||||
{:selrect selrect
|
||||
:page-id page-id
|
||||
:frame frame
|
||||
:zoom zoom
|
||||
:coord :x
|
||||
:selected selected}]
|
||||
[:& shape-distance
|
||||
{:selrect selrect
|
||||
:page-id page-id
|
||||
:frame frame
|
||||
:zoom zoom
|
||||
:coord :y
|
||||
:selected selected}]]))
|
||||
|
|
|
@ -6,12 +6,10 @@
|
|||
|
||||
(ns app.main.ui.workspace.viewport.snap-points
|
||||
(:require
|
||||
[app.common.pages :as cp]
|
||||
[app.common.math :as mth]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.refs :as refs]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.snap :as snap]
|
||||
[app.util.geom.snap-points :as sp]
|
||||
[beicon.core :as rx]
|
||||
|
@ -106,7 +104,7 @@
|
|||
(hash-map coord fixedv (flip coord) maxv)]))))
|
||||
|
||||
(mf/defc snap-feedback
|
||||
[{:keys [shapes page-id filter-shapes zoom modifiers] :as props}]
|
||||
[{:keys [shapes filter-shapes zoom modifiers] :as props}]
|
||||
(let [state (mf/use-state [])
|
||||
subject (mf/use-memo #(rx/subject))
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
(ns app.main.ui.workspace.viewport.utils
|
||||
(:require
|
||||
[app.util.dom :as dom]
|
||||
[app.common.geom.point :as gpt]
|
||||
[cuerdas.core :as str]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.main.ui.cursors :as cur]
|
||||
))
|
||||
[app.util.dom :as dom]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn update-transform [node shapes modifiers]
|
||||
;; TODO: looks like first argument is not necessary.
|
||||
(defn update-transform [_node shapes modifiers]
|
||||
(doseq [{:keys [id type]} shapes]
|
||||
(let [shape-node (dom/get-element (str "shape-" id))
|
||||
|
||||
|
@ -30,7 +30,8 @@
|
|||
shape-node)]
|
||||
(dom/set-attribute node "transform" (str (:displacement modifiers)))))))
|
||||
|
||||
(defn remove-transform [node shapes]
|
||||
;; TODO: looks like first argument is not necessary.
|
||||
(defn remove-transform [_node shapes]
|
||||
(doseq [{:keys [id type]} shapes]
|
||||
(when-let [node (dom/get-element (str "shape-" id))]
|
||||
(let [node (if (= :frame type) (.-parentNode node) node)]
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.workspace.viewport.path-actions :refer [path-actions]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.object :as obj]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(mf/defc pixel-grid
|
||||
|
@ -110,13 +109,13 @@
|
|||
on-pointer-enter
|
||||
(mf/use-callback
|
||||
(mf/deps (:id frame) on-frame-enter)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(on-frame-enter (:id frame))))
|
||||
|
||||
on-pointer-leave
|
||||
(mf/use-callback
|
||||
(mf/deps (:id frame) on-frame-leave)
|
||||
(fn [event]
|
||||
(fn [_]
|
||||
(on-frame-leave (:id frame))))]
|
||||
|
||||
[:text {:x 0
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.util.color :as uc]
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
(ns app.worker.impl
|
||||
(:require
|
||||
[app.common.pages.changes :as ch]
|
||||
[app.common.transit :as t]
|
||||
[okulary.core :as l]))
|
||||
|
||||
(enable-console-print!)
|
||||
|
|
|
@ -6,17 +6,14 @@
|
|||
|
||||
(ns app.worker.selection
|
||||
(:require
|
||||
[cljs.spec.alpha :as s]
|
||||
[okulary.core :as l]
|
||||
[app.common.data :as d]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.util.quadtree :as qdt]
|
||||
[app.worker.impl :as impl]
|
||||
[clojure.set :as set]))
|
||||
[clojure.set :as set]
|
||||
[okulary.core :as l]))
|
||||
|
||||
(defonce state (l/atom {}))
|
||||
|
||||
|
@ -66,8 +63,8 @@
|
|||
changed-ids (into #{}
|
||||
(comp (filter changes?)
|
||||
(filter #(not= % uuid/zero)))
|
||||
(set/union (keys old-objects)
|
||||
(keys new-objects)))
|
||||
(set/union (set (keys old-objects))
|
||||
(set (keys new-objects))))
|
||||
|
||||
shapes (->> changed-ids (mapv #(get new-objects %)) (filterv (comp not nil?)))
|
||||
parents-index (cp/generate-child-all-parents-index new-objects shapes)
|
||||
|
@ -87,7 +84,7 @@
|
|||
(create-index new-objects)))
|
||||
|
||||
(defn- query-index
|
||||
[{index :index z-index :z-index} rect frame-id include-frames? include-groups? disabled-masks reverse?]
|
||||
[{index :index z-index :z-index} rect frame-id include-frames? include-groups? reverse?]
|
||||
(let [result (-> (qdt/search index (clj->js rect))
|
||||
(es6-iterator-seq))
|
||||
|
||||
|
@ -137,7 +134,7 @@
|
|||
|
||||
|
||||
(defmethod impl/handler :selection/initialize-index
|
||||
[{:keys [file-id data] :as message}]
|
||||
[{:keys [data] :as message}]
|
||||
(letfn [(index-page [state page]
|
||||
(let [id (:id page)
|
||||
objects (:objects page)]
|
||||
|
@ -154,10 +151,10 @@
|
|||
nil)
|
||||
|
||||
(defmethod impl/handler :selection/query
|
||||
[{:keys [page-id rect frame-id include-frames? include-groups? disabled-masks reverse?]
|
||||
:or {include-groups? true disabled-masks #{} reverse? false} :as message}]
|
||||
[{:keys [page-id rect frame-id include-frames? include-groups? reverse?]
|
||||
:or {include-groups? true reverse? false} :as message}]
|
||||
(when-let [index (get @state page-id)]
|
||||
(query-index index rect frame-id include-frames? include-groups? disabled-masks reverse?)))
|
||||
(query-index index rect frame-id include-frames? include-groups? reverse?)))
|
||||
|
||||
(defmethod impl/handler :selection/query-z-index
|
||||
[{:keys [page-id objects ids]}]
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
(ns app.worker.snaps
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.util.geom.grid :as gg]
|
||||
[app.util.geom.snap-points :as snap]
|
||||
|
@ -99,7 +98,8 @@
|
|||
|
||||
changed-ids (into #{}
|
||||
(filter changed?)
|
||||
(set/union (keys old-objects) (keys new-objects)))
|
||||
(set/union (set (keys old-objects))
|
||||
(set (keys new-objects))))
|
||||
|
||||
to-delete (aggregate-data old-objects changed-ids)
|
||||
to-add (aggregate-data new-objects changed-ids)
|
||||
|
@ -134,30 +134,25 @@
|
|||
(reduce add-data $ to-add)
|
||||
(reduce delete-frames $ frames-to-delete))))
|
||||
|
||||
(defn- log-state
|
||||
"Helper function to print a friendly version of the snap tree. Debugging purposes"
|
||||
[]
|
||||
(let [process-frame-data #(d/mapm rt/as-map %)
|
||||
process-page-data #(d/mapm process-frame-data %)]
|
||||
(js/console.log "STATE" (clj->js (d/mapm process-page-data @state)))))
|
||||
;; (defn- log-state
|
||||
;; "Helper function to print a friendly version of the snap tree. Debugging purposes"
|
||||
;; []
|
||||
;; (let [process-frame-data #(d/mapm rt/as-map %)
|
||||
;; process-page-data #(d/mapm process-frame-data %)]
|
||||
;; (js/console.log "STATE" (clj->js (d/mapm process-page-data @state)))))
|
||||
|
||||
(defn- index-page [state page-id objects]
|
||||
(let [snap-data (initialize-snap-data objects)]
|
||||
(assoc state page-id snap-data)))
|
||||
|
||||
(defn- update-page [state page-id old-objects new-objects]
|
||||
(let [changed? #(not= (get old-objects %) (get new-objects %))
|
||||
changed-ids (into #{}
|
||||
(filter changed?)
|
||||
(set/union (keys old-objects) (keys new-objects)))
|
||||
|
||||
snap-data (get state page-id)
|
||||
(let [snap-data (get state page-id)
|
||||
snap-data (update-snap-data snap-data old-objects new-objects)]
|
||||
(assoc state page-id snap-data)))
|
||||
|
||||
;; Public API
|
||||
(defmethod impl/handler :snaps/initialize-index
|
||||
[{:keys [file-id data] :as message}]
|
||||
[{:keys [data] :as message}]
|
||||
;; Create the index
|
||||
(letfn [(process-page [state page]
|
||||
(let [id (:id page)
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
|
||||
(ns app.worker.thumbnails
|
||||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[beicon.core :as rx]
|
||||
[promesa.core :as p]
|
||||
[app.main.fonts :as fonts]
|
||||
["react-dom/server" :as rds]
|
||||
[app.main.exports :as exports]
|
||||
[app.worker.impl :as impl]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.util.http :as http]
|
||||
["react-dom/server" :as rds]))
|
||||
[app.worker.impl :as impl]
|
||||
[beicon.core :as rx]
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(defn- handle-response
|
||||
[response]
|
||||
|
|
Loading…
Add table
Reference in a new issue