mirror of
https://github.com/penpot/penpot.git
synced 2025-05-22 13:46:11 +02:00
commit
7954ad0edf
16 changed files with 166 additions and 117 deletions
|
@ -1,6 +1,5 @@
|
||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
## :rocket: Next
|
## :rocket: Next
|
||||||
|
|
||||||
### :boom: Breaking changes & Deprecations
|
### :boom: Breaking changes & Deprecations
|
||||||
|
@ -22,6 +21,9 @@
|
||||||
- Fix problem when undoing multiple selected colors [Taiga #4920](https://tree.taiga.io/project/penpot/issue/4920)
|
- Fix problem when undoing multiple selected colors [Taiga #4920](https://tree.taiga.io/project/penpot/issue/4920)
|
||||||
- Allow selection of empty board by partial rect [Taiga #4806](https://tree.taiga.io/project/penpot/issue/4806)
|
- Allow selection of empty board by partial rect [Taiga #4806](https://tree.taiga.io/project/penpot/issue/4806)
|
||||||
- Improve behavior for undo on text edition [Taiga #4693](https://tree.taiga.io/project/penpot/issue/4693)
|
- Improve behavior for undo on text edition [Taiga #4693](https://tree.taiga.io/project/penpot/issue/4693)
|
||||||
|
- Improve deeps selection of nested arboards [Taiga #4913](https://tree.taiga.io/project/penpot/issue/4913)
|
||||||
|
- Fix problem on selection numeric inputs on Firefox [#2991](https://github.com/penpot/penpot/issues/2991)
|
||||||
|
- Changed the text dominant-baseline to use ideographic [Taiga #4791](https://tree.taiga.io/project/penpot/issue/4791)
|
||||||
|
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
|
|
||||||
|
@ -29,8 +31,6 @@
|
||||||
- To @ondrejkonec: for contributing to the code with:
|
- To @ondrejkonec: for contributing to the code with:
|
||||||
- Refactor CSS variables [Github #2948](https://github.com/penpot/penpot/pull/2948)
|
- Refactor CSS variables [Github #2948](https://github.com/penpot/penpot/pull/2948)
|
||||||
|
|
||||||
=======
|
|
||||||
>>>>>>> origin/staging
|
|
||||||
## 1.17.3
|
## 1.17.3
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
|
@ -24,9 +24,11 @@
|
||||||
(and (= type :frame) (= id uuid/zero)))
|
(and (= type :frame) (= id uuid/zero)))
|
||||||
|
|
||||||
(defn root-frame?
|
(defn root-frame?
|
||||||
[{:keys [frame-id type]}]
|
([objects id]
|
||||||
(and (= type :frame)
|
(root-frame? (get objects id)))
|
||||||
(= frame-id uuid/zero)))
|
([{:keys [frame-id type]}]
|
||||||
|
(and (= type :frame)
|
||||||
|
(= frame-id uuid/zero))))
|
||||||
|
|
||||||
(defn frame-shape?
|
(defn frame-shape?
|
||||||
([objects id]
|
([objects id]
|
||||||
|
|
|
@ -179,18 +179,22 @@
|
||||||
|
|
||||||
([objects ids {:keys [bottom-frames?] :as options}]
|
([objects ids {:keys [bottom-frames?] :as options}]
|
||||||
(letfn [(comp [id-a id-b]
|
(letfn [(comp [id-a id-b]
|
||||||
(let [type-a (dm/get-in objects [id-a :type])
|
(let [frame-a? (= :frame (dm/get-in objects [id-a :type]))
|
||||||
type-b (dm/get-in objects [id-b :type])]
|
frame-b? (= :frame (dm/get-in objects [id-b :type]))]
|
||||||
(cond
|
(cond
|
||||||
(and (not= :frame type-a) (= :frame type-b))
|
|
||||||
(if bottom-frames? -1 1)
|
|
||||||
|
|
||||||
(and (= :frame type-a) (not= :frame type-b))
|
|
||||||
(if bottom-frames? 1 -1)
|
|
||||||
|
|
||||||
(= id-a id-b)
|
(= id-a id-b)
|
||||||
0
|
0
|
||||||
|
|
||||||
|
(and (not frame-a?) frame-b?)
|
||||||
|
(if bottom-frames? -1 1)
|
||||||
|
|
||||||
|
(and frame-a? (not frame-b?))
|
||||||
|
(if bottom-frames? 1 -1)
|
||||||
|
|
||||||
|
;; When comparing frames we invert the order if the flag `bottom-frames?` is on
|
||||||
|
(and frame-a? frame-b? bottom-frames?)
|
||||||
|
(if (is-shape-over-shape? objects id-b id-a) 1 -1)
|
||||||
|
|
||||||
(is-shape-over-shape? objects id-b id-a)
|
(is-shape-over-shape? objects id-b id-a)
|
||||||
-1
|
-1
|
||||||
|
|
||||||
|
|
|
@ -194,47 +194,43 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn ensure-loaded!
|
(defn ensure-loaded!
|
||||||
([id]
|
[id]
|
||||||
(p/create (fn [resolve]
|
(log/debug :action "try-ensure-loaded!" :font-id id)
|
||||||
(ensure-loaded! id resolve))))
|
(if-not (exists? js/window)
|
||||||
([id on-loaded]
|
;; If we are in the worker environment, we just mark it as loaded
|
||||||
(log/debug :action "try-ensure-loaded!" :font-id id)
|
;; without really loading it.
|
||||||
(if-not (exists? js/window)
|
(do
|
||||||
;; If we are in the worker environment, we just mark it as loaded
|
(swap! loaded conj id)
|
||||||
;; without really loading it.
|
(p/resolved id))
|
||||||
(do
|
|
||||||
(swap! loaded conj id)
|
|
||||||
(p/resolved id))
|
|
||||||
|
|
||||||
(when-let [font (get @fontsdb id)]
|
(let [font (get @fontsdb id)]
|
||||||
(cond
|
(cond
|
||||||
;; Font already loaded, we just continue
|
(nil? font)
|
||||||
(contains? @loaded id)
|
(p/resolved id)
|
||||||
(p/do
|
|
||||||
(on-loaded id)
|
|
||||||
id)
|
|
||||||
|
|
||||||
;; Font is currently downloading. We attach the caller to the promise
|
;; Font already loaded, we just continue
|
||||||
(contains? @loading id)
|
(contains? @loaded id)
|
||||||
(-> (get @loading id)
|
(p/resolved id)
|
||||||
(p/then #(do (on-loaded id) id)))
|
|
||||||
|
|
||||||
;; First caller, we create the promise and then wait
|
;; Font is currently downloading. We attach the caller to the promise
|
||||||
:else
|
(contains? @loading id)
|
||||||
(let [on-load (fn [resolve]
|
(p/resolved (get @loading id))
|
||||||
(swap! loaded conj id)
|
|
||||||
(swap! loading dissoc id)
|
|
||||||
(on-loaded id)
|
|
||||||
(resolve id))
|
|
||||||
|
|
||||||
load-p (p/create
|
;; First caller, we create the promise and then wait
|
||||||
(fn [resolve _]
|
:else
|
||||||
(-> font
|
(let [on-load (fn [resolve]
|
||||||
(assoc ::on-loaded (partial on-load resolve))
|
(swap! loaded conj id)
|
||||||
(load-font))))]
|
(swap! loading dissoc id)
|
||||||
|
(resolve id))
|
||||||
|
|
||||||
(swap! loading assoc id load-p)
|
load-p (p/create
|
||||||
load-p))))))
|
(fn [resolve _]
|
||||||
|
(-> font
|
||||||
|
(assoc ::on-loaded (partial on-load resolve))
|
||||||
|
(load-font))))]
|
||||||
|
|
||||||
|
(swap! loading assoc id load-p)
|
||||||
|
load-p)))))
|
||||||
|
|
||||||
(defn ready
|
(defn ready
|
||||||
[cb]
|
[cb]
|
||||||
|
|
|
@ -69,16 +69,21 @@
|
||||||
|
|
||||||
[:> :g group-props
|
[:> :g group-props
|
||||||
(for [[index data] (d/enumerate position-data)]
|
(for [[index data] (d/enumerate position-data)]
|
||||||
(let [alignment-bl (when (cf/check-browser? :safari) "text-before-edge")
|
(let [rtl? (= "rtl" (:direction data))
|
||||||
dominant-bl (when-not (cf/check-browser? :safari) "text-before-edge")
|
|
||||||
rtl? (= "rtl" (:direction data))
|
browser-props
|
||||||
|
(cond
|
||||||
|
(cf/check-browser? :safari)
|
||||||
|
#js {:dominantBaseline "hanging"
|
||||||
|
:dy "0.2em"
|
||||||
|
:y (- (:y data) (:height data))})
|
||||||
|
|
||||||
props (-> #js {:key (dm/str "text-" (:id shape) "-" index)
|
props (-> #js {:key (dm/str "text-" (:id shape) "-" index)
|
||||||
:x (if rtl? (+ (:x data) (:width data)) (:x data))
|
:x (if rtl? (+ (:x data) (:width data)) (:x data))
|
||||||
:y (- (:y data) (:height data))
|
:y (:y data)
|
||||||
|
:dominantBaseline "ideographic"
|
||||||
:textLength (:width data)
|
:textLength (:width data)
|
||||||
:lengthAdjust "spacingAndGlyphs"
|
:lengthAdjust "spacingAndGlyphs"
|
||||||
:alignmentBaseline alignment-bl
|
|
||||||
:dominantBaseline dominant-bl
|
|
||||||
:style (-> #js {:fontFamily (:font-family data)
|
:style (-> #js {:fontFamily (:font-family data)
|
||||||
:fontSize (:font-size data)
|
:fontSize (:font-size data)
|
||||||
:fontWeight (:font-weight data)
|
:fontWeight (:font-weight data)
|
||||||
|
@ -88,7 +93,9 @@
|
||||||
:fontStyle (:font-style data)
|
:fontStyle (:font-style data)
|
||||||
:direction (:direction data)
|
:direction (:direction data)
|
||||||
:whiteSpace "pre"}
|
:whiteSpace "pre"}
|
||||||
(obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))})
|
(obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))}
|
||||||
|
(cond-> browser-props
|
||||||
|
(obj/merge! browser-props)))
|
||||||
shape (assoc shape :fills (:fills data))]
|
shape (assoc shape :fills (:fills data))]
|
||||||
|
|
||||||
[:& (mf/provider muc/render-id) {:key index :value (str render-id "_" (:id shape) "_" index)}
|
[:& (mf/provider muc/render-id) {:key index :value (str render-id "_" (:id shape) "_" index)}
|
||||||
|
|
|
@ -15,9 +15,54 @@
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.ui.shapes.shape :refer [shape-container]]
|
[app.main.ui.shapes.shape :refer [shape-container]]
|
||||||
[app.main.ui.shapes.text :as text]
|
[app.main.ui.shapes.text :as text]
|
||||||
|
[app.util.dom :as dom]
|
||||||
[debug :refer [debug?]]
|
[debug :refer [debug?]]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(mf/defc debug-text-bounds
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
(let [shape (unchecked-get props "shape")
|
||||||
|
zoom (mf/deref refs/selected-zoom)
|
||||||
|
bounding-box (gsht/position-data-selrect shape)
|
||||||
|
ctx (js* "document.createElement(\"canvas\").getContext(\"2d\")")]
|
||||||
|
[:g {:transform (gsh/transform-str shape)}
|
||||||
|
[:rect {:x (:x bounding-box)
|
||||||
|
:y (:y bounding-box)
|
||||||
|
:width (:width bounding-box)
|
||||||
|
:height (:height bounding-box)
|
||||||
|
:style {:fill "none"
|
||||||
|
:stroke "orange"
|
||||||
|
:stroke-width (/ 1 zoom)}}]
|
||||||
|
|
||||||
|
(for [[index data] (d/enumerate (:position-data shape))]
|
||||||
|
(let [{:keys [x y width height]} data
|
||||||
|
res (dom/measure-text ctx (:font-size data) (:font-family data) (:text data))]
|
||||||
|
[:g {:key (dm/str index)}
|
||||||
|
;; Text fragment bounding box
|
||||||
|
[:rect {:x x
|
||||||
|
:y (- y height)
|
||||||
|
:width width
|
||||||
|
:height height
|
||||||
|
:style {:fill "none"
|
||||||
|
:stroke "red"
|
||||||
|
:stroke-width (/ 1 zoom)}}]
|
||||||
|
|
||||||
|
;; Text baseline
|
||||||
|
[:line {:x1 (mth/round x)
|
||||||
|
:y1 (mth/round (- (:y data) (:height data)))
|
||||||
|
:x2 (mth/round (+ x width))
|
||||||
|
:y2 (mth/round (- (:y data) (:height data)))
|
||||||
|
:style {:stroke "blue"
|
||||||
|
:stroke-width (/ 1 zoom)}}]
|
||||||
|
|
||||||
|
[:line {:x1 (:x data)
|
||||||
|
:y1 (- (:y data) (:descent res))
|
||||||
|
:x2 (+ (:x data) (:width data))
|
||||||
|
:y2 (- (:y data) (:descent res))
|
||||||
|
:style {:stroke "green"
|
||||||
|
:stroke-width (/ 2 zoom)}}]]))]))
|
||||||
|
|
||||||
;; --- Text Wrapper for workspace
|
;; --- Text Wrapper for workspace
|
||||||
(mf/defc text-wrapper
|
(mf/defc text-wrapper
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
@ -39,28 +84,4 @@
|
||||||
[:& text/text-shape {:shape shape}]]
|
[:& text/text-shape {:shape shape}]]
|
||||||
|
|
||||||
(when (and (debug? :text-outline) (d/not-empty? (:position-data shape)))
|
(when (and (debug? :text-outline) (d/not-empty? (:position-data shape)))
|
||||||
[:g {:transform (gsh/transform-str shape)}
|
[:& debug-text-bounds {:shape shape}])]))
|
||||||
(let [bounding-box (gsht/position-data-selrect shape)]
|
|
||||||
[:rect {
|
|
||||||
:x (:x bounding-box)
|
|
||||||
:y (:y bounding-box)
|
|
||||||
:width (:width bounding-box)
|
|
||||||
:height (:height bounding-box)
|
|
||||||
:style { :fill "none" :stroke "orange"}}])
|
|
||||||
|
|
||||||
(for [[index data] (d/enumerate (:position-data shape))]
|
|
||||||
(let [{:keys [x y width height]} data]
|
|
||||||
[:g {:key (dm/str index)}
|
|
||||||
;; Text fragment bounding box
|
|
||||||
[:rect {:x x
|
|
||||||
:y (- y height)
|
|
||||||
:width width
|
|
||||||
:height height
|
|
||||||
:style {:fill "none" :stroke "red"}}]
|
|
||||||
|
|
||||||
;; Text baseline
|
|
||||||
[:line {:x1 (mth/round x)
|
|
||||||
:y1 (mth/round (- (:y data) (:height data)))
|
|
||||||
:x2 (mth/round (+ x width))
|
|
||||||
:y2 (mth/round (- (:y data) (:height data)))
|
|
||||||
:style {:stroke "blue"}}]]))])]))
|
|
||||||
|
|
|
@ -336,7 +336,7 @@
|
||||||
[:span.element-set-subtitle.wide (tr "workspace.options.interaction-delay")]
|
[:span.element-set-subtitle.wide (tr "workspace.options.interaction-delay")]
|
||||||
[:div.input-element {:title (tr "workspace.options.interaction-ms")}
|
[:div.input-element {:title (tr "workspace.options.interaction-ms")}
|
||||||
[:> numeric-input {:ref ext-delay-ref
|
[:> numeric-input {:ref ext-delay-ref
|
||||||
:on-click (select-text ext-delay-ref)
|
:on-focus (select-text ext-delay-ref)
|
||||||
:on-change change-delay
|
:on-change change-delay
|
||||||
:value (:delay interaction)
|
:value (:delay interaction)
|
||||||
:title (tr "workspace.options.interaction-ms")}]
|
:title (tr "workspace.options.interaction-ms")}]
|
||||||
|
@ -523,7 +523,7 @@
|
||||||
[:span.element-set-subtitle.wide (tr "workspace.options.interaction-duration")]
|
[:span.element-set-subtitle.wide (tr "workspace.options.interaction-duration")]
|
||||||
[:div.input-element {:title (tr "workspace.options.interaction-ms")}
|
[:div.input-element {:title (tr "workspace.options.interaction-ms")}
|
||||||
[:> numeric-input {:ref ext-duration-ref
|
[:> numeric-input {:ref ext-duration-ref
|
||||||
:on-click (select-text ext-duration-ref)
|
:on-focus (select-text ext-duration-ref)
|
||||||
:on-change change-duration
|
:on-change change-duration
|
||||||
:value (-> interaction :animation :duration)
|
:value (-> interaction :animation :duration)
|
||||||
:title (tr "workspace.options.interaction-ms")}]
|
:title (tr "workspace.options.interaction-ms")}]
|
||||||
|
|
|
@ -113,7 +113,7 @@
|
||||||
[:div.input-element {:title (tr "workspace.options.opacity") :class "percentail"}
|
[:div.input-element {:title (tr "workspace.options.opacity") :class "percentail"}
|
||||||
[:> numeric-input {:value (-> values :opacity opacity->string)
|
[:> numeric-input {:value (-> values :opacity opacity->string)
|
||||||
:placeholder (tr "settings.multiple")
|
:placeholder (tr "settings.multiple")
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change handle-opacity-change
|
:on-change handle-opacity-change
|
||||||
:min 0
|
:min 0
|
||||||
:max 100}]]
|
:max 100}]]
|
||||||
|
|
|
@ -266,10 +266,11 @@
|
||||||
[:span.icon.rotated i/auto-padding-both-sides]
|
[:span.icon.rotated i/auto-padding-both-sides]
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
|
||||||
:on-change (partial on-change :simple :p1)
|
:on-change (partial on-change :simple :p1)
|
||||||
:on-focus #(select-paddings true false true false)
|
:on-focus #(select-paddings true false true false)
|
||||||
:on-blur #(select-paddings false false false false)
|
:on-blur #(do
|
||||||
|
(dom/select-target %)
|
||||||
|
(select-paddings false false false false))
|
||||||
:value p1}]]
|
:value p1}]]
|
||||||
|
|
||||||
[:div.padding-item.tooltip.tooltip-bottom-left
|
[:div.padding-item.tooltip.tooltip-bottom-left
|
||||||
|
@ -277,9 +278,9 @@
|
||||||
[:span.icon i/auto-padding-both-sides]
|
[:span.icon i/auto-padding-both-sides]
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
|
||||||
:on-change (partial on-change :simple :p2)
|
:on-change (partial on-change :simple :p2)
|
||||||
:on-focus #(select-paddings false true false true)
|
:on-focus #(do (dom/select-target %)
|
||||||
|
(select-paddings false true false true))
|
||||||
:on-blur #(select-paddings false false false false)
|
:on-blur #(select-paddings false false false false)
|
||||||
:value p2}]]]
|
:value p2}]]]
|
||||||
|
|
||||||
|
@ -296,9 +297,9 @@
|
||||||
[:div.input-element.auto
|
[:div.input-element.auto
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
|
||||||
:on-change (partial on-change :multiple num)
|
:on-change (partial on-change :multiple num)
|
||||||
:on-focus #(select-padding num)
|
:on-focus #(do (dom/select-target %)
|
||||||
|
(select-padding num))
|
||||||
:on-blur #(select-paddings false false false false)
|
:on-blur #(select-paddings false false false false)
|
||||||
:value (num (:layout-padding values))}]]])])
|
:value (num (:layout-padding values))}]]])])
|
||||||
|
|
||||||
|
@ -320,7 +321,7 @@
|
||||||
i/auto-gap]
|
i/auto-gap]
|
||||||
[:> numeric-input {:no-validate true
|
[:> numeric-input {:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click (fn [event]
|
:on-focus (fn [event]
|
||||||
(reset! gap-selected? :column-gap)
|
(reset! gap-selected? :column-gap)
|
||||||
(dom/select-target event))
|
(dom/select-target event))
|
||||||
:on-change (partial set-gap (= :nowrap wrap-type) :column-gap)
|
:on-change (partial set-gap (= :nowrap wrap-type) :column-gap)
|
||||||
|
@ -334,7 +335,7 @@
|
||||||
i/auto-gap]
|
i/auto-gap]
|
||||||
[:> numeric-input {:no-validate true
|
[:> numeric-input {:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click (fn [event]
|
:on-focus (fn [event]
|
||||||
(reset! gap-selected? :row-gap)
|
(reset! gap-selected? :row-gap)
|
||||||
(dom/select-target event))
|
(dom/select-target event))
|
||||||
:on-change (partial set-gap (= :nowrap wrap-type) :row-gap)
|
:on-change (partial set-gap (= :nowrap wrap-type) :row-gap)
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
[:span.icon i/auto-margin-both-sides]
|
[:span.icon i/auto-margin-both-sides]
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
:on-focus #(dom/select-target %)
|
||||||
:on-change (partial on-margin-change :simple :m1)
|
:on-change (partial on-margin-change :simple :m1)
|
||||||
:value m1}]]
|
:value m1}]]
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
[:span.icon.rotated i/auto-margin-both-sides]
|
[:span.icon.rotated i/auto-margin-both-sides]
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
:on-focus #(dom/select-target %)
|
||||||
:on-change (partial on-margin-change :simple :m2)
|
:on-change (partial on-margin-change :simple :m2)
|
||||||
:value m2}]]]
|
:value m2}]]]
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
[:div.input-element.auto
|
[:div.input-element.auto
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
:on-focus #(dom/select-target %)
|
||||||
:on-change (partial on-margin-change :multiple num)
|
:on-change (partial on-margin-change :multiple num)
|
||||||
:value (num (:layout-item-margin values))}]]])])
|
:value (num (:layout-item-margin values))}]]])])
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@
|
||||||
i/layers
|
i/layers
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
:on-focus #(dom/select-target %)
|
||||||
:on-change #(on-change-z-index %)
|
:on-change #(on-change-z-index %)
|
||||||
:value (:layout-item-z-index values)}]]]])
|
:value (:layout-item-z-index values)}]]]])
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@
|
||||||
:min 0
|
:min 0
|
||||||
:data-wrap true
|
:data-wrap true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click #(dom/select-target %)
|
:on-focus #(dom/select-target %)
|
||||||
:on-change (partial on-size-change item)
|
:on-change (partial on-size-change item)
|
||||||
:value (get values item)
|
:value (get values item)
|
||||||
:nillable true}]]])]]])]]))
|
:nillable true}]]])]]])]]))
|
||||||
|
|
|
@ -316,7 +316,7 @@
|
||||||
[:> numeric-input {:min 0.01
|
[:> numeric-input {:min 0.01
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-width-change
|
:on-change on-width-change
|
||||||
:disabled disabled-width-sizing?
|
:disabled disabled-width-sizing?
|
||||||
:value (:width values)}]]
|
:value (:width values)}]]
|
||||||
|
@ -325,7 +325,7 @@
|
||||||
[:> numeric-input {:min 0.01
|
[:> numeric-input {:min 0.01
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-height-change
|
:on-change on-height-change
|
||||||
:disabled disabled-height-sizing?
|
:disabled disabled-height-sizing?
|
||||||
:value (:height values)}]]
|
:value (:height values)}]]
|
||||||
|
@ -345,14 +345,14 @@
|
||||||
[:div.input-element.Xaxis {:title (tr "workspace.options.x")}
|
[:div.input-element.Xaxis {:title (tr "workspace.options.x")}
|
||||||
[:> numeric-input {:no-validate true
|
[:> numeric-input {:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-pos-x-change
|
:on-change on-pos-x-change
|
||||||
:disabled disabled-position-x?
|
:disabled disabled-position-x?
|
||||||
:value (:x values)}]]
|
:value (:x values)}]]
|
||||||
[:div.input-element.Yaxis {:title (tr "workspace.options.y")}
|
[:div.input-element.Yaxis {:title (tr "workspace.options.y")}
|
||||||
[:> numeric-input {:no-validate true
|
[:> numeric-input {:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:disabled disabled-position-y?
|
:disabled disabled-position-y?
|
||||||
:on-change on-pos-y-change
|
:on-change on-pos-y-change
|
||||||
:value (:y values)}]]])
|
:value (:y values)}]]])
|
||||||
|
@ -368,7 +368,7 @@
|
||||||
:max 359
|
:max 359
|
||||||
:data-wrap true
|
:data-wrap true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-rotation-change
|
:on-change on-rotation-change
|
||||||
:value (:rotation values)}]]])
|
:value (:rotation values)}]]])
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:ref radius-input-ref
|
:ref radius-input-ref
|
||||||
:min 0
|
:min 0
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-radius-1-change
|
:on-change on-radius-1-change
|
||||||
:value (:rx values)}]]
|
:value (:rx values)}]]
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@
|
||||||
{:type "number"
|
{:type "number"
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:min 0
|
:min 0
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-radius-multi-change
|
:on-change on-radius-multi-change
|
||||||
:value ""}]]
|
:value ""}]]
|
||||||
|
|
||||||
|
@ -416,7 +416,7 @@
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:min 0
|
:min 0
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-radius-r1-change
|
:on-change on-radius-r1-change
|
||||||
:value (:r1 values)}]]
|
:value (:r1 values)}]]
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:min 0
|
:min 0
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-radius-r2-change
|
:on-change on-radius-r2-change
|
||||||
:value (:r2 values)}]]
|
:value (:r2 values)}]]
|
||||||
|
|
||||||
|
@ -432,7 +432,7 @@
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:min 0
|
:min 0
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-radius-r3-change
|
:on-change on-radius-r3-change
|
||||||
:value (:r3 values)}]]
|
:value (:r3 values)}]]
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@
|
||||||
[:> numeric-input
|
[:> numeric-input
|
||||||
{:placeholder "--"
|
{:placeholder "--"
|
||||||
:min 0
|
:min 0
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-change on-radius-r4-change
|
:on-change on-radius-r4-change
|
||||||
:value (:r4 values)}]]])])
|
:value (:r4 values)}]]])])
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
[:> numeric-input {:ref adv-offset-x-ref
|
[:> numeric-input {:ref adv-offset-x-ref
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click (select-text adv-offset-x-ref)
|
:on-focus (select-text adv-offset-x-ref)
|
||||||
:on-change (update-attr index :offset-x valid-number? basic-offset-x-ref)
|
:on-change (update-attr index :offset-x valid-number? basic-offset-x-ref)
|
||||||
:value (:offset-x value)}]
|
:value (:offset-x value)}]
|
||||||
[:span.after (tr "workspace.options.shadow-options.offsetx")]]
|
[:span.after (tr "workspace.options.shadow-options.offsetx")]]
|
||||||
|
@ -159,7 +159,7 @@
|
||||||
[:> numeric-input {:ref adv-offset-y-ref
|
[:> numeric-input {:ref adv-offset-y-ref
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click (select-text adv-offset-y-ref)
|
:on-focus (select-text adv-offset-y-ref)
|
||||||
:on-change (update-attr index :offset-y valid-number? basic-offset-y-ref)
|
:on-change (update-attr index :offset-y valid-number? basic-offset-y-ref)
|
||||||
:value (:offset-y value)}]
|
:value (:offset-y value)}]
|
||||||
[:span.after (tr "workspace.options.shadow-options.offsety")]]]
|
[:span.after (tr "workspace.options.shadow-options.offsety")]]]
|
||||||
|
@ -169,7 +169,7 @@
|
||||||
[:> numeric-input {:ref adv-blur-ref
|
[:> numeric-input {:ref adv-blur-ref
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click (select-text adv-blur-ref)
|
:on-focus (select-text adv-blur-ref)
|
||||||
:on-change (update-attr index :blur valid-number? basic-blur-ref)
|
:on-change (update-attr index :blur valid-number? basic-blur-ref)
|
||||||
:min 0
|
:min 0
|
||||||
:value (:blur value)}]
|
:value (:blur value)}]
|
||||||
|
@ -179,7 +179,7 @@
|
||||||
[:> numeric-input {:ref adv-spread-ref
|
[:> numeric-input {:ref adv-spread-ref
|
||||||
:no-validate true
|
:no-validate true
|
||||||
:placeholder "--"
|
:placeholder "--"
|
||||||
:on-click (select-text adv-spread-ref)
|
:on-focus (select-text adv-spread-ref)
|
||||||
:on-change (update-attr index :spread valid-number?)
|
:on-change (update-attr index :spread valid-number?)
|
||||||
:value (:spread value)}]
|
:value (:spread value)}]
|
||||||
[:span.after (tr "workspace.options.shadow-options.spread")]]]
|
[:span.after (tr "workspace.options.shadow-options.spread")]]]
|
||||||
|
|
|
@ -196,7 +196,7 @@
|
||||||
""
|
""
|
||||||
(-> color :color uc/remove-hash))
|
(-> color :color uc/remove-hash))
|
||||||
:placeholder (tr "settings.multiple")
|
:placeholder (tr "settings.multiple")
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-blur on-blur
|
:on-blur on-blur
|
||||||
:on-change handle-value-change}]]
|
:on-change handle-value-change}]]
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@
|
||||||
{:class (dom/classnames :percentail (not= (:opacity color) :multiple))}
|
{:class (dom/classnames :percentail (not= (:opacity color) :multiple))}
|
||||||
[:> numeric-input {:value (-> color :opacity opacity->string)
|
[:> numeric-input {:value (-> color :opacity opacity->string)
|
||||||
:placeholder (tr "settings.multiple")
|
:placeholder (tr "settings.multiple")
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-blur on-blur
|
:on-blur on-blur
|
||||||
:on-change handle-opacity-change
|
:on-change handle-opacity-change
|
||||||
:min 0
|
:min 0
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
:value (-> (:stroke-width stroke) width->string)
|
:value (-> (:stroke-width stroke) width->string)
|
||||||
:placeholder (tr "settings.multiple")
|
:placeholder (tr "settings.multiple")
|
||||||
:on-change (on-stroke-width-change index)
|
:on-change (on-stroke-width-change index)
|
||||||
:on-click select-all
|
:on-focus select-all
|
||||||
:on-blur on-blur}]]
|
:on-blur on-blur}]]
|
||||||
|
|
||||||
[:select#style.input-select {:value (enum->string (:stroke-alignment stroke))
|
[:select#style.input-select {:value (enum->string (:stroke-alignment stroke))
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
(ns app.main.ui.workspace.viewport.hooks
|
(ns app.main.ui.workspace.viewport.hooks
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
|
@ -169,7 +170,8 @@
|
||||||
;; but the mouse has not been moved from its position.
|
;; but the mouse has not been moved from its position.
|
||||||
(->> mod-str
|
(->> mod-str
|
||||||
(rx/observe-on :async)
|
(rx/observe-on :async)
|
||||||
(rx/map #(deref last-point-ref)))
|
(rx/map #(deref last-point-ref))
|
||||||
|
(rx/merge-map query-point))
|
||||||
|
|
||||||
(->> move-stream
|
(->> move-stream
|
||||||
(rx/tap #(reset! last-point-ref %))
|
(rx/tap #(reset! last-point-ref %))
|
||||||
|
@ -241,10 +243,17 @@
|
||||||
remove-id?
|
remove-id?
|
||||||
(into selected-with-parents remove-id-xf ids)
|
(into selected-with-parents remove-id-xf ids)
|
||||||
|
|
||||||
|
no-fill-nested-frames?
|
||||||
|
(fn [id]
|
||||||
|
(and (cph/frame-shape? objects id)
|
||||||
|
(not (cph/root-frame? objects id))
|
||||||
|
(empty? (dm/get-in objects [id :fills]))))
|
||||||
|
|
||||||
hover-shape
|
hover-shape
|
||||||
(->> ids
|
(->> ids
|
||||||
(remove remove-id?)
|
(remove remove-id?)
|
||||||
(remove (partial cph/hidden-parent? objects))
|
(remove (partial cph/hidden-parent? objects))
|
||||||
|
(remove no-fill-nested-frames?)
|
||||||
(filter #(or (empty? focus) (cp/is-in-focus? objects focus %)))
|
(filter #(or (empty? focus) (cp/is-in-focus? objects focus %)))
|
||||||
(first)
|
(first)
|
||||||
(get objects))]
|
(get objects))]
|
||||||
|
|
|
@ -662,3 +662,12 @@
|
||||||
(defn has-children?
|
(defn has-children?
|
||||||
[^js node]
|
[^js node]
|
||||||
(> (-> node .-children .-length) 0))
|
(> (-> node .-children .-length) 0))
|
||||||
|
|
||||||
|
;; WARNING: Use only for debugging. It's to costly to use for real
|
||||||
|
(defn measure-text
|
||||||
|
"Given a canvas' context 2d and the text info returns tis ascent/descent info"
|
||||||
|
[context-2d font-size font-family text]
|
||||||
|
(let [_ (set! (.-font context-2d) (str font-size " " font-family))
|
||||||
|
measures (.measureText context-2d text)]
|
||||||
|
{:descent (.-actualBoundingBoxDescent measures)
|
||||||
|
:ascent (.-actualBoundingBoxAscent measures)}))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue