0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-10 00:58:26 -05:00

Allows auto-width and auto-height for text layouts

This commit is contained in:
alonso.torres 2020-09-18 13:55:57 +02:00 committed by Andrey Antukh
parent 9c61c52dc5
commit abdd4d68d5
10 changed files with 130 additions and 59 deletions

View file

@ -2678,5 +2678,9 @@
"ru" : "Кликни чтобы закончить фигуру",
"es" : "Pulsar para cerrar la ruta"
}
}
},
"workspace.options.text-options.grow-fixed": "Fixed",
"workspace.options.text-options.grow-auto-width": "Auto width",
"workspace.options.text-options.grow-auto-height": "Auto height"
}

View file

@ -1374,6 +1374,7 @@
(defn change-canvas-color
[color]
(s/assert string? color)
(ptk/reify ::change-canvas-color
ptk/WatchEvent
(watch [_ state stream]

View file

@ -273,10 +273,10 @@
(rx/of dw/clear-drawing)
(when (::initialized? shape)
(let [shape-click-width (case (:type shape)
:text 150
:text 3
20)
shape-click-height (case (:type shape)
:text 40
:text 16
20)
shape (if (::click-draw? shape)
(-> shape
@ -285,10 +285,14 @@
(assoc-in [:modifiers :resize-origin]
(gpt/point (:x shape) (:y shape))))
shape)
shape (cond-> shape
(= (:type shape) :text) (assoc :grow-type
(if (::click-draw? shape) :auto-width :fixed)))
shape (-> shape
geom/transform-shape
(dissoc ::initialized?
::click-draw?))]
(dissoc ::initialized? ::click-draw?))]
;; Add & select the created shape to the workspace
(rx/of dw/deselect-all
(dw/add-shape shape)))))))))

View file

@ -22,14 +22,19 @@
(defn- generate-root-styles
[data]
(let [valign (obj/get data "vertical-align")
(let [valign (obj/get data "vertical-align" "top")
talign (obj/get data "text-align" "flex-start")
base #js {:height "100%"
:width "100%"
:display "flex"}]
(cond-> base
(= valign "top") (obj/set! "alignItems" "flex-start")
(= valign "center") (obj/set! "alignItems" "center")
(= valign "bottom") (obj/set! "alignItems" "flex-end"))))
(= valign "bottom") (obj/set! "alignItems" "flex-end")
(= talign "left") (obj/set! "justifyContent" "flex-start")
(= talign "center") (obj/set! "justifyContent" "center")
(= talign "right") (obj/set! "justifyContent" "flex-end")
(= talign "justify") (obj/set! "justifyContent" "stretch"))))
(defn- generate-paragraph-styles
[data]
@ -47,6 +52,7 @@
(let [letter-spacing (obj/get data "letter-spacing")
text-decoration (obj/get data "text-decoration")
text-transform (obj/get data "text-transform")
line-height (obj/get data "line-height")
font-id (obj/get data "font-id")
font-variant-id (obj/get data "font-variant-id")
@ -61,7 +67,7 @@
:color fill
:opacity opacity
:textTransform text-transform
:lineHeight "inherit"}]
:lineHeight (or line-height "inherit")}]
(when (and (string? letter-spacing)
(pos? (alength letter-spacing)))
@ -128,7 +134,7 @@
(if (string? text)
(let [style (generate-text-styles (clj->js node))]
[:span {:style style :key index} text])
[:span {:style style :key index} (if (= text "") "\u00A0" text)])
(let [children (map-indexed (fn [index node]
(mf/element text-node {:index index :node node :key index}))
children)]
@ -145,8 +151,7 @@
children])
"paragraph-set"
(let [style #js {:display "inline-block"
:width "100%"}]
(let [style #js {:display "inline-block"}]
[:div.paragraphs {:key index :style style} children])
"paragraph"

View file

@ -29,7 +29,7 @@
(mf/defc generic-draw-area
[{:keys [shape zoom]}]
(let [{:keys [x y width height] :as kk} (:selrect (gsh/transform-shape shape))]
(let [{:keys [x y width height]} (:selrect (gsh/transform-shape shape))]
(when (and x y
(not (d/nan? x))
(not (d/nan? y)))

View file

@ -28,6 +28,7 @@
[app.util.dom :as dom]
[app.common.geom.shapes :as geom]
[app.util.object :as obj]
[app.util.timers :as timers]
["slate" :as slate]
["slate-react" :as rslate])
(:import
@ -81,15 +82,21 @@
;; --- Text Editor Rendering
(defn- generate-root-styles
[data]
(let [valign (obj/get data "vertical-align")
[data props]
(let [valign (obj/get data "vertical-align" "top")
talign (obj/get data "text-align")
shape (obj/get props "shape")
base #js {:height "100%"
:width "100%"
:width (:width shape)
:display "flex"}]
(cond-> base
(= valign "top") (obj/set! "alignItems" "flex-start")
(= valign "center") (obj/set! "alignItems" "center")
(= valign "bottom") (obj/set! "alignItems" "flex-end"))))
(= valign "bottom") (obj/set! "alignItems" "flex-end")
(= talign "left") (obj/set! "justifyContent" "flex-start")
(= talign "center") (obj/set! "justifyContent" "center")
(= talign "right") (obj/set! "justifyContent" "flex-end")
(= talign "justify") (obj/set! "justifyContent" "stretch"))))
(defn- generate-paragraph-styles
[data]
@ -107,6 +114,7 @@
(let [letter-spacing (obj/get data "letter-spacing")
text-decoration (obj/get data "text-decoration")
text-transform (obj/get data "text-transform")
line-height (obj/get data "line-height")
font-id (obj/get data "font-id")
font-variant-id (obj/get data "font-variant-id")
@ -121,7 +129,7 @@
:color fill
:opacity opacity
:textTransform text-transform
:lineHeight "inherit"}]
:lineHeight (or line-height "inherit")}]
(when (and (string? letter-spacing)
(pos? (alength letter-spacing)))
@ -157,7 +165,7 @@
childs (obj/get props "children")
data (obj/get props "element")
type (obj/get data "type")
style (generate-root-styles data)
style (generate-root-styles data props)
attrs (obj/set! attrs "style" style)
attrs (obj/set! attrs "className" type)]
[:> :div attrs childs]))
@ -169,8 +177,13 @@
childs (obj/get props "children")
data (obj/get props "element")
type (obj/get data "type")
shape (obj/get props "shape")
;; The position absolute is used so the paragraph is "outside"
;; the normal layout and can grow outside its parent
;; We use this element to measure the size of the text
style #js {:display "inline-block"
:width "100%"}
:position "absolute"}
attrs (obj/set! attrs "style" style)
attrs (obj/set! attrs "className" type)]
[:> :div attrs childs]))
@ -196,9 +209,10 @@
[:> :span attrs childs]))
(defn- render-element
[props]
[shape props]
(mf/html
(let [element (obj/get props "element")]
(let [element (obj/get props "element")
props (obj/merge! props #js {:shape shape})]
(case (obj/get element "type")
"root" [:> editor-root-node props]
"paragraph-set" [:> editor-paragraph-set-node props]
@ -229,12 +243,13 @@
(mf/defc text-shape-edit
{::mf/wrap [mf/memo]}
[{:keys [shape] :as props}]
(let [{:keys [id x y width height content]} shape
(let [{:keys [id x y width height content grow-type]} shape
state (mf/use-state #(parse-content content))
editor (mf/use-memo #(dwt/create-editor))
self-ref (mf/use-ref)
selecting-ref (mf/use-ref)
measure-ref (mf/use-ref)
on-close
(fn []
@ -297,8 +312,25 @@
(mf/use-effect on-mount)
[:foreignObject {:transform (geom/transform-matrix shape)
:x x :y y :width width :height height :ref self-ref}
(mf/use-effect
(mf/deps @state)
(fn []
(timers/schedule
#(if (#{:auto-width :auto-height} grow-type)
(let [self-node (mf/ref-val self-ref)
paragraph-node (dom/query self-node ".paragraph-set")]
(when paragraph-node
(let [{:keys [width height]} (dom/get-bounding-rect paragraph-node)]
(st/emit! (dw/update-shape id (if (= grow-type :auto-width)
{:width width :height height}
{:height height}))))))))))
[:foreignObject {:ref self-ref
:transform (geom/transform-matrix shape)
:x x :y y
:width (if (= :auto-width grow-type) 10000 width)
:height height}
[:style "span { line-height: inherit; }"]
[:> rslate/Slate {:editor editor
:value @state
:on-change on-change}
@ -308,7 +340,7 @@
:on-focus on-focus
:class "rich-text"
:style {:cursor cur/text}
:render-element render-element
:render-element #(render-element shape %)
:render-leaf render-text
:on-mouse-up on-mouse-up
:on-mouse-down on-mouse-down
@ -317,4 +349,4 @@
(dom/stop-propagation event)
;; WARN: monky patch
(obj/set! slate/Transforms "deselect" (constantly nil)))
:placeholder "Type some text here..."}]]]))
:placeholder (when (= :fixed grow-type) "Type some text here...")}]]]))

View file

@ -149,5 +149,6 @@
:spacing-values spacing-values
:valign-values valign-values
:decoration-values decoration-values
:transform-values transform-values}])]))
:transform-values transform-values
:shapes shapes}])]))

View file

@ -15,6 +15,7 @@
[app.main.ui.icons :as i]
[app.common.data :as d]
[app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.texts :as dwt]
[app.main.store :as st]
[app.main.refs :as refs]
@ -152,10 +153,15 @@
on-change
(fn [event new-align]
(run! #(st/emit! (dwt/update-paragraph-attrs
{:id %
:editor editor
:attrs {:text-align new-align}}))
(run! #(st/emit!
(dwt/update-root-attrs
{:id %
:editor editor
:attrs {:text-align new-align}})
(dwt/update-paragraph-attrs
{:id %
:editor editor
:attrs {:text-align new-align}}))
ids))]
;; --- Align
@ -226,35 +232,29 @@
:placeholder (t locale "settings.multiple")
:on-change #(on-change % :letter-spacing)}]]]))
;; (mf/defc box-sizing-options
;; [{:keys [editor] :as props}]
;; [:div.align-icons
;; [:span.tooltip.tooltip-bottom
;; {:alt "Auto height"}
;; i/auto-height]
;; [:span.tooltip.tooltip-bottom
;; {:alt "Auto width"}
;; i/auto-width]
;; [:span.tooltip.tooltip-bottom
;; {:alt "Fixed size"}
;; i/auto-fix]])
(mf/defc vertical-align-options
[{:keys [editor ids values locale] :as props}]
(mf/defc additional-options
[{:keys [shapes editor ids values locale] :as props}]
(let [{:keys [vertical-align]} values
to-single-value (fn [coll] (if (> (count coll) 1) nil (first coll)))
grow-type (->> shapes (map :grow-type) (into #{}) to-single-value)
vertical-align (or vertical-align "top")
on-change-grow
(fn [event grow-type]
(st/emit! (dwc/update-shapes ids #(assoc % :grow-type grow-type))))
on-change
(fn [event new-align]
(run! #(st/emit! (dwt/update-root-attrs
{:id %
:editor editor
:attrs {:vertical-align new-align}}))
{:id %
:editor editor
:attrs {:vertical-align new-align}}))
ids))]
[:div.row-flex
[:span.element-set-subtitle (t locale "workspace.options.text-options.vertical-align")]
[:div.align-icons
[:span.tooltip.tooltip-bottom
{:alt (t locale "workspace.options.text-options.align-top")
@ -270,7 +270,24 @@
{:alt (t locale "workspace.options.text-options.align-bottom")
:class (dom/classnames :current (= "bottom" vertical-align))
:on-click #(on-change % "bottom")}
i/align-bottom]]]))
i/align-bottom]]
[:div.align-icons
[:span.tooltip.tooltip-bottom
{:alt (t locale "workspace.options.text-options.grow-fixed")
:class (dom/classnames :current (= :fixed grow-type))
:on-click #(on-change-grow % :fixed)}
i/auto-fix]
[:span.tooltip.tooltip-bottom
{:alt (t locale "workspace.options.text-options.grow-auto-width")
:class (dom/classnames :current (= :auto-width grow-type))
:on-click #(on-change-grow % :auto-width)}
i/auto-width]
[:span.tooltip.tooltip-bottom
{:alt (t locale "workspace.options.text-options.grow-auto-height")
:class (dom/classnames :current (= :auto-height grow-type))
:on-click #(on-change-grow % :auto-height)}
i/auto-height]]]))
(mf/defc text-decoration-options
[{:keys [editor ids values locale] :as props}]
@ -353,7 +370,8 @@
spacing-values
valign-values
decoration-values
transform-values] :as props}]
transform-values
shapes] :as props}]
(let [locale (mf/deref i18n/locale)
label (case type
:multiple (t locale "workspace.options.text-options.title-selection")
@ -365,7 +383,7 @@
[:& font-options {:editor editor :ids ids :values font-values :locale locale}]
[:& text-align-options {:editor editor :ids ids :values align-values :locale locale}]
[:& spacing-options {:editor editor :ids ids :values spacing-values :locale locale}]
[:& vertical-align-options {:editor editor :ids ids :values valign-values :locale locale}]
[:& additional-options {:shapes shapes :editor editor :ids ids :values valign-values :locale locale}]
[:& text-decoration-options {:editor editor :ids ids :values decoration-values :locale locale}]
[:& text-transform-options {:editor editor :ids ids :values transform-values :locale locale}]]]))
@ -432,4 +450,5 @@
:spacing-values spacing-values
:valign-values valign-values
:decoration-values decoration-values
:transform-values transform-values}]]))
:transform-values transform-values
:shapes [shape]}]]))

View file

@ -9,6 +9,7 @@
(ns app.main.ui.workspace.snap-points
(:require
[app.common.math :as mth]
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.main.refs :as refs]
@ -22,6 +23,8 @@
(mf/defc snap-point
[{:keys [point zoom]}]
(let [{:keys [x y]} point
x (mth/round x)
y (mth/round y)
cross-width (/ 3 zoom)]
[:g
[:line {:x1 (- x cross-width)
@ -37,10 +40,10 @@
(mf/defc snap-line
[{:keys [snap point zoom]}]
[:line {:x1 (:x snap)
:y1 (:y snap)
:x2 (:x point)
:y2 (:y point)
[:line {:x1 (mth/round (:x snap))
:y1 (mth/round (:y snap))
:x2 (mth/round (:x point))
:y2 (mth/round (:y point))
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}
:opacity 0.4}])

View file

@ -167,7 +167,9 @@
{:left (.-left ^js rect)
:top (.-top ^js rect)
:right (.-right ^js rect)
:bottom (.-bottom ^js rect)}))
:bottom (.-bottom ^js rect)
:width (.-width ^js rect)
:height (.-height ^js rect)}))
(defn get-window-size
[]